浏览代码

edges are now deletable

Lucas Heer 7 年之前
父节点
当前提交
da33214bb3
共有 8 个文件被更改,包括 112 次插入83 次删除
  1. 1 0
      main.py
  2. 10 13
      sketchUI/exm_mainwindow.py
  3. 36 21
      sketchUI/exm_scene.py
  4. 2 1
      sketchUI/graphics_edge_item.py
  5. 10 13
      sketchUI/im_mainwindow.py
  6. 49 34
      sketchUI/im_scene.py
  7. 3 0
      sketchUI/mvops.py
  8. 1 1
      wrappers/modelverse_SCCD.py

+ 1 - 0
main.py

@@ -100,6 +100,7 @@ if __name__ == "__main__":
     # open existing model?
     if args.m:
         model = args.m
+        # TODO: Check if this model exists
     else:
         # no model to open, create an empty one
         if mode == "IM":

+ 10 - 13
sketchUI/exm_mainwindow.py

@@ -5,6 +5,7 @@ from sketchUI.ui import Ui_MainWindow
 from sketchUI.exm_scene import SketchScene, Mode
 from sketchUI import mvops
 from sketchUI.graphics_node_item import GraphicsNodeItem
+from sketchUI.graphics_edge_item import GraphicsEdgeItem
 from wrappers.modelverse import element_list_nice
 import commons
 
@@ -184,17 +185,13 @@ class EXMMainWindow(QMainWindow, Ui_MainWindow):
 
     def _make_items_movable(self, movable):
         for item in self._scene.items():
-            try:
-                # hacky hack because of pythons isinstance fails due to import chaos
-                # edges are not selectable or movable
-                item.__hack__()
+            if isinstance(item, GraphicsEdgeItem):
+                # edges are never movable, but selectable
                 item.setFlag(QGraphicsItem.ItemIsMovable, False)
-                item.setFlag(QGraphicsItem.ItemIsSelectable, False)
-                continue
-            except AttributeError:
-                pass
-            item.setFlag(QGraphicsItem.ItemIsMovable, movable)
-            item.setFlag(QGraphicsItem.ItemIsSelectable, movable)
+                item.setFlag(QGraphicsItem.ItemIsSelectable, True)
+            else:
+                item.setFlag(QGraphicsItem.ItemIsMovable, movable)
+                item.setFlag(QGraphicsItem.ItemIsSelectable, movable)
 
     def _enable_box_select(self, enable):
         if enable:
@@ -220,7 +217,7 @@ class EXMMainWindow(QMainWindow, Ui_MainWindow):
             if typ == "Edge":
                 target = item["__target"]
                 src = item["__source"]
-                self._add_edge_to_scene(src, target)
+                self._add_edge_to_scene(src, target, item["id"])
 
     def _add_node_to_scene(self, node_id, node_type, x=0, y=0):
         consyn = mvops.get_consyn_of(node_type)
@@ -230,7 +227,7 @@ class EXMMainWindow(QMainWindow, Ui_MainWindow):
         item.setFlag(QGraphicsItem.ItemIsSelectable, True)
         self._scene.addItem(item)
 
-    def _add_edge_to_scene(self, from_id, to_id):
+    def _add_edge_to_scene(self, from_id, to_id, edge_id):
         from_item = None
         to_item = None
         for item in self._scene.items():
@@ -245,7 +242,7 @@ class EXMMainWindow(QMainWindow, Ui_MainWindow):
             if node_id == to_id:
                 to_item = item
 
-        self._scene.draw_edge(from_item, to_item, is_new=False)
+        self._scene.draw_edge(from_item, to_item, is_new=False, edge_id=edge_id)
 
     def _on_list_item_clicked(self, event):
         # add node to model

+ 36 - 21
sketchUI/exm_scene.py

@@ -40,17 +40,18 @@ class SketchScene(QGraphicsScene):
             return False
         return True
 
-    def draw_edge(self, from_item, to_item, is_new):
-        # type: (GraphicsNodeItem, GraphicsNodeItem, bool) -> None
+    def draw_edge(self, from_item, to_item, is_new, edge_id=None):
+        # type: (GraphicsNodeItem, GraphicsNodeItem, bool, str) -> None
         # draw an edge between two items. If is_new, also add it to the model
-        line = GraphicsEdgeItem(from_item, to_item)
+        line = GraphicsEdgeItem(from_item, to_item, edge_id)
         line.setFlag(QGraphicsItem.ItemIsMovable, False)
         line.setFlag(QGraphicsItem.ItemIsSelectable, False)
         self.addItem(line)
         line.redraw()
 
         if is_new:
-            mvops.add_edge(self._cur_model, from_item.node_id, to_item.node_id)
+            edge_id = mvops.add_edge(self._cur_model, from_item.node_id, to_item.node_id)
+            line.edge_id = edge_id
 
     def mousePressEvent(self, event):
         if event.button() == Qt.LeftButton and self._in_draw_mode():
@@ -67,26 +68,29 @@ class SketchScene(QGraphicsScene):
                 self._connect_from_item = item
 
         elif event.button() == Qt.LeftButton and self._mode == Mode.SELECT:
-            # load attributes for selected item (if it is a typed node)
             item = self.itemAt(event.scenePos(), QTransform())
-            if not item or not isinstance(item, GraphicsNodeItem):
-                # just a sketched element, delegate event
-                QGraphicsScene.mousePressEvent(self, event)
+
+            if not item:
                 return
 
-            self._parent.tableWidget.setRowCount(0)
-            self._parent.tableWidget.blockSignals(True)
-            self._parent.plainTextEdit.appendPlainText("Selected node of type {}".format(item.get_type()))
-            attrs = commons.get_attributes_of_node(self._cur_model, item.node_id)
-            for attr in attrs:
-                table_item_key = QTableWidgetItem(attr.key)
-                table_item_key.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
-                table_item_val = QTableWidgetItem(attr.val)
-                cur_row_cnt = self._parent.tableWidget.rowCount()
-                self._parent.tableWidget.insertRow(cur_row_cnt)
-                self._parent.tableWidget.setItem(cur_row_cnt, 0, table_item_key)
-                self._parent.tableWidget.setItem(cur_row_cnt, 1, table_item_val)
-            self._parent.tableWidget.blockSignals(False)
+            elif isinstance(item, GraphicsNodeItem):
+                # load attributes for selected node
+                self._parent.tableWidget.setRowCount(0)
+                self._parent.tableWidget.blockSignals(True)
+                self._parent.plainTextEdit.appendPlainText("Selected node of type {}".format(item.get_type()))
+                attrs = commons.get_attributes_of_node(self._cur_model, item.node_id)
+                for attr in attrs:
+                    table_item_key = QTableWidgetItem(attr.key)
+                    table_item_key.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
+                    table_item_val = QTableWidgetItem(attr.val)
+                    cur_row_cnt = self._parent.tableWidget.rowCount()
+                    self._parent.tableWidget.insertRow(cur_row_cnt)
+                    self._parent.tableWidget.setItem(cur_row_cnt, 0, table_item_key)
+                    self._parent.tableWidget.setItem(cur_row_cnt, 1, table_item_val)
+                self._parent.tableWidget.blockSignals(False)
+
+            elif isinstance(item, GraphicsEdgeItem):
+                self._parent.plainTextEdit.appendPlainText("Selected edge")
 
         else:
             pass
@@ -314,6 +318,14 @@ class SketchScene(QGraphicsScene):
 
     def _handle_keypress_delete(self, selected):
         del_hander = NodeDelete()
+
+        if len(selected) == 1 and isinstance(selected[0], GraphicsEdgeItem):
+            self._parent.plainTextEdit.appendPlainText("Deleting edge")
+            edge = selected[0]
+            mvops.delete_node(self._cur_model, edge.edge_id)
+            self.removeItem(edge)
+            return
+
         for item in selected:
             # only delete nodes, edges are taken care of later
             if isinstance(item, GraphicsNodeItem):
@@ -340,6 +352,9 @@ class SketchScene(QGraphicsScene):
 
                 self.removeItem(item)
 
+            elif isinstance(item, GraphicsEdgeItem):
+                continue
+
             else:
                 # no NodeItem -> untyped sketch, simply remove
                 for obj in selected:

+ 2 - 1
sketchUI/graphics_edge_item.py

@@ -6,10 +6,11 @@ from PyQt5.QtWidgets import QGraphicsItem, QGraphicsLineItem
 
 
 class GraphicsEdgeItem(QGraphicsLineItem):
-    def __init__(self, from_item, to_item):
+    def __init__(self, from_item, to_item, edge_id=None):
         QGraphicsLineItem.__init__(self)
         self.from_item = from_item
         self.to_item = to_item
+        self.edge_id = edge_id
         self.setFlag(QGraphicsItem.ItemIsMovable, False)
         self.setFlag(QGraphicsItem.ItemIsSelectable, False)
 

+ 10 - 13
sketchUI/im_mainwindow.py

@@ -6,6 +6,7 @@ from sketchUI.ui import Ui_MainWindow
 from sketchUI.im_scene import CustomScene, Mode
 from sketchUI import mvops
 from sketchUI.graphics_node_item import GraphicsNodeItem
+from sketchUI.graphics_edge_item import GraphicsEdgeItem
 from wrappers.modelverse import element_list_nice
 from verifier import Verifier
 import commons
@@ -96,7 +97,7 @@ class IMMainWindow(QMainWindow, Ui_MainWindow):
             if typ == "Edge":
                 target = item["__target"]
                 src = item["__source"]
-                self._add_edge_to_scene(src, target)
+                self._add_edge_to_scene(src, target, item["id"])
 
     def _state_connect_entered(self):
         self._scene.set_mode(Mode.CONNECT)
@@ -115,17 +116,13 @@ class IMMainWindow(QMainWindow, Ui_MainWindow):
 
     def _make_items_movable(self, movable):
         for item in self._scene.items():
-            try:
-                # hacky hack because of pythons isinstance fails due to import chaos
-                # edges are not selectable or movable
-                item.__hack__()
+            if isinstance(item, GraphicsEdgeItem):
+                # edges are selectable (for delete) but never movable
                 item.setFlag(QGraphicsItem.ItemIsMovable, False)
-                item.setFlag(QGraphicsItem.ItemIsSelectable, False)
-                continue
-            except AttributeError:
-                pass
-            item.setFlag(QGraphicsItem.ItemIsMovable, movable)
-            item.setFlag(QGraphicsItem.ItemIsSelectable, movable)
+                item.setFlag(QGraphicsItem.ItemIsSelectable, True)
+            else:
+                item.setFlag(QGraphicsItem.ItemIsMovable, movable)
+                item.setFlag(QGraphicsItem.ItemIsSelectable, movable)
 
     def _enable_box_select(self, enable):
         if enable:
@@ -145,7 +142,7 @@ class IMMainWindow(QMainWindow, Ui_MainWindow):
         item.setFlag(QGraphicsItem.ItemIsSelectable, True)
         self._scene.addItem(item)
 
-    def _add_edge_to_scene(self, from_id, to_id):
+    def _add_edge_to_scene(self, from_id, to_id, edge_id):
         from_item = None
         to_item = None
         for item in self._scene.items():
@@ -160,7 +157,7 @@ class IMMainWindow(QMainWindow, Ui_MainWindow):
             if node_id == to_id:
                 to_item = item
 
-        self._scene.draw_edge(from_item, to_item, is_new=False)
+        self._scene.draw_edge(from_item, to_item, is_new=False, edge_id=edge_id)
 
     def _on_list_item_clicked(self, event):
         # add new node to model in mv

+ 49 - 34
sketchUI/im_scene.py

@@ -33,22 +33,27 @@ class CustomScene(QGraphicsScene):
         if event.button() == Qt.LeftButton and self._mode == Mode.SELECT:
             # load attributes for selected node
             item = self.itemAt(event.scenePos(), QTransform())
-            if not item or not isinstance(item, GraphicsNodeItem):
+            if not item:
                 return
-
-            self._parent.tableWidget.setRowCount(0)
-            self._parent.tableWidget.blockSignals(True)
-            self._parent.plainTextEdit.appendPlainText("Selected item of type {}".format(item.get_type()))
-            attrs = commons.get_attributes_of_node(self._cur_model, item.node_id)
-            for attr in attrs:
-                table_item_key = QTableWidgetItem(attr.key)
-                table_item_key.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
-                table_item_val = QTableWidgetItem(attr.val)
-                cur_row_cnt = self._parent.tableWidget.rowCount()
-                self._parent.tableWidget.insertRow(cur_row_cnt)
-                self._parent.tableWidget.setItem(cur_row_cnt, 0, table_item_key)
-                self._parent.tableWidget.setItem(cur_row_cnt, 1, table_item_val)
-            self._parent.tableWidget.blockSignals(False)
+            elif isinstance(item, GraphicsNodeItem):
+                self._parent.tableWidget.setRowCount(0)
+                self._parent.tableWidget.blockSignals(True)
+                self._parent.plainTextEdit.appendPlainText("Selected node of type {}".format(item.get_type()))
+                attrs = commons.get_attributes_of_node(self._cur_model, item.node_id)
+                for attr in attrs:
+                    table_item_key = QTableWidgetItem(attr.key)
+                    table_item_key.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
+                    table_item_val = QTableWidgetItem(attr.val)
+                    cur_row_cnt = self._parent.tableWidget.rowCount()
+                    self._parent.tableWidget.insertRow(cur_row_cnt)
+                    self._parent.tableWidget.setItem(cur_row_cnt, 0, table_item_key)
+                    self._parent.tableWidget.setItem(cur_row_cnt, 1, table_item_val)
+                self._parent.tableWidget.blockSignals(False)
+
+            elif isinstance(item, GraphicsEdgeItem):
+                self._parent.plainTextEdit.appendPlainText("Selected edge")
+            else:
+                pass
 
         QGraphicsScene.mousePressEvent(self, event)
 
@@ -89,8 +94,8 @@ class CustomScene(QGraphicsScene):
 
         QGraphicsScene.keyPressEvent(self, event)
 
-    def draw_edge(self, from_item, to_item, is_new):
-        # type: (GraphicsNodeItem, GraphicsNodeItem, bool) -> None
+    def draw_edge(self, from_item, to_item, is_new, edge_id=None):
+        # type: (GraphicsNodeItem, GraphicsNodeItem, bool, str) -> 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).
@@ -102,32 +107,42 @@ class CustomScene(QGraphicsScene):
                 self._parent.plainTextEdit.appendPlainText("Error: Edge not supported between types {} and {}".format(from_type, to_type))
                 return
 
-        line = GraphicsEdgeItem(from_item, to_item)
+        line = GraphicsEdgeItem(from_item, to_item, edge_id)
         line.setFlag(QGraphicsItem.ItemIsMovable, False)
         line.setFlag(QGraphicsItem.ItemIsSelectable, False)
         self.addItem(line)
         line.redraw()
 
         if is_new:
-            mvops.add_edge(self._cur_model, from_item.node_id, to_item.node_id)
+            edge_id = mvops.add_edge(self._cur_model, from_item.node_id, to_item.node_id)
+            line.edge_id = edge_id
             self._parent.plainTextEdit.appendPlainText("Added edge between {} and {} to model".format(from_type, to_type))
 
     def _handle_keypress_delete(self, selected):
-        for item in selected:
-            # delete node in model (also deletes edges in model)
-            if isinstance(item, GraphicsNodeItem):
-                self._parent.plainTextEdit.appendPlainText("Deleting node of type {}".format(item.get_type()))
-                mvops.delete_node(self._cur_model, item.node_id)
-
-                # 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
-                    if edge.from_item.node_id == item.node_id or edge.to_item.node_id == item.node_id:
-                        self.removeItem(edge)
-
-                self.removeItem(item)
+        if not len(selected) == 1:
+            return
+        item = selected[0]
+
+        if isinstance(item, GraphicsNodeItem):
+            # delete node in model (also deletes edges connected to it in model)
+            self._parent.plainTextEdit.appendPlainText("Deleting node of type {}".format(item.get_type()))
+            mvops.delete_node(self._cur_model, item.node_id)
+
+            # 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
+                if edge.from_item.node_id == item.node_id or edge.to_item.node_id == item.node_id:
+                    self.removeItem(edge)
+
+            self.removeItem(item)
+
+        if isinstance(item, GraphicsEdgeItem):
+            self._parent.plainTextEdit.appendPlainText("Deleting edge")
+            mvops.delete_edge(self._cur_model, item.edge_id)
+            self.removeItem(item)
+
 
     def _handle_keypress_attribute(self, selected):
         if not len(selected) == 1:

+ 3 - 0
sketchUI/mvops.py

@@ -24,6 +24,9 @@ def add_edge(model, from_id, to_id, directed=False):
 def delete_node(model, node_id):
     mv.delete_element(model, node_id)
 
+def delete_edge(model, edge_id):
+    mv.delete_element(model, edge_id)
+
 def get_consyn_of(node_type):
     """
     Queries the modelverse for a concrete syntax of elements of type "node_type".

+ 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:   Thu Apr 26 17:38:33 2018
+Date:   Thu Apr 26 19:01:00 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server