|
@@ -7,7 +7,8 @@ from PyQt5.Qt import Qt, QEvent, QGraphicsScene, QPointF, QFileDialog, \
|
|
|
QApplication, QMessageBox, QTreeWidgetItem, \
|
|
QApplication, QMessageBox, QTreeWidgetItem, \
|
|
|
QGraphicsTextItem, QGraphicsItem, QGraphicsRectItem, \
|
|
QGraphicsTextItem, QGraphicsItem, QGraphicsRectItem, \
|
|
|
QBrush, QColor, QGraphicsLineItem, QLineF, \
|
|
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 PyQt5.QtWidgets import QMainWindow, QGraphicsView
|
|
|
from path import Path
|
|
from path import Path
|
|
|
|
|
|
|
@@ -36,7 +37,6 @@ class GraphicsObject(QGraphicsItemGroup):
|
|
|
def __init__(self, obj, parent=None):
|
|
def __init__(self, obj, parent=None):
|
|
|
super(GraphicsObject, self).__init__(parent=parent)
|
|
super(GraphicsObject, self).__init__(parent=parent)
|
|
|
self.obj = obj
|
|
self.obj = obj
|
|
|
- self._text = "[{}]<br/><b>{}</b>".format(obj.type_, obj.nom)
|
|
|
|
|
self.links = []
|
|
self.links = []
|
|
|
self._x = 0
|
|
self._x = 0
|
|
|
self._y = 0
|
|
self._y = 0
|
|
@@ -44,11 +44,12 @@ class GraphicsObject(QGraphicsItemGroup):
|
|
|
self.setFlag(QGraphicsItem.ItemIsMovable, True)
|
|
self.setFlag(QGraphicsItem.ItemIsMovable, True)
|
|
|
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
|
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
|
|
|
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
|
|
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
|
|
|
|
|
+ self.setAcceptHoverEvents(True)
|
|
|
|
|
|
|
|
self.label = QGraphicsTextItem()
|
|
self.label = QGraphicsTextItem()
|
|
|
- self.label.setHtml(self._text)
|
|
|
|
|
self.label.setTextWidth(cell_width)
|
|
self.label.setTextWidth(cell_width)
|
|
|
self.label.setZValue(2)
|
|
self.label.setZValue(2)
|
|
|
|
|
+ self.setText()
|
|
|
self.addToGroup(self.label)
|
|
self.addToGroup(self.label)
|
|
|
|
|
|
|
|
pen = QPen(palette[self.obj.type_].darker(150))
|
|
pen = QPen(palette[self.obj.type_].darker(150))
|
|
@@ -68,8 +69,15 @@ class GraphicsObject(QGraphicsItemGroup):
|
|
|
anchor.setZValue(1)
|
|
anchor.setZValue(1)
|
|
|
self.addToGroup(anchor)
|
|
self.addToGroup(anchor)
|
|
|
|
|
|
|
|
|
|
+ effect = QGraphicsColorizeEffect()
|
|
|
|
|
+ effect.setEnabled(False)
|
|
|
|
|
+ self.rect.setGraphicsEffect(effect)
|
|
|
|
|
+
|
|
|
GraphicsObject.items.append(self)
|
|
GraphicsObject.items.append(self)
|
|
|
|
|
|
|
|
|
|
+ def setText(self):
|
|
|
|
|
+ self.label.setHtml("[{}]<br/><b>{}</b>".format(self.obj.type_, self.obj.nom))
|
|
|
|
|
+
|
|
|
def topAnchorCenter(self):
|
|
def topAnchorCenter(self):
|
|
|
return self.mapToScene(QPointF(*self.topAnchorCoords))
|
|
return self.mapToScene(QPointF(*self.topAnchorCoords))
|
|
|
|
|
|
|
@@ -87,6 +95,15 @@ class GraphicsObject(QGraphicsItemGroup):
|
|
|
self._x, self._y = self.pos().x(), self.pos().y()
|
|
self._x, self._y = self.pos().x(), self.pos().y()
|
|
|
self.update()
|
|
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):
|
|
class GraphicsRootObject(GraphicsObject):
|
|
|
def __init__(self, obj, parent=None):
|
|
def __init__(self, obj, parent=None):
|
|
|
super(GraphicsRootObject, self).__init__(obj, parent=parent)
|
|
super(GraphicsRootObject, self).__init__(obj, parent=parent)
|
|
@@ -99,14 +116,8 @@ class GraphicsRootObject(GraphicsObject):
|
|
|
def xleft(self):
|
|
def xleft(self):
|
|
|
return 0
|
|
return 0
|
|
|
|
|
|
|
|
-# def compute_coords(self):
|
|
|
|
|
-# return 0, 0
|
|
|
|
|
-
|
|
|
|
|
def compute_coords(self):
|
|
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):
|
|
def dep_emprise(self):
|
|
|
if not self._dep_emprise:
|
|
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)
|
|
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
|
|
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):
|
|
class GraphicsRefObject(GraphicsObject):
|
|
|
def __init__(self, obj, childItem, parent=None):
|
|
def __init__(self, obj, childItem, parent=None):
|
|
|
super(GraphicsRefObject, self).__init__(obj, parent=parent)
|
|
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)
|
|
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
|
|
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):
|
|
class GraphicsLink(QGraphicsLineItem):
|
|
|
items = []
|
|
items = []
|
|
@@ -200,7 +262,6 @@ class Viewer(QMainWindow):
|
|
|
super (Viewer, self).__init__()
|
|
super (Viewer, self).__init__()
|
|
|
self.createWidgets()
|
|
self.createWidgets()
|
|
|
|
|
|
|
|
- # ## UI related methods
|
|
|
|
|
def createWidgets(self):
|
|
def createWidgets(self):
|
|
|
self.ui = Ui_window()
|
|
self.ui = Ui_window()
|
|
|
self.ui.setupUi(self)
|
|
self.ui.setupUi(self)
|
|
@@ -210,7 +271,7 @@ class Viewer(QMainWindow):
|
|
|
|
|
|
|
|
self.ui.btn_test.clicked.connect(self.test)
|
|
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_plus.clicked.connect(self.zoom_plus)
|
|
|
self.ui.btn_zoom_minus.clicked.connect(self.zoom_minus)
|
|
self.ui.btn_zoom_minus.clicked.connect(self.zoom_minus)
|
|
|
self.ui.btn_zoom_view.clicked.connect(self.fit_in_view)
|
|
self.ui.btn_zoom_view.clicked.connect(self.fit_in_view)
|
|
@@ -225,8 +286,18 @@ class Viewer(QMainWindow):
|
|
|
|
|
|
|
|
self._scene = QGraphicsScene()
|
|
self._scene = QGraphicsScene()
|
|
|
self._scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
|
|
self._scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
|
|
|
|
|
+
|
|
|
self.ui.view.setScene(self._scene)
|
|
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):
|
|
def eventFilter(self, _, event):
|
|
|
if event.type() == QEvent.Wheel:
|
|
if event.type() == QEvent.Wheel:
|
|
@@ -238,6 +309,9 @@ class Viewer(QMainWindow):
|
|
|
return False
|
|
return False
|
|
|
|
|
|
|
|
def fit_in_view(self):
|
|
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)
|
|
self.ui.view.fitInView(self._scene.sceneRect(), Qt.KeepAspectRatio)
|
|
|
|
|
|
|
|
def zoom_plus(self):
|
|
def zoom_plus(self):
|
|
@@ -268,9 +342,14 @@ class Viewer(QMainWindow):
|
|
|
self.ui.txtPanel.append(msg)
|
|
self.ui.txtPanel.append(msg)
|
|
|
QApplication.processEvents()
|
|
QApplication.processEvents()
|
|
|
|
|
|
|
|
- def run(self):
|
|
|
|
|
-
|
|
|
|
|
|
|
+ def selectSourceDir(self):
|
|
|
source_dir = QFileDialog.getExistingDirectory(self, "Sélectionner le répertoire des sources", "", QFileDialog.ShowDirsOnly)
|
|
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.progressBar.setVisible(True)
|
|
|
self.ui.lbl_repertoire.setText(source_dir)
|
|
self.ui.lbl_repertoire.setText(source_dir)
|
|
@@ -320,10 +399,11 @@ class Viewer(QMainWindow):
|
|
|
|
|
|
|
|
def _addDeps(go):
|
|
def _addDeps(go):
|
|
|
for dep in go.obj.deps:
|
|
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)
|
|
self._scene.addItem(gdep)
|
|
|
|
|
|
|
|
link = GraphicsLink(go, gdep)
|
|
link = GraphicsLink(go, gdep)
|
|
@@ -334,10 +414,10 @@ class Viewer(QMainWindow):
|
|
|
|
|
|
|
|
def _addRefs(go):
|
|
def _addRefs(go):
|
|
|
for ref in go.obj.refs:
|
|
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)
|
|
self._scene.addItem(gref)
|
|
|
|
|
|
|
|
link = GraphicsLink(gref, go)
|
|
link = GraphicsLink(gref, go)
|
|
@@ -348,38 +428,25 @@ class Viewer(QMainWindow):
|
|
|
|
|
|
|
|
for item in GraphicsObject.items:
|
|
for item in GraphicsObject.items:
|
|
|
item._x, item._y = item.compute_coords()
|
|
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()
|
|
item.update()
|
|
|
|
|
|
|
|
self.ui.btn_save.setEnabled(True)
|
|
self.ui.btn_save.setEnabled(True)
|
|
|
|
|
+
|
|
|
self.fit_in_view()
|
|
self.fit_in_view()
|
|
|
|
|
|
|
|
def treeItemSelected(self, item):
|
|
def treeItemSelected(self, item):
|
|
|
index = item.data(1, 0)
|
|
index = item.data(1, 0)
|
|
|
|
|
+ if not index:
|
|
|
|
|
+ return
|
|
|
obj = core.Analyse.objects[index]
|
|
obj = core.Analyse.objects[index]
|
|
|
self.maj_scene_with(obj)
|
|
self.maj_scene_with(obj)
|
|
|
|
|
|
|
|
def test(self):
|
|
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):
|
|
def keyPressEvent(self, e):
|
|
|
if e.key() == Qt.Key_Control:
|
|
if e.key() == Qt.Key_Control:
|