Ver Fonte

Viewer OK

olivier.massot há 7 anos atrás
pai
commit
c6afce9df9
2 ficheiros alterados com 112 adições e 45 exclusões
  1. 111 44
      Viewer.py
  2. 1 1
      core.py

+ 111 - 44
Viewer.py

@@ -7,7 +7,8 @@ from PyQt5.Qt import Qt, QEvent, QGraphicsScene, QPointF, QFileDialog, \
     QApplication, QMessageBox, QTreeWidgetItem, \
     QGraphicsTextItem, QGraphicsItem, QGraphicsRectItem, \
     QBrush, QColor, QGraphicsLineItem, QLineF, \
-    QPen, QPainter, QSvgGenerator, QSize, QRect, QGraphicsItemGroup
+    QPen, QPainter, QSvgGenerator, QSize, QRect, QGraphicsItemGroup, \
+    QGraphicsColorizeEffect, QFont
 from PyQt5.QtWidgets import QMainWindow, QGraphicsView
 from path import Path
 
@@ -36,7 +37,6 @@ class GraphicsObject(QGraphicsItemGroup):
     def __init__(self, obj, parent=None):
         super(GraphicsObject, self).__init__(parent=parent)
         self.obj = obj
-        self._text = "[{}]<br/><b>{}</b>".format(obj.type_, obj.nom)
         self.links = []
         self._x = 0
         self._y = 0
@@ -44,11 +44,12 @@ class GraphicsObject(QGraphicsItemGroup):
         self.setFlag(QGraphicsItem.ItemIsMovable, True)
         self.setFlag(QGraphicsItem.ItemIsSelectable, True)
         self.setFlag(QGraphicsItem.ItemIsFocusable, True)
+        self.setAcceptHoverEvents(True)
 
         self.label = QGraphicsTextItem()
-        self.label.setHtml(self._text)
         self.label.setTextWidth(cell_width)
         self.label.setZValue(2)
+        self.setText()
         self.addToGroup(self.label)
 
         pen = QPen(palette[self.obj.type_].darker(150))
@@ -68,8 +69,15 @@ class GraphicsObject(QGraphicsItemGroup):
             anchor.setZValue(1)
             self.addToGroup(anchor)
 
+        effect = QGraphicsColorizeEffect()
+        effect.setEnabled(False)
+        self.rect.setGraphicsEffect(effect)
+
         GraphicsObject.items.append(self)
 
+    def setText(self):
+        self.label.setHtml("[{}]<br/><b>{}</b>".format(self.obj.type_, self.obj.nom))
+
     def topAnchorCenter(self):
         return self.mapToScene(QPointF(*self.topAnchorCoords))
 
@@ -87,6 +95,15 @@ class GraphicsObject(QGraphicsItemGroup):
         self._x, self._y = self.pos().x(), self.pos().y()
         self.update()
 
+    def setShining(self, active):
+        self.rect.graphicsEffect().setEnabled(active)
+
+    def hoverEnterEvent(self, *args, **kwargs):
+        self.setShining(True)
+
+    def hoverLeaveEvent(self, *args, **kwargs):
+        self.setShining(False)
+
 class GraphicsRootObject(GraphicsObject):
     def __init__(self, obj, parent=None):
         super(GraphicsRootObject, self).__init__(obj, parent=parent)
@@ -99,14 +116,8 @@ class GraphicsRootObject(GraphicsObject):
     def xleft(self):
         return 0
 
-#     def compute_coords(self):
-#         return 0, 0
-
     def compute_coords(self):
-        return (0.5 * self.emprise() - (cell_width / 2 + cell_spacing)), 0
-
-    def emprise(self):
-        return max([self.dep_emprise(), self.ref_emprise()])
+        return 0, 0
 
     def dep_emprise(self):
         if not self._dep_emprise:
@@ -143,6 +154,33 @@ class GraphicsDepObject(GraphicsObject):
             self._dep_emprise = sum([d.dep_emprise() for d in self.deps]) if self.deps else (cell_width + 2 * cell_spacing)
         return self._dep_emprise
 
+class GraphicsCloneDepObject(GraphicsDepObject):
+    def __init__(self, obj, childItem, parent=None):
+        super(GraphicsCloneDepObject, self).__init__(obj, childItem, parent)
+        self.bottom_anchor.setBrush(QColor("red"))
+        self.clone_of = next((item for item in GraphicsObject.items if item.obj == obj
+                                                            and type(item) is GraphicsDepObject
+                                                            or type(item) is GraphicsRefObject))
+
+    def setText(self):
+        self.label.setHtml("[{}]<br/><b>{}</b><br/>(!) Clône".format(self.obj.type_, self.obj.nom))
+
+    @property
+    def deps(self):
+        return []
+
+    @deps.setter
+    def deps(self, value):
+        pass
+
+    def hoverEnterEvent(self, *args, **kwargs):
+        self.setShining(True)
+        self.clone_of.setShining(True)
+
+    def hoverLeaveEvent(self, *args, **kwargs):
+        self.setShining(False)
+        self.clone_of.setShining(False)
+
 class GraphicsRefObject(GraphicsObject):
     def __init__(self, obj, childItem, parent=None):
         super(GraphicsRefObject, self).__init__(obj, parent=parent)
@@ -166,6 +204,30 @@ class GraphicsRefObject(GraphicsObject):
             self._ref_emprise = sum([d.ref_emprise() for d in self.refs]) if self.refs else (cell_width + 2 * cell_spacing)
         return self._ref_emprise
 
+class GraphicsCloneRefObject(GraphicsRefObject):
+    def __init__(self, obj, childItem, parent=None):
+        super(GraphicsCloneRefObject, self).__init__(obj, childItem, parent)
+        self.top_anchor.setBrush(QColor("red"))
+        self.clone_of = next((item for item in GraphicsObject.items if item.obj == obj
+                                                                    and type(item) is GraphicsDepObject
+                                                                    or type(item) is GraphicsRefObject))
+
+    def setText(self):
+        self.label.setHtml("[{}]<br/><b>{}</b><br/>(!) Clône".format(self.obj.type_, self.obj.nom))
+
+    @property
+    def refs(self):
+        return []
+
+    @refs.setter
+    def refs(self, value):
+        pass
+
+    def hoverEnterEvent(self, *args, **kwargs):
+        self.clone_of.setShining(True)
+
+    def hoverLeaveEvent(self, *args, **kwargs):
+        self.clone_of.setShining(False)
 
 class GraphicsLink(QGraphicsLineItem):
     items = []
@@ -200,7 +262,6 @@ class Viewer(QMainWindow):
         super (Viewer, self).__init__()
         self.createWidgets()
 
-    # ## UI related methods
     def createWidgets(self):
         self.ui = Ui_window()
         self.ui.setupUi(self)
@@ -210,7 +271,7 @@ class Viewer(QMainWindow):
 
         self.ui.btn_test.clicked.connect(self.test)
 
-        self.ui.btn_select.clicked.connect(self.run)
+        self.ui.btn_select.clicked.connect(self.selectSourceDir)
         self.ui.btn_zoom_plus.clicked.connect(self.zoom_plus)
         self.ui.btn_zoom_minus.clicked.connect(self.zoom_minus)
         self.ui.btn_zoom_view.clicked.connect(self.fit_in_view)
@@ -225,8 +286,18 @@ class Viewer(QMainWindow):
 
         self._scene = QGraphicsScene()
         self._scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
+
         self.ui.view.setScene(self._scene)
-        self.fit_in_view()
+
+        helpLabel = QGraphicsTextItem()
+        helpLabel.setPlainText("Sélectionnez le répertoire contenant les sources de la base à analyser,\npuis sélectionnez dans la liste de droite un objet à partir duquel afficher les dépendances...")
+        helpLabel.setTextWidth(600)
+        font = QFont()
+        font.setItalic(True)
+        font.setWeight(63)
+        helpLabel.setFont(font)
+
+        self._scene.addItem(helpLabel)
 
     def eventFilter(self, _, event):
         if event.type() == QEvent.Wheel:
@@ -238,6 +309,9 @@ class Viewer(QMainWindow):
         return False
 
     def fit_in_view(self):
+        rect = self._scene.itemsBoundingRect()
+        rect.adjust(-50, -50, 50, 50)
+        self._scene.setSceneRect(rect)
         self.ui.view.fitInView(self._scene.sceneRect(), Qt.KeepAspectRatio)
 
     def zoom_plus(self):
@@ -268,9 +342,14 @@ class Viewer(QMainWindow):
             self.ui.txtPanel.append(msg)
         QApplication.processEvents()
 
-    def run(self):
-
+    def selectSourceDir(self):
         source_dir = QFileDialog.getExistingDirectory(self, "Sélectionner le répertoire des sources", "", QFileDialog.ShowDirsOnly)
+        if not source_dir:
+            return
+        self.run(source_dir)
+
+
+    def run(self, source_dir):
 
         self.ui.progressBar.setVisible(True)
         self.ui.lbl_repertoire.setText(source_dir)
@@ -320,10 +399,11 @@ class Viewer(QMainWindow):
 
         def _addDeps(go):
             for dep in go.obj.deps:
-                if dep in [go.obj for go in GraphicsObject.items]:
-                    print("ref circulaire: {}".format(dep))
-                    continue
-                gdep = GraphicsDepObject(dep, go)
+                if dep not in [go.obj for go in GraphicsObject.items]:
+                    gdep = GraphicsDepObject(dep, go)
+                else:
+                    gdep = GraphicsCloneDepObject(dep, go)
+
                 self._scene.addItem(gdep)
 
                 link = GraphicsLink(go, gdep)
@@ -334,10 +414,10 @@ class Viewer(QMainWindow):
 
         def _addRefs(go):
             for ref in go.obj.refs:
-                if ref in [go.obj for go in GraphicsObject.items]:
-                    print("ref circulaire: {}".format(ref))
-                    continue
-                gref = GraphicsRefObject(ref, go)
+                if ref not in [go.obj for go in GraphicsObject.items]:
+                    gref = GraphicsRefObject(ref, go)
+                else:
+                    gref = GraphicsCloneRefObject(ref, go)
                 self._scene.addItem(gref)
 
                 link = GraphicsLink(gref, go)
@@ -348,38 +428,25 @@ class Viewer(QMainWindow):
 
         for item in GraphicsObject.items:
             item._x, item._y = item.compute_coords()
+            if isinstance(item, GraphicsDepObject):
+                item._x -= (root.dep_emprise() - (cell_width + 2 * cell_spacing)) / 2
+            if isinstance(item, GraphicsRefObject):
+                item._x -= (root.ref_emprise() - (cell_width + 2 * cell_spacing)) / 2
             item.update()
 
         self.ui.btn_save.setEnabled(True)
+
         self.fit_in_view()
 
     def treeItemSelected(self, item):
         index = item.data(1, 0)
+        if not index:
+            return
         obj = core.Analyse.objects[index]
         self.maj_scene_with(obj)
 
     def test(self):
-        a = AccessObject("queries", "testA_", "")
-        b = AccessObject("queries", "testB", "")
-        c = AccessObject("tables", "testC", "")
-        d = AccessObject("tables", "testD", "")
-        e = AccessObject("modules", "testE", "")
-        f = AccessObject("relations", "testF", "")
-        g = AccessObject("reports", "testG", "")
-        h = AccessObject("forms", "testH", "")
-        i = AccessObject("scripts", "testI", "")
-
-        j = AccessObject("reports", "testJ", "")
-        k = AccessObject("forms", "testK", "")
-        l = AccessObject("scripts", "testL", "")
-
-        b.deps = [e, f, g]
-        c.deps = [h, i]
-        a.deps = [b, c, d]
-        j.refs = [k, l]
-        a.refs = [j]
-
-        self.maj_scene_with(a)
+        self.run(Path(__file__).parent / r"test\source")
 
     def keyPressEvent(self, e):
         if e.key() == Qt.Key_Control:

+ 1 - 1
core.py

@@ -51,7 +51,7 @@ class AccessObject():
             self.deps.append(obj)
 
     def add_ref(self, obj):
-        if not obj in self.ref_by:
+        if not obj in self.refs:
             self.refs.append(obj)
 
 class Analyse():