| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- """
- """
- from core import mncheck, checking
- import logging
- from qgis.core import QgsProject
- from PyQt5 import QtWidgets
- from PyQt5 import uic
- from PyQt5.Qt import Qt
- from PyQt5.QtCore import QObject, pyqtSignal
- from PyQt5.QtGui import QIcon, QPixmap
- from PyQt5.QtWidgets import QApplication, QTreeWidgetItem
- from core.checking import TestResult
- from core.constants import MAIN, RSCDIR, VERSION
- from ui.dlg_contact import DlgContact
- logger = logging.getLogger("mncheck")
- Ui_Main, _ = uic.loadUiType(MAIN / 'ui'/ 'dlg_main.ui')
- class QComlink(QObject):
- started_test = pyqtSignal(TestResult)
- ended_test = pyqtSignal(TestResult)
-
- def _started_test(self, test):
- self.started_test.emit(test)
-
- def _ended_test(self, test):
- self.ended_test.emit(test)
-
- class DlgMain(QtWidgets.QDialog):
- def __init__(self, iface, parent=None):
- super().__init__(parent)
- self.available_schemas = mncheck.list_schemas()
- self.iface = iface
- self._contact_dlg = None
- self.schema_lib = None
- self.user_conf = {}
-
- self.createWidgets()
- def createWidgets(self):
- """ set up the interface """
- self.ui = Ui_Main()
- self.ui.setupUi(self)
-
- self.user_conf = mncheck.get_user_data()
-
- self.setWindowTitle(f"MnCheck v{VERSION}")
- self.setWindowIcon(QIcon(MAIN / "icon.png"))
- self.ui.lbl_mn_logo.setPixmap(QPixmap(RSCDIR / "mn_logo_mini.png"))
-
- self.ui.btn_run.setIcon(QIcon(RSCDIR / "play.png"))
- self.ui.btn_run.clicked.connect(self.run)
- self.ui.btn_contact.clicked.connect(self.show_contact)
- for i, schema_name in enumerate(self.available_schemas):
- s = mncheck.get_schema(schema_name)
- try:
- self.ui.cbb_schemas.addItem(s.SCHEMA_NAME, i)
- except AttributeError:
- self.ui.cbb_schemas.addItem(schema_name, i)
-
- if 'current_schema' in self.user_conf and self.user_conf['current_schema'] == schema_name:
- self.ui.cbb_schemas.setCurrentIndex(i)
-
- self.ui.cbb_schemas.currentIndexChanged.connect(self.update_layers_list)
-
- self.ui.progress_bar.setVisible(False)
-
- self.ui.tree_report.setColumnWidth(0, 35)
- self.ui.tree_report.itemClicked.connect(self.tree_item_clicked)
- self.ui.tree_report.expanded.connect(self.tree_item_expanded)
-
- QgsProject.instance().layersAdded.connect(self.update_layers_list)
- QgsProject.instance().layersRemoved.connect(self.update_layers_list)
-
- self.update_layers_list()
-
- def tree_item_expanded(self, _):
- self.tree_auto_resize()
- def tree_auto_resize(self):
- self.ui.tree_report.resizeColumnToContents(1)
- self.ui.tree_report.resizeColumnToContents(2)
- self.ui.tree_report.setColumnWidth(1, self.ui.tree_report.columnWidth(1) + 20)
- self.ui.tree_report.setColumnWidth(2, self.ui.tree_report.columnWidth(2) + 20)
-
- def current_schema_name(self):
- return self.available_schemas[int(self.ui.cbb_schemas.itemData(self.ui.cbb_schemas.currentIndex()))]
-
- def init_progress_bar(self, value=0, minimum=0, maximum=100):
- self.ui.progress_bar.setMinimum(minimum)
- self.ui.progress_bar.setValue(value)
- self.ui.progress_bar.setMaximum(maximum)
-
- def test_started(self, test):
- logger.debug("* %s - start test", test.name)
-
- def test_ended(self, test):
- logger.debug("* %s - %s", test.name, test.status_str)
- if test.status == checking.ERROR:
- try:
- logger.debug("%s", "\n".join([e.info['exc_info'] for e in test.errors]))
- except KeyError:
- pass
- self.ui.progress_bar.setValue(self.ui.progress_bar.value() + 1)
- self.ui.progress_bar.update()
-
- def update_layers_list(self):
-
- schema_name = self.current_schema_name()
- logger.info("Selected schema: %s", schema_name)
-
- schema = mncheck.get_schema(schema_name)
-
- logger.info("Expected layers: %s", str([model.layername for model in schema.models]))
- found = [layer.name().lower() for layer in QgsProject.instance().mapLayers().values()]
- logger.info("Found layers: %s", str(found))
- self.ui.btn_run.setEnabled(True)
- self.ui.tree_report.clear()
- for model in schema.models:
-
- item = QTreeWidgetItem()
-
- if model.layername.lower() in found:
- item.setIcon(0, QIcon(QPixmap(RSCDIR / "ok_16.png")))
- item.setText(1, model.layername)
- else:
- item.setText(1, f"{model.layername}: La couche est introuvable")
- if model.required:
- item.setIcon(0, QIcon(QPixmap(RSCDIR / "error_16.png")))
- self.ui.btn_run.setEnabled(False)
- else:
- item.setIcon(0, QIcon(QPixmap(RSCDIR / "warning_16.png")))
-
- self.ui.tree_report.addTopLevelItem(item)
- self.tree_auto_resize()
- def run(self):
-
- QApplication.setOverrideCursor(Qt.WaitCursor)
- self.ui.tree_report.clear()
-
- try:
- schema_name = self.current_schema_name()
-
- schema = mncheck.get_schema(schema_name)
- if not schema:
- logger.error("Aucun schéma sélectionné - Opération annulée")
- return
-
- if not schema.checkers:
- logger.error("Aucun testeur trouvé dans le schéma")
- return
-
- for checker_cls in schema.checkers:
- logger.info(f"Execution du checker {checker_cls.__name__}")
- self._run(checker_cls)
- except:
- raise
- finally:
- self.tree_auto_resize()
- self.ui.progress_bar.setVisible(False)
- QApplication.restoreOverrideCursor()
-
- def _run(self, checker_cls):
-
- checker = checker_cls()
-
- checker.comlink = QComlink()
- checker.comlink.started_test.connect(self.test_started)
- checker.comlink.ended_test.connect(self.test_ended)
-
- self.ui.progress_bar.setVisible(True)
- self.init_progress_bar(maximum=len(checker.tests))
-
- results = checker.run()
-
- for result in results:
- topitem = QTreeWidgetItem()
-
- if result.status == checking.SUCCESS:
- topitem.setIcon(0, QIcon(QPixmap(RSCDIR / "ok_16.png")))
- topitem.setText(1, f"{result.title}")
-
- elif result.status == checking.FAILURE:
- topitem.setIcon(0, QIcon(QPixmap(RSCDIR / "error_16.png")))
- topitem.setText(1, f"{result.title} ({len(result.errors)})")
-
- elif result.status == checking.ERROR:
- topitem.setIcon(0, QIcon(QPixmap(RSCDIR / "warning_16.png")))
- topitem.setText(1, f"{result.title} [Erreur]")
-
- else:
- topitem.setText(1, f"{result.title} [Erreur: aucun résultat]")
-
- topitem.setToolTip(0, f"{result.status_str}")
- topitem.setToolTip(1, f"{result.description}\n[test: {result.name}]")
-
- self.ui.tree_report.addTopLevelItem(topitem)
-
- for err in result.errors:
- erritem = QTreeWidgetItem()
-
- msg = err.message
-
- erritem.setText(1, msg)
-
- if "exc_info" in err.info:
- erritem.setData(1, Qt.UserRole, err)
-
- elif "model" in err.info:
- data = err.info["model"]
- erritem.setText(2, f"{data.layername}".upper())
- erritem.setData(1, Qt.UserRole, data)
-
- elif "item" in err.info:
- data = err.info["item"]
- erritem.setText(2, f"{data}")
- erritem.setData(1, Qt.UserRole, data)
-
- font = erritem.font(2)
- font.setItalic(True)
- erritem.setFont(2, font)
-
- topitem.addChild(erritem)
-
-
- def tree_item_clicked(self, item, _):
-
- data = item.data(1, Qt.UserRole)
-
- if not data:
- return
-
- elif hasattr(data, "_feature"):
- self.zoom_to_feature(data.layer, data._feature)
-
- elif hasattr(data, "layer"):
- self.select_layer(data.layer)
-
- def select_layer(self, layer):
- self.iface.setActiveLayer(layer)
-
- def zoom_to_feature(self, layer, feature):
- self.iface.setActiveLayer(layer)
- self.iface.mapCanvas().zoomToFeatureExtent(feature.geometry().boundingBox())
- layer.removeSelection()
- layer.select(feature.id())
-
- def show_contact(self):
- try:
- self._contact_dlg.close()
- except:
- pass
- self._contact_dlg = DlgContact()
- self._contact_dlg.show()
- self._contact_dlg.exec_()
-
- def store_config(self):
- user_conf = mncheck.get_user_data()
-
- user_conf["current_schema"] = self.current_schema_name()
-
- mncheck.dump_user_data(user_conf)
-
- def closeEvent(self, event):
- self.store_config()
-
- super().closeEvent(event)
-
|