| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762 |
- '''
- '''
- from PyQt5 import uic
- 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, \
- QGraphicsColorizeEffect, QFont, QDialog, QTableWidgetItem, \
- QListWidgetItem, QInputDialog, QIcon, QPixmap
- from PyQt5.QtWidgets import QMainWindow, QGraphicsView
- from path import Path
- from core import Mention
- import core
- Ui_window, _ = uic.loadUiType(Path(__file__).parent / 'qt_viewer.ui')
- Ui_details, _ = uic.loadUiType(Path(__file__).parent / 'qt_details.ui')
- Ui_select, _ = uic.loadUiType(Path(__file__).parent / 'qt_select_object.ui')
- Ui_warning, _ = uic.loadUiType(Path(__file__).parent / 'qt_warning.ui')
- palette = {
- "Table": QColor(240, 240, 20),
- "Query": QColor(210, 50, 210),
- "Module": QColor(220, 10, 33),
- "Relation": QColor(122, 50, 209),
- "Report": QColor(25, 10, 220),
- "Form": QColor(10, 180, 220),
- "Macro": QColor(40, 220, 10),
- }
- v_spacing = 120
- cell_width = 150
- cell_spacing = 25
- class GraphicsObject(QGraphicsItemGroup):
- items = []
- def __init__(self, obj, parent=None):
- super(GraphicsObject, self).__init__(parent=parent)
- self.obj = obj
- self.links = []
- self._x = 0
- self._y = 0
- self.setFlag(QGraphicsItem.ItemIsMovable, True)
- self.setFlag(QGraphicsItem.ItemIsSelectable, True)
- self.setFlag(QGraphicsItem.ItemIsFocusable, True)
- self.setAcceptHoverEvents(True)
- self.label = QGraphicsTextItem()
- self.label.setTextWidth(cell_width)
- self.label.setZValue(2)
- self.setText()
- self.addToGroup(self.label)
- pen = QPen(palette[self.obj.type_].darker(150))
- pen.setWidth(2)
- self.rect = QGraphicsRectItem(self.label.boundingRect())
- self.rect.setPen(pen)
- self.rect.setBrush(palette[self.obj.type_].lighter(150))
- self.rect.setZValue(0)
- self.addToGroup(self.rect)
- self.topAnchorCoords = ((self.boundingRect().topLeft().x() + self.boundingRect().topRight().x() / 2), self.boundingRect().topLeft().y())
- self.bottomAnchorCoords = ((self.boundingRect().topLeft().x() + self.boundingRect().topRight().x() / 2), self.boundingRect().bottomLeft().y())
- self.top_anchor = QGraphicsRectItem(self.topAnchorCoords[0] - 3, self.topAnchorCoords[1] - 3, 6, 6)
- self.bottom_anchor = QGraphicsRectItem(self.bottomAnchorCoords[0] - 3, self.bottomAnchorCoords[1] - 3, 6, 6)
- for anchor in (self.top_anchor, self.bottom_anchor):
- anchor.setBrush(QBrush(QColor(255, 153, 51)))
- anchor.setZValue(1)
- self.addToGroup(anchor)
- effect = QGraphicsColorizeEffect()
- effect.setColor(QColor(255, 255, 255))
- effect.setStrength(0.35)
- effect.setEnabled(False)
- self.rect.setGraphicsEffect(effect)
- self.setToolTip("[{}] '{}'".format(self.obj.type_, self.obj.name_))
- GraphicsObject.items.append(self)
- def setText(self):
- self.label.setHtml(self.html())
- def html(self):
- return "[{}]<br/><b>{}</b>".format(self.obj.type_,
- self.obj.name_)
- def topAnchorCenter(self):
- return self.mapToScene(QPointF(*self.topAnchorCoords))
- def bottomAnchorCenter(self):
- return self.mapToScene(QPointF(*self.bottomAnchorCoords))
- def update(self):
- if self.pos() is not QPointF(self._x, self._y):
- self.setPos(QPointF(self._x, self._y))
- for l in self.links:
- l.update()
- def paint(self, *args, **kwargs):
- super(GraphicsObject, self).paint(*args, **kwargs)
- self._x, self._y = self.pos().x(), self.pos().y()
- self.update()
- def setShining(self, active):
- self.rect.graphicsEffect().setEnabled(active)
- def hoverEnterEvent(self, _):
- self.setShining(True)
- def hoverLeaveEvent(self, _):
- self.setShining(False)
- class GraphicsRootObject(GraphicsObject):
- def __init__(self, obj, parent=None):
- super(GraphicsRootObject, self).__init__(obj, parent=parent)
- self.level = 0
- self.deps = []
- self.refs = []
- self._dep_emprise = 0
- self._ref_emprise = 0
- pen = QPen(QColor("red"))
- pen.setWidth(2)
- self.rect.setPen(pen)
- def xleft(self):
- return 0
- def compute_coords(self):
- return 0, 0
- def dep_emprise(self):
- if not self._dep_emprise:
- 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
- def ref_emprise(self):
- if not self._ref_emprise:
- self._ref_emprise = sum([r.ref_emprise() for r in self.refs]) if self.refs else (cell_width + 2 * cell_spacing)
- return self._ref_emprise
- class GraphicsDepObject(GraphicsObject):
- def __init__(self, obj, parentItem, parent=None):
- super(GraphicsDepObject, self).__init__(obj, parent=parent)
- self.deps = []
- self.parentItem = parentItem
- if parentItem:
- parentItem.deps.append(self)
- self.level = parentItem.level + 1
- self._dep_emprise = 0
- def xleft(self):
- x0 = sum([n.dep_emprise() for n in self.parentItem.deps[0:self.parentItem.deps.index(self)]])
- return self.parentItem.xleft() + x0
- def compute_coords(self):
- x0 = sum([n.dep_emprise() for n in self.parentItem.deps[0:self.parentItem.deps.index(self)]])
- x = self.parentItem.xleft() + (0.5 * self.dep_emprise() - (cell_width / 2 + cell_spacing)) + x0
- y = v_spacing * self.level
- return x, y
- def dep_emprise(self):
- if not self._dep_emprise:
- 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 is obj
- and (type(item) in (GraphicsRootObject, GraphicsDepObject, GraphicsRefObject))))
- self.setToolTip("L'objet [{}] '{}' a déjà été placé sur l'arbre".format(self.obj.type_, self.obj.name_))
- def html(self):
- return "* Clone *<br/>" + super(GraphicsCloneDepObject, self).html()
- @property
- def deps(self):
- return []
- @deps.setter
- def deps(self, value):
- pass
- def hoverEnterEvent(self, _):
- self.setShining(True)
- self.clone_of.setShining(True)
- def hoverLeaveEvent(self, _):
- 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)
- self.refs = []
- self.childItem = childItem
- if childItem:
- childItem.refs.append(self)
- self.level = childItem.level - 1
- self._ref_emprise = 0
- def xleft(self):
- x0 = sum([n.ref_emprise() for n in self.childItem.refs[0:self.childItem.refs.index(self)]])
- return self.childItem.xleft() + x0
- def compute_coords(self):
- x0 = sum([n.ref_emprise() for n in self.childItem.refs[0:self.childItem.refs.index(self)]])
- return self.childItem.xleft() + (0.5 * self.ref_emprise() - (cell_width / 2 + cell_spacing)) + x0, v_spacing * self.level
- def ref_emprise(self):
- if not self._ref_emprise:
- 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 is obj
- and (type(item) in (GraphicsRootObject, GraphicsDepObject, GraphicsRefObject))))
- self.setToolTip("L'objet [{}] '{}' a déjà été placé sur l'arbre".format(self.obj.type_, self.obj.name_))
- def html(self):
- return "* Clone *<br/>" + super(GraphicsCloneRefObject, self).html()
- @property
- def refs(self):
- return []
- @refs.setter
- def refs(self, value):
- pass
- def hoverEnterEvent(self, _):
- self.setShining(True)
- self.clone_of.setShining(True)
- def hoverLeaveEvent(self, _):
- self.setShining(False)
- self.clone_of.setShining(False)
- class GraphicsLink(QGraphicsLineItem):
- items = []
- def __init__(self, topGraphicsObject, bottomGraphicsObject, parent=None):
- self.topGraphicsObject = topGraphicsObject
- self.topGraphicsObject.links.append(self)
- self.bottomGraphicsObject = bottomGraphicsObject
- self.bottomGraphicsObject.links.append(self)
- super(QGraphicsLineItem, self).__init__(parent=parent)
- self.update()
- def update(self):
- line = QLineF(self.mapToScene(self.topGraphicsObject.bottomAnchorCenter()), self.mapToScene(self.bottomGraphicsObject.topAnchorCenter()))
- self.setLine(line)
- class Viewer(QMainWindow):
- def __init__(self):
- super (Viewer, self).__init__()
- self.createWidgets()
- def createWidgets(self):
- self.ui = Ui_window()
- self.ui.setupUi(self)
- self.ui.progressBar.setVisible(False)
- self.ui.stackedWidget.setCurrentIndex(0)
- self.ui.stackedView.setCurrentIndex(0)
- 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)
- self.ui.btn_zoom_center.clicked.connect(self.zoom_center)
- self.ui.btn_svg.clicked.connect(self.to_svg)
- self.ui.btn_save.clicked.connect(self.save)
- self.ui.btn_load.clicked.connect(self.open)
- self.ui.treeWidget.itemClicked.connect(self.treeItemSelected)
- self.ui.btn_edit_item.clicked.connect(self.edit_selected_item)
- self.ui.btn_graphic_view.clicked.connect(self.switch_graphic_view)
- self.ui.btn_table_view.clicked.connect(self.switch_table_view)
- self.ui.searchBoxDeps.textChanged.connect(self.filterTblDeps)
- self.ui.searchBoxRefs.textChanged.connect(self.filterTblRefs)
- self._title = "<unknown>"
- core.Analyse.report = self.update_progression
- self.ui.view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
- self.ui.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
- self.ui.view.viewport().installEventFilter(self)
- self._scene = QGraphicsScene()
- self._scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
- self.ui.view.setScene(self._scene)
- 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:
- if event.angleDelta().y() > 0:
- self.zoom_plus()
- elif event.angleDelta().y() < 0:
- self.zoom_minus()
- return True
- 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):
- self.ui.view.scale(1.2, 1.2)
- def zoom_minus(self):
- self.ui.view.scale(0.8, 0.8)
- def zoom_center(self):
- root = next((item for item in GraphicsObject.items if type(item) is GraphicsRootObject))
- rect = root.boundingRect()
- rect.adjust(-200, -200, 200, 200)
- self.ui.view.fitInView(rect, Qt.KeepAspectRatio)
- def switch_graphic_view(self):
- self.ui.stackedView.setCurrentIndex(0)
- def switch_table_view(self):
- self.ui.stackedView.setCurrentIndex(1)
- def to_svg(self):
- fileName, _ = QFileDialog.getSaveFileName(self, "Save File", "", "Svg File (*.svg)")
- if not fileName:
- return
- gen = QSvgGenerator()
- gen.setFileName(fileName)
- gen.setSize(QSize(1000, 1000))
- gen.setViewBox(QRect(0, 0, 1000, 1000))
- gen.setTitle("Access Analyser")
- gen.setDescription("Access Analyser Report for {}".format(self._title))
- painter = QPainter(gen)
- self._scene.render(painter)
- painter.end()
- def save(self):
- if not core.Analyse.objects:
- return
- filepath, _ = QFileDialog.getSaveFileName(self, 'Enregistrer sous', '', "Access Analyser Files (*.acan)")
- if filepath:
- core.Analyse.dump_to(filepath)
- def open(self):
- filepath, _ = QFileDialog.getOpenFileName(self, 'Charger les données de', '', "Access Analyser Files (*.acan)")
- if filepath:
- core.Analyse.load_from(filepath)
- self._title = Path(filepath).name
- self.load()
- def update_progression(self, i, total, msg=""):
- self.ui.progressBar.setMaximum(total)
- self.ui.progressBar.setValue(i)
- if msg:
- self.ui.txtPanel.append(msg)
- QApplication.processEvents()
- 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):
- source_dir = Path(source_dir)
- self._title = source_dir
- self.ui.stackedWidget.setCurrentIndex(0)
- self.ui.progressBar.setVisible(True)
- self.ui.txtPanel.clear()
- core.Analyse.run(source_dir)
- self.ui.progressBar.setVisible(False)
- self.ui.txtPanel.clear()
- self.load()
- duplicates = core.Analyse.duplicates()
- if duplicates:
- msg = "Les noms d'objets suivants sont utilisés simultanément par plusieurs objets:\n"
- msg += "\n".join(["- {} ({})".format(key, ", ".join([obj.type_ for obj in val])) for key, val in duplicates.items()])
- msg += "\n Veuillez corriger manuellement les rélérences des objets succeptibles de contenir des erreurs."
- dlg = WarningDialog(msg, parent=self)
- dlg.show()
- dlg.exec_()
- QMessageBox.information(self, "Analyse", "Analyse terminée: {} objets chargés en mémoire".format(len(core.Analyse.objects)))
- def load(self):
- self.clear_scene()
- self.ui.treeWidget.clear()
- self.ui.stackedWidget.setCurrentIndex(1)
- topitem = QTreeWidgetItem()
- topitem.setText(0, "Objets")
- self.ui.treeWidget.addTopLevelItem(topitem)
- groupes = {}
- for index, obj in enumerate(core.Analyse.objects):
- if not obj.type_ in groupes:
- item = QTreeWidgetItem()
- item.setText(0, obj.type_)
- groupes[obj.type_] = item
- topitem.addChild(item)
- item = QTreeWidgetItem()
- if any(m.warning for m in obj.mentions):
- item.setIcon(0, QIcon(QPixmap(core.here / "rsc\\warning_16.png")))
- item.setText(1, obj.name_)
- item.setData(2, 0, index)
- groupes[obj.type_].addChild(item)
- self.ui.treeWidget.setColumnHidden(2, True)
- self.ui.treeWidget.expandToDepth(1)
- self.ui.btn_save.setEnabled(True)
- def enable_view_buttons(self, enable):
- self.ui.btn_zoom_plus.setEnabled(enable)
- self.ui.btn_zoom_center.setEnabled(enable)
- self.ui.btn_zoom_view.setEnabled(enable)
- self.ui.btn_zoom_minus.setEnabled(enable)
- self.ui.btn_graphic_view.setEnabled(enable)
- self.ui.btn_table_view.setEnabled(enable)
- def clear_scene(self):
- self._scene.clear()
- GraphicsObject.items = []
- self.enable_view_buttons(False)
- def maj_view_with(self, root_object):
- self.switch_graphic_view()
- self.clear_scene()
- root = GraphicsRootObject(root_object)
- self._scene.addItem(root)
- def _addDeps(go):
- for dep in go.obj.deps:
- if dep not in [go.obj for go in GraphicsObject.items]:
- gdep = GraphicsDepObject(dep, go)
- if dep.deps:
- _addDeps(gdep)
- else:
- gdep = GraphicsCloneDepObject(dep, go)
- self._scene.addItem(gdep)
- link = GraphicsLink(go, gdep)
- self._scene.addItem(link)
- _addDeps(root)
- def _addRefs(go):
- for ref in go.obj.refs:
- if ref not in [go.obj for go in GraphicsObject.items]:
- gref = GraphicsRefObject(ref, go)
- if ref.refs:
- _addRefs(gref)
- else:
- gref = GraphicsCloneRefObject(ref, go)
- self._scene.addItem(gref)
- link = GraphicsLink(gref, go)
- self._scene.addItem(link)
- _addRefs(root)
- 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.tblDeps.clearContents()
- self.ui.tblRefs.clearContents()
- self.ui.tblDeps.setRowCount(0)
- self.ui.tblRefs.setRowCount(0)
- self.ui.lblRootTitle.setText("{}: {}".format(root_object.type_, root_object.name_))
- for item in GraphicsObject.items:
- if type(item) is GraphicsDepObject:
- row = self.ui.tblDeps.rowCount()
- self.ui.tblDeps.insertRow(row)
- self.ui.tblDeps.setItem(row, 0, QTableWidgetItem(item.obj.type_))
- self.ui.tblDeps.setItem(row, 1, QTableWidgetItem(item.obj.name_))
- if type(item) is GraphicsRefObject:
- row = self.ui.tblRefs.rowCount()
- self.ui.tblRefs.insertRow(row)
- self.ui.tblRefs.setItem(row, 0, QTableWidgetItem(item.obj.type_))
- self.ui.tblRefs.setItem(row, 1, QTableWidgetItem(item.obj.name_))
- self.enable_view_buttons(True)
- self.fit_in_view()
- def treeItemSelected(self, item):
- index = item.data(2, 0)
- if index is None:
- self.ui.btn_edit_item.setEnabled(False)
- return
- obj = core.Analyse.objects[index]
- self.maj_view_with(obj)
- self.ui.btn_edit_item.setEnabled(True)
- def filterTblDeps(self, filterStr):
- for row in range(self.ui.tblDeps.rowCount()):
- content = "{}{}".format(self.ui.tblDeps.item(row, 0).text(), self.ui.tblDeps.item(row, 1).text())
- self.ui.tblDeps.setRowHidden(row, filterStr.lower() not in content.lower())
- def filterTblRefs(self, filterStr):
- for row in range(self.ui.tblRefs.rowCount()):
- content = "{}{}".format(self.ui.tblRefs.item(row, 0).text(), self.ui.tblRefs.item(row, 1).text())
- self.ui.tblRefs.setRowHidden(row, filterStr.lower() not in content.lower())
- def edit_selected_item(self):
- index = self.ui.treeWidget.currentItem().data(2, 0)
- obj = core.Analyse.objects[index]
- dlg = DetailsDialog(obj, self)
- dlg.show()
- r = dlg.exec_()
- if r:
- core.Analyse.build_trees()
- self.maj_view_with(obj)
- if any(m.warning for m in obj.mentions):
- self.ui.treeWidget.currentItem().setIcon(0, QIcon(QPixmap(core.here / "rsc\\warning_16.png")))
- else:
- self.ui.treeWidget.currentItem().setIcon(0, QIcon())
- def keyPressEvent(self, e):
- if e.key() == Qt.Key_S and e.modifiers() & Qt.ControlModifier:
- self.save()
- e.accept()
- if e.key() == Qt.Key_Control:
- self.ui.view.setDragMode(QGraphicsView.ScrollHandDrag)
- e.accept()
- def keyReleaseEvent(self, e):
- if e.key() == Qt.Key_Control:
- self.ui.view.setDragMode(QGraphicsView.RubberBandDrag)
- class DetailsDialog(QDialog):
- def __init__(self, obj, parent=None):
- self.obj = obj
- super (DetailsDialog, self).__init__(parent)
- self.createWidgets()
- def createWidgets(self):
- self.ui = Ui_details()
- self.ui.setupUi(self)
- self.ui.tbl_mentions.verticalHeader().sectionClicked.connect(self.verticalHeaderClicked)
- self.ui.tbl_mentions.itemClicked.connect(self.itemClicked)
- self.ui.btn_add.clicked.connect(self.add_mention)
- self.ui.btn_edit.clicked.connect(self.edit_mention)
- self.ui.btn_del.clicked.connect(self.del_mention)
- self.ui.btn_ok.clicked.connect(self.ok)
- self.ui.lbl_title.setText("{}: {}".format(self.obj.type_, self.obj.name_))
- self.ui.tbl_mentions.hideColumn(0)
- self.ui.tbl_mentions.setColumnWidth(1, 50)
- self.ui.tbl_mentions.setColumnWidth(2, 70)
- self.ui.tbl_mentions.setColumnWidth(3, 150)
- self.load_table()
- def load_table(self):
- self.ui.tbl_mentions.setSortingEnabled(False)
- self.ui.tbl_mentions.clearContents()
- self.ui.tbl_mentions.setRowCount(len(self.obj.mentions))
- for index, mention in enumerate(self.obj.mentions):
- item = QTableWidgetItem("")
- if mention.warning:
- item.setIcon(QIcon(QPixmap(core.here / "rsc\\warning_16.png")))
- item.setToolTip(mention.warning)
- self.ui.tbl_mentions.setVerticalHeaderItem(index, item)
- item = QTableWidgetItem("")
- item.setData(0, index)
- self.ui.tbl_mentions.setItem(index, 0, item)
- item = QTableWidgetItem("{}".format(mention.line))
- self.ui.tbl_mentions.setItem(index, 1, item)
- item = QTableWidgetItem("{}".format(mention.obj.type_))
- self.ui.tbl_mentions.setItem(index, 2, item)
- item = QTableWidgetItem("{}".format(mention.objname))
- self.ui.tbl_mentions.setItem(index, 3, item)
- item = QTableWidgetItem("{}".format(mention.quote))
- item.setFont(QFont("Consolas", 8))
- self.ui.tbl_mentions.setItem(index, 4, item)
- self.ui.tbl_mentions.setSortingEnabled(True)
- def itemClicked(self, _):
- self.ui.btn_edit.setEnabled(True)
- self.ui.btn_del.setEnabled(True)
- def verticalHeaderClicked(self, row):
- index = self.ui.tbl_mentions.item(row, 0).data(0)
- mention = self.obj.mentions[index]
- if mention.warning:
- if QMessageBox.question(self, "Confirmation", "Voulez-vous supprimer cet avertissement?") == QMessageBox.Yes:
- mention.warning = ""
- self.ui.tbl_mentions.setVerticalHeaderItem(row, QTableWidgetItem(""))
- def add_mention(self):
- dlg = ObjectSelectorDialog(parent=self)
- dlg.show()
- r = dlg.exec_()
- if not r:
- return
- mention = Mention(0, dlg.obj.name_, "(ajouté manuellement)", dlg.obj)
- linenum, _ = QInputDialog.getInt(self, "Ligne", "Numéro de ligne correspondant dans le code-source? (facultatif)", 0)
- if linenum > 0:
- mention.line = linenum
- try:
- with open(self.obj.sourcefile, "r", encoding='utf-8') as f:
- mention.quote = next((line.strip() for i, line in enumerate(f) if i == linenum - 1)).strip()
- except FileNotFoundError:
- pass
- self.obj.mentions.append(mention)
- self.load_table()
- def selected_index(self):
- row = self.ui.tbl_mentions.currentRow()
- if row < 0:
- return None
- return self.ui.tbl_mentions.item(row, 0).data(0)
- def edit_mention(self):
- row = self.ui.tbl_mentions.currentRow()
- if row < 0:
- return
- item = QTableWidgetItem("")
- item.setIcon(QIcon(QPixmap(core.here / "rsc\\edit_16.png")))
- self.ui.tbl_mentions.setVerticalHeaderItem(row, item)
- index = self.ui.tbl_mentions.item(row, 0).data(0)
- mention = self.obj.mentions[index]
- dlg = ObjectSelectorDialog(filterStr=mention.objname, parent=self)
- dlg.show()
- r = dlg.exec_()
- if r:
- mention.obj = dlg.obj
- mention.warning = ""
- self.load_table()
- def del_mention(self):
- index = self.selected_index()
- if not QMessageBox.question(self, "Confirmation", "Etes-vous sûr de vouloir supprimer la référence sélectionnée?") == QMessageBox.Yes:
- return
- del self.obj.mentions[index]
- self.load_table()
- def ok(self):
- self.done(1)
- def keyPressEvent(self, e):
- if e.key() == Qt.Key_Delete:
- if self.ui.tbl_mentions.currentRow() < 0:
- return
- self.del_mention()
- e.accept()
- class ObjectSelectorDialog(QDialog):
- def __init__(self, filterStr="", parent=None):
- self.obj = None
- super (ObjectSelectorDialog, self).__init__(parent)
- self.createWidgets()
- self.ui.searchBox.setText(filterStr)
- def createWidgets(self):
- self.ui = Ui_select()
- self.ui.setupUi(self)
- for obj in core.Analyse.objects:
- item = QListWidgetItem("{} - {}".format(obj.type_, obj.name_))
- item.obj = obj
- self.ui.listWidget.addItem(item)
- self.ui.searchBox.textChanged.connect(self.filter)
- self.ui.listWidget.itemClicked.connect(self.itemClicked)
- self.ui.listWidget.itemDoubleClicked.connect(self.itemDoubleClicked)
- self.ui.btn_ok.clicked.connect(self.ok)
- def itemClicked(self, item):
- self.obj = item.obj
- self.ui.btn_ok.setEnabled(True)
- def itemDoubleClicked(self, item):
- self.itemClicked(item)
- self.ok()
- def filter(self, filterStr):
- for i in range(self.ui.listWidget.count()):
- item = self.ui.listWidget.item(i)
- item.setHidden(filterStr.lower() not in item.text().lower())
- def ok(self):
- self.done(1)
- def done(self, status):
- if not status:
- self.obj = None
- super(ObjectSelectorDialog, self).done(status)
- class WarningDialog(QDialog):
- def __init__(self, msg="", parent=None):
- super (WarningDialog, self).__init__(parent)
- self.createWidgets()
- self.ui.displayText.setPlainText(msg)
- def createWidgets(self):
- self.ui = Ui_warning()
- self.ui.setupUi(self)
|