Browse Source

added log viewer to UI to replace command line prints

Lucas Heer 7 years ago
parent
commit
35038fb76e
9 changed files with 118 additions and 43 deletions
  1. 3 3
      main.py
  2. 4 0
      sketchUI/exm_mainwindow.py
  3. 36 22
      sketchUI/exm_scene.py
  4. 10 3
      sketchUI/im_mainwindow.py
  5. 9 3
      sketchUI/im_scene.py
  6. 0 4
      sketchUI/mvops.py
  7. 23 3
      sketchUI/ui.py
  8. 32 4
      sketchUI/ui.ui
  9. 1 1
      wrappers/modelverse_SCCD.py

+ 3 - 3
main.py

@@ -82,9 +82,9 @@ if __name__ == "__main__":
     if args.u:
         upload_graph_MM()
         upload_consyn_MM()
-        #upload_consyn()
-        #upload_example_models()
-        #upload_instance_model()
+        upload_consyn()
+        upload_example_models()
+        upload_instance_model()
         upload_ops.upload_evolution_ops()
 
     # determine modeling mode

+ 4 - 0
sketchUI/exm_mainwindow.py

@@ -31,6 +31,9 @@ class EXMMainWindow(QMainWindow, Ui_MainWindow):
         # load model
         self._load_model()
 
+        # setup log viewer
+        self.plainTextEdit.setReadOnly(True)
+
         # lastly, run state machine
         self._statemachine.start()
 
@@ -243,3 +246,4 @@ class EXMMainWindow(QMainWindow, Ui_MainWindow):
         node_id = mvops.add_node(self._cur_model, event.text())
         # render node
         self._add_node_to_scene(node_id, event.text())
+        self.plainTextEdit.appendPlainText("Added node of type {} to model".format(event.text()))

+ 36 - 22
sketchUI/exm_scene.py

@@ -1,7 +1,7 @@
 from enum import Enum
 from PyQt5.QtWidgets import QGraphicsScene, QGraphicsItem, QGraphicsLineItem, QGraphicsRectItem, \
     QGraphicsEllipseItem, QInputDialog, QGraphicsItemGroup
-from PyQt5.Qt import Qt, QPointF, QPen, QTransform
+from PyQt5.Qt import Qt, QPointF, QPen, QTransform, QApplication
 from sketchUI.graphics_edge_item import GraphicsEdgeItem
 from sketchUI.graphics_node_item import GraphicsNodeItem, IconType
 from sketchUI import mvops
@@ -180,7 +180,7 @@ class SketchScene(QGraphicsScene):
             elif isinstance(item, GraphicsNodeItem):
                 self._handle_keypress_type_on_node(item)
             else:
-                print("Cannot type element {}".format(item))
+                self._parent.plainTextEdit.appendPlainText("Error: Cannot type element {}".format(item))
 
         else:
             QGraphicsScene.keyPressEvent(self, event)
@@ -193,20 +193,21 @@ class SketchScene(QGraphicsScene):
         """
         old_type = item.get_type()
         node_type, ok = QInputDialog.getText(self._parent, "Retype node", "New type", text=item.get_type())
-        if not ok:
-            # user canceled
+        if not ok or not node_type:
+            # user canceled or node type empty
+            return
+
+        if node_type in mvops.get_available_types():
+            self._parent.plainTextEdit.appendPlainText("Error: Already such a type: {}".format(node_type))
             return
-        if node_type:
-            print("Reyping item {} to type {}".format(item, node_type))
-            if node_type in mvops.get_available_types():
-                print("Error: Already such a type: {}".format(node_type))
-                return
 
         # local or global retype?
         scope, ok = QInputDialog.getItem(self._parent, "Select scope", "Scope", ["Local", "Global"])
         if not ok:
             return
 
+        self._parent.plainTextEdit.appendPlainText("Performing retype of node {}".format(node_type))
+        QApplication.setOverrideCursor(Qt.WaitCursor)
         retype_handler = NodeRetype()
         if scope == "Global":
             retype_handler.execute(self._cur_model, item.node_id, node_type, local=False)
@@ -214,14 +215,18 @@ class SketchScene(QGraphicsScene):
             retype_handler.execute(self._cur_model, item.node_id, node_type, local=True)
 
         # rename on screen
-        for node_item in self.items():
-            if not isinstance(node_item, GraphicsNodeItem):
-                continue
-            if node_item.get_type() == old_type:
-                node_item.set_type(node_type)
+        if scope == "Global":
+            for node_item in self.items():
+                if not isinstance(node_item, GraphicsNodeItem):
+                    continue
+                if node_item.get_type() == old_type:
+                    node_item.set_type(node_type)
+        else:
+            item.set_type(node_type)
 
         # update list widget
         self._parent.populate_types()
+        QApplication.restoreOverrideCursor()
 
     def _handle_keypress_type_on_group(self, group):
         # type: (QGraphicsItemGroup) -> None
@@ -231,20 +236,21 @@ class SketchScene(QGraphicsScene):
         """
         # get the type from the user
         node_type, ok = QInputDialog.getText(self._parent, "Type node", "Enter type")
-        if not ok:
-            # user canceled
+        if not ok or not node_type:
+            # user canceled or empty type string
+            return
+
+        if node_type in mvops.get_available_types():
+            self._parent.plainTextEdit.appendPlainText("Error: Already such a type: {}".format(node_type))
             return
-        if node_type:
-            print("Typing item {} to type {}".format(group, node_type))
-            if node_type in mvops.get_available_types():
-                print("Error: Already such a type: {}".format(node_type))
-                return
 
         # perform add local or global?
         scope, ok = QInputDialog.getItem(self._parent, "Select scope", "Scope", ["Local", "Global"])
         if not ok:
             return
 
+        self._parent.plainTextEdit.appendPlainText("Typing group to type {}".format(node_type))
+        QApplication.setOverrideCursor(Qt.WaitCursor)
         # add the node to the model
         add_handler = NodeAdd()
         if scope == "Global":
@@ -254,10 +260,11 @@ class SketchScene(QGraphicsScene):
         # Get node id of newly added node in current model
         nodeid = all_nodes_with_type(self._cur_model, node_type)[0]
 
+        self._parent.plainTextEdit.appendPlainText("Capturing concrete syntax of group ...")
         # create concrete syntax model for the sketched elements
         csm = mvops.new_concrete_syntax(node_type, IconType.PRIMITIVE)
         if not csm:
-            # CS for such a type already exists
+            self._parent.plainTextEdit.appendPlainText("Error: Concrete syntax for type {} already exists".format(node_type))
             return
 
         # TODO: populate CSM with sketched elements
@@ -275,16 +282,20 @@ class SketchScene(QGraphicsScene):
         self.removeItem(group)
         self.addItem(nodeitem)
         self._parent.populate_types()
+        QApplication.restoreOverrideCursor()
+        self._parent.plainTextEdit.appendPlainText("OK")
 
     def _handle_keypress_delete(self, selected):
         del_hander = NodeDelete()
         for item in selected:
             # only delete nodes, edges are taken care of later
             if isinstance(item, GraphicsNodeItem):
+                self._parent.plainTextEdit.appendPlainText("Deleting node of type {}".format(item.get_type()))
                 # when deleting a node, local or global?
                 scope, ok = QInputDialog.getItem(self._parent, "Select scope", "Scope", ["Local", "Global"])
                 if not ok:
                     return
+                QApplication.setOverrideCursor(Qt.WaitCursor)
                 if scope == "Global":
                     # global language evolution, so delete node with same type everywhere
                     del_hander.execute(self._cur_model, item.node_id, local=False, check_if_last=False)
@@ -293,6 +304,7 @@ class SketchScene(QGraphicsScene):
                     del_hander.execute(self._cur_model, item.node_id, local=True, check_if_last=True)
 
                 # in view, delete edges that were connected to this node as well
+                # modelverse does this on its own so do not delete edges explicitly here
                 for edge in self.items():
                     if not isinstance(edge, GraphicsEdgeItem):
                         continue
@@ -309,3 +321,5 @@ class SketchScene(QGraphicsScene):
         # if any node was deleted, repopulate list of available items
         if any(isinstance(item, GraphicsNodeItem) for item in selected):
             self._parent.populate_types()
+
+        QApplication.restoreOverrideCursor()

+ 10 - 3
sketchUI/im_mainwindow.py

@@ -1,6 +1,7 @@
 from PyQt5.QtWidgets import QMainWindow, QGraphicsItem, QAction, QActionGroup, QGraphicsView
 from PyQt5.QtGui import QIcon
 from PyQt5.QtCore import QStateMachine, QState
+from PyQt5.Qt import QApplication, Qt
 from sketchUI.ui import Ui_MainWindow
 from sketchUI.im_scene import CustomScene, Mode
 from sketchUI import mvops
@@ -16,7 +17,7 @@ class IMMainWindow(QMainWindow, Ui_MainWindow):
         self.setWindowTitle(model)
         self._cur_model = model
 
-        self._scene = CustomScene(model)
+        self._scene = CustomScene(model, self)
         self._scene.set_mode(Mode.SELECT)
         self._scene.setSceneRect(0, 0, 200, 200)
         self.graphicsView.setScene(self._scene)
@@ -31,6 +32,9 @@ class IMMainWindow(QMainWindow, Ui_MainWindow):
         # load the model
         self._load_model()
 
+        # setup log viewer
+        self.plainTextEdit.setReadOnly(True)
+
         #lastly, start the state machine
         self._statemachine.start()
 
@@ -152,8 +156,11 @@ class IMMainWindow(QMainWindow, Ui_MainWindow):
         node_id = mvops.add_node(self._cur_model, event.text())
         # render to scene
         self._add_node_to_scene(node_id, event.text())
+        self.plainTextEdit.appendPlainText("Added node of type {} to model".format(event.text()))
 
     def _on_verify_clicked(self, event):
-        print("Verifying model ...")
+        self.plainTextEdit.appendPlainText("Verifying instance model against example models ...")
+        QApplication.setOverrideCursor(Qt.WaitCursor)
         ret = verify(self._cur_model)
-        print(ret)
+        self.plainTextEdit.appendPlainText("Result: {}".format(str(ret)))
+        QApplication.restoreOverrideCursor()

+ 9 - 3
sketchUI/im_scene.py

@@ -12,11 +12,12 @@ class Mode(Enum):
 
 
 class CustomScene(QGraphicsScene):
-    def __init__(self, model):
+    def __init__(self, model, parent):
         QGraphicsScene.__init__(self)
         self._mode = None  # set by mainwindow at start
         self.connect_from_item = None  # store the item to draw the connecting line from
         self._cur_model = model  # the mv model we operate on
+        self._parent = parent  # mainwindow parent
 
     def set_mode(self, mode):
         self._mode = mode
@@ -36,7 +37,7 @@ class CustomScene(QGraphicsScene):
             if not item:
                 return
             if item == self.connect_from_item:
-                print("Not connecting same elements")
+                self._parent.plainTextEdit.appendPlainText("Error: Cannot connect same elements")
                 return
             self.draw_edge(self.connect_from_item, item, is_new=True)
 
@@ -55,11 +56,15 @@ class CustomScene(QGraphicsScene):
 
     def draw_edge(self, from_item, to_item, is_new):
         # type: (GraphicsNodeItem, GraphicsNodeItem, bool) -> None
+        """
+        Draw edge on screen between the node items "from_item" and "to_item".
+        If is_new, additionally instantiate the edge in the model (if supported).
+        """
         from_type = from_item.get_type()
         to_type = to_item.get_type()
         if is_new:
             if not mvops.is_edge_supported(from_type, to_type):
-                print("edge not supported between {} and {}".format(from_type, to_type))
+                self._parent.plainTextEdit.appendPlainText("Error: Edge not supported between types {} and {}".format(from_type, to_type))
                 return
 
         line = GraphicsEdgeItem(from_item, to_item)
@@ -70,3 +75,4 @@ class CustomScene(QGraphicsScene):
 
         if is_new:
             mvops.add_edge(self._cur_model, from_item.node_id, to_item.node_id)
+            self._parent.plainTextEdit.appendPlainText("Added edge between {} and {} to model".format(from_type, to_type))

+ 0 - 4
sketchUI/mvops.py

@@ -39,14 +39,12 @@ def add_node(model, node_type):
     """ Adds new node to model "model" with type attribute "node_type" """
     node_id = mv.instantiate(model, "Node")
     mv.attr_assign(model, node_id, "typeID", node_type)
-    print("Added node with id {} and type {} to model {}".format(node_id, node_type, model))
     return node_id
 
 def add_edge(model, from_id, to_id, directed=False):
     """ Adds an edge to model "model" between the nodes "from_id" and "to_id" """
     edge_id = mv.instantiate(model, "Edge", (from_id, to_id))
     mv.attr_assign(model, edge_id, "directed", directed)
-    print("Added edge between {} and {} to model".format(from_id, to_id))
     return edge_id
 
 def get_consyn_of(node_type):
@@ -65,12 +63,10 @@ def new_concrete_syntax(type_id, icon_type):
     """
     Add a new concrete syntax model for type "type_id" and representation type "icon_type" to the modelverse
     """
-    print("Creating new concrete syntax model for type {}".format(type_id))
     csm = "models/consyn/" + type_id
     try:
         mv.model_add(csm, "formalisms/consynMM")
     except mv.ModelExists:
-        print("Model for concrete syntax {} already exists".format(type_id))
         return ""
 
     icon = mv.instantiate(csm, "Icon")

+ 23 - 3
sketchUI/ui.py

@@ -14,12 +14,23 @@ class Ui_MainWindow(object):
         MainWindow.resize(991, 678)
         self.centralwidget = QtWidgets.QWidget(MainWindow)
         self.centralwidget.setObjectName("centralwidget")
-        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
+        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.frame = QtWidgets.QFrame(self.centralwidget)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
+        self.frame.setSizePolicy(sizePolicy)
+        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
+        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+        self.frame.setObjectName("frame")
+        self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
         self.horizontalLayout.setObjectName("horizontalLayout")
-        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
+        self.graphicsView = QtWidgets.QGraphicsView(self.frame)
         self.graphicsView.setObjectName("graphicsView")
         self.horizontalLayout.addWidget(self.graphicsView)
-        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
+        self.listWidget = QtWidgets.QListWidget(self.frame)
         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
@@ -27,6 +38,15 @@ class Ui_MainWindow(object):
         self.listWidget.setSizePolicy(sizePolicy)
         self.listWidget.setObjectName("listWidget")
         self.horizontalLayout.addWidget(self.listWidget)
+        self.verticalLayout.addWidget(self.frame)
+        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.plainTextEdit.sizePolicy().hasHeightForWidth())
+        self.plainTextEdit.setSizePolicy(sizePolicy)
+        self.plainTextEdit.setObjectName("plainTextEdit")
+        self.verticalLayout.addWidget(self.plainTextEdit)
         MainWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtWidgets.QMenuBar(MainWindow)
         self.menubar.setGeometry(QtCore.QRect(0, 0, 991, 26))

+ 32 - 4
sketchUI/ui.ui

@@ -14,14 +14,42 @@
    <string>MainWindow</string>
   </property>
   <widget class="QWidget" name="centralwidget">
-   <layout class="QHBoxLayout" name="horizontalLayout">
+   <layout class="QVBoxLayout" name="verticalLayout">
     <item>
-     <widget class="QGraphicsView" name="graphicsView"/>
+     <widget class="QFrame" name="frame">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Raised</enum>
+      </property>
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QGraphicsView" name="graphicsView"/>
+       </item>
+       <item>
+        <widget class="QListWidget" name="listWidget">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
     </item>
     <item>
-     <widget class="QListWidget" name="listWidget">
+     <widget class="QPlainTextEdit" name="plainTextEdit">
       <property name="sizePolicy">
-       <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+       <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>

+ 1 - 1
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Mon Apr 23 13:20:39 2018
+Date:   Mon Apr 23 14:39:12 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server