def tearDownClass(cls): """Run after all tests""" TestQgsPalLabeling.tearDownClass() cls.removeMapLayer(cls.layer) cls.layer = None # avoid crash on finish, probably related to https://bugreports.qt.io/browse/QTBUG-35760 QThreadPool.globalInstance().waitForDone()
def __init__(self, iface, startX, startY, endX, endY, parent=None): """Constructor.""" super(OSMDownloaderDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface self.setCoordinates(startX, startY, endX, endY) self.threadpool = QThreadPool() self.size = 0
def tearDown(self): # avoid crash on finish, probably related to https://bugreports.qt.io/browse/QTBUG-35760 QThreadPool.globalInstance().waitForDone()
def tearDownClass(cls): TestQgsPalLabeling.tearDownClass() # avoid crash on finish, probably related to https://bugreports.qt.io/browse/QTBUG-35760 QThreadPool.globalInstance().waitForDone()
def tearDownClass(cls): TestQgsPalLabeling.tearDownClass() cls.removeMapLayer(cls.layer) cls.layer = None # avoid crash on finish, probably related to https://bugreports.qt.io/browse/QTBUG-35760 QThreadPool.globalInstance().waitForDone()
def __init__(self, network): super().__init__() self.pool = QThreadPool() # .globalInstance() will crash afterward self._config(network)
class UploadOverview(uicls_log, basecls_log): """Upload status overview dialog.""" MAX_SCHEMATISATION_MODELS = 3 def __init__(self, plugin_dock, parent=None): super().__init__(parent) self.setupUi(self) self.plugin_dock = plugin_dock self.threedi_api = self.plugin_dock.threedi_api self.tc = ThreediCalls(self.plugin_dock.threedi_api) self.communication = self.plugin_dock.communication self.feedback_logger = ListViewLogger(self.lv_upload_feedback) self.upload_thread_pool = QThreadPool() self.ended_tasks = OrderedDict() self.upload_progresses = defaultdict(lambda: ("NO TASK", 0.0, 0.0)) self.current_upload_row = 0 self.schematisation = None self.schematisation_sqlite = None self.schematisation_id = None self.pb_new_upload.clicked.connect(self.upload_new_model) self.pb_hide.clicked.connect(self.close) self.tv_model = None self.setup_view_model() self.adjustSize() @property def current_local_schematisation(self): """Return currently loaded local schematisation.""" return self.plugin_dock.current_local_schematisation def setup_view_model(self): """Setting up model and columns for TreeView.""" nr_of_columns = 4 self.tv_model = QStandardItemModel(0, nr_of_columns - 1) self.tv_model.setHorizontalHeaderLabels(["Schematisation name", "Revision", "Commit message", "Status"]) self.tv_uploads.setModel(self.tv_model) self.tv_uploads.selectionModel().selectionChanged.connect(self.on_upload_context_change) for i in range(nr_of_columns): self.tv_uploads.resizeColumnToContents(i) self.progress_widget.hide() self.label_success.hide() self.label_failure.hide() def on_upload_context_change(self): """Updating progress bars based on upload selection change.""" selected_indexes = self.tv_uploads.selectedIndexes() if selected_indexes: current_index = selected_indexes[0] current_row = current_index.row() self.current_upload_row = current_row + 1 self.on_update_upload_progress(self.current_upload_row, *self.upload_progresses[self.current_upload_row]) self.feedback_logger.clear() try: for msg, success in self.ended_tasks[self.current_upload_row]: if success: self.feedback_logger.log_info(msg) else: self.feedback_logger.log_error(msg) except KeyError: pass status_item = self.tv_model.item(current_row, 3) status = status_item.text() if status == UploadStatus.SUCCESS.value: self.progress_widget.hide() self.label_success.show() self.label_failure.hide() elif status == UploadStatus.FAILURE.value: self.progress_widget.hide() self.label_success.hide() self.label_failure.show() else: self.progress_widget.show() self.label_success.hide() self.label_failure.hide() def add_upload_to_model(self, upload_specification): """Initializing a new upload.""" create_revision = upload_specification["create_revision"] schematisation = upload_specification["schematisation"] schema_name_item = QStandardItem(f"{schematisation.name}") revision = upload_specification["latest_revision"] revision_number = revision.number + 1 if create_revision is True else revision.number revision_item = QStandardItem(f"{revision_number}") commit_msg_item = QStandardItem(f"{upload_specification['commit_message']}") status_item = QStandardItem(UploadStatus.IN_PROGRESS.value) self.tv_model.appendRow([schema_name_item, revision_item, commit_msg_item, status_item]) upload_row_number = self.tv_model.rowCount() upload_row_idx = self.tv_model.index(upload_row_number - 1, 0) self.tv_uploads.selectionModel().setCurrentIndex(upload_row_idx, QItemSelectionModel.ClearAndSelect) worker = UploadProgressWorker( self.threedi_api, self.current_local_schematisation, upload_specification, upload_row_number ) worker.signals.upload_progress.connect(self.on_update_upload_progress) worker.signals.thread_finished.connect(self.on_upload_finished_success) worker.signals.upload_failed.connect(self.on_upload_failed) worker.signals.revision_committed.connect(self.on_revision_committed) self.upload_thread_pool.start(worker) def upload_new_model(self): """Initializing new upload wizard.""" if not self.current_local_schematisation or not self.current_local_schematisation.sqlite: warn_msg = "Please load the schematisation first before starting the upload." self.communication.show_warn(warn_msg, parent=self) self.plugin_dock.build_options.load_local_schematisation() return self.schematisation_sqlite = self.current_local_schematisation.sqlite schema_sqlite_loaded = is_toolbox_spatialite_loaded(self.schematisation_sqlite) if schema_sqlite_loaded is False: title = "Warning" question = ( "Warning: the Spatialite that you loaded with the 3Di Toolbox is not in the revision you are " "about to upload. Do you want to continue?" ) on_continue_answer = self.communication.ask(self, title, question, QMessageBox.Warning) if on_continue_answer is not True: return self.schematisation_id = self.current_local_schematisation.id self.schematisation = self.tc.fetch_schematisation(self.schematisation_id) current_wip_revision = self.current_local_schematisation.wip_revision latest_revision = ( self.tc.fetch_schematisation_latest_revision(self.schematisation_id) if current_wip_revision.number > 0 else None ) latest_revision_number = latest_revision.number if latest_revision else 0 if latest_revision_number != current_wip_revision.number: question = f"WIP revision number different than latest online revision ({latest_revision_number})" answer = self.communication.custom_ask(self, "Pick action", question, "Upload anyway?", "Cancel") if answer == "Cancel": return upload_wizard_dialog = UploadWizard(self.plugin_dock, self) upload_wizard_dialog.exec_() new_upload = upload_wizard_dialog.new_upload if not new_upload: return if not new_upload["upload_only"]: deletion_dlg = ModelDeletionDialog(self.plugin_dock, self) if len(deletion_dlg.threedi_models) >= self.MAX_SCHEMATISATION_MODELS: deletion_dlg.exec_() if len(deletion_dlg.threedi_models) >= self.MAX_SCHEMATISATION_MODELS: self.communication.bar_warn("Uploading canceled...") return self.add_upload_to_model(new_upload) def on_revision_committed(self): """Handling actions on successful revision commit.""" self.plugin_dock.update_schematisation_view() def on_update_upload_progress(self, upload_row_number, task_name, task_progress, total_progress): """Handling actions on upload progress update.""" self.upload_progresses[upload_row_number] = (task_name, task_progress, total_progress) if self.current_upload_row == upload_row_number: self.lbl_current_task.setText(task_name) self.pbar_current_task.setValue(task_progress) self.pbar_total_upload.setValue(total_progress) if task_progress == 100.0 and task_name != "DONE": success = True enriched_success_message = f"{task_name} ==> done" ended_task_row = (enriched_success_message, success) if upload_row_number not in self.ended_tasks: self.ended_tasks[upload_row_number] = [ended_task_row] else: upload_ended_tasks = self.ended_tasks[upload_row_number] if ended_task_row not in upload_ended_tasks: upload_ended_tasks.append(ended_task_row) else: return self.feedback_logger.log_info(enriched_success_message) def on_upload_finished_success(self, upload_row_number, msg): """Handling action on upload success.""" item = self.tv_model.item(upload_row_number - 1, 3) item.setText(UploadStatus.SUCCESS.value) self.plugin_dock.communication.bar_info(msg, log_text_color=Qt.darkGreen) self.on_upload_context_change() def on_upload_failed(self, upload_row_number, error_message): """Handling action on upload failure.""" item = self.tv_model.item(upload_row_number - 1, 3) item.setText(UploadStatus.FAILURE.value) self.plugin_dock.communication.bar_error(error_message, log_text_color=Qt.red) success = False failed_task_name = self.upload_progresses[self.current_upload_row][0] enriched_error_message = f"{failed_task_name} ==> failed\n{error_message}" failed_task_row = (enriched_error_message, success) if upload_row_number not in self.ended_tasks: self.ended_tasks[upload_row_number] = [failed_task_row] else: self.ended_tasks[upload_row_number].append(failed_task_row) self.feedback_logger.log_error(enriched_error_message) self.on_upload_context_change()
def __init__(self, network, n_parallel=1): super(ReloadLayerController, self).__init__() self.pool = QThreadPool() # .globalInstance() will crash afterward self.n_parallel = 1 self.status = self.LOADING self._config(network)
def __init__(self, network, n_parallel=1): super(UploadLayerController, self).__init__() self.n_parallel = n_parallel self.pool = QThreadPool() # .globalInstance() will crash afterward self._config(network) self.feat_cnt = 0
def __init__(self, *a): super(InitUploadLayerController, self).__init__() self.pool = QThreadPool() # .globalInstance() will crash afterward self._config()
def setUp(self): super().setUp() self.pool = QThreadPool() # .globalInstance() will crash afterward
class OSMDownloaderDialog(QDialog, FORM_CLASS): def __init__(self, iface, startX, startY, endX, endY, parent=None): """Constructor.""" super(OSMDownloaderDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface self.setCoordinates(startX, startY, endX, endY) self.threadpool = QThreadPool() self.size = 0 def setCoordinates(self, startX, startY, endX, endY): if startX < endX: minLong = startX maxLong = endX else: minLong = endX maxLong = startX if startY < endY: minLat = startY maxLat = endY else: minLat = endY maxLat = startY self.wEdit.setText(str(minLong)) self.sEdit.setText(str(minLat)) self.eEdit.setText(str(maxLong)) self.nEdit.setText(str(maxLat)) @pyqtSlot() def on_saveButton_clicked(self): ret = QFileDialog.getSaveFileName(parent=None, caption='Define file name and location', filter='OSM Files(*.osm)') fileName = ret[0] split = fileName.split('.') if len(split)>0 and split[-1] == 'osm': pass else: fileName += '.osm' self.filenameEdit.setText(fileName) @pyqtSlot() def on_button_box_accepted(self): if self.filenameEdit.text() == '': QMessageBox.warning(self, self.tr("Warning!"), self.tr("Please, select a location to save the file.")) return # Initiating processing osmRequest = OSMRequest(self.filenameEdit.text()) osmRequest.setParameters(self.wEdit.text(), self.sEdit.text(), self.eEdit.text(), self.nEdit.text()) # Connecting end signal osmRequest.signals.processFinished.connect(self.processFinished) osmRequest.signals.sizeReported.connect(self.reportSize) osmRequest.signals.proxyOpened.connect(self.proxy) osmRequest.signals.errorOccurred.connect(self.errorOccurred) osmRequest.signals.userCanceled.connect(self.userCanceled) # Setting the progress bar self.progressMessageBar = self.iface.messageBar().createMessage('Downloading data...') self.progressBar = QProgressBar() self.progressBar.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progressBar) self.iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) self.progressBar.setRange(0, 0) self.progressMessageBar.destroyed.connect(osmRequest.signals.cancel) # Starting process self.threadpool.start(osmRequest) @pyqtSlot(str) def proxy(self, proxy): self.progressMessageBar.setText('Proxy set to: '+proxy) @pyqtSlot(str) def errorOccurred(self, message): QMessageBox.warning(self, 'Fatal!', message) self.close() @pyqtSlot() def userCanceled(self): QMessageBox.warning(self, 'Info!', 'Process canceled by user!') self.close() @pyqtSlot(float) def reportSize(self, size): self.size = size self.progressMessageBar.setText('Downloading: '+"{0:.2f}".format(size)+' megabytes from OSM servers...') @pyqtSlot(str) def processFinished(self, message): self.progressBar.setRange(0, 100) self.progressBar.setValue(100) self.progressMessageBar.setText('Downloaded '+"{0:.2f}".format(self.size)+' megabytes in total from OSM servers') QMessageBox.warning(self, 'Info!', message) if self.checkBox.isChecked(): self.iface.addVectorLayer(self.filenameEdit.text(), 'osm_data', 'ogr') self.close()
class OSMDownloaderDialog(QDialog, FORM_CLASS): def __init__(self, iface, startX, startY, endX, endY, parent=None): """Constructor.""" super(OSMDownloaderDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface self.setCoordinates(startX, startY, endX, endY) self.threadpool = QThreadPool() self.size = 0 def setCoordinates(self, startX, startY, endX, endY): if startX < endX: minLong = startX maxLong = endX else: minLong = endX maxLong = startX if startY < endY: minLat = startY maxLat = endY else: minLat = endY maxLat = startY self.wEdit.setText(str(minLong)) self.sEdit.setText(str(minLat)) self.eEdit.setText(str(maxLong)) self.nEdit.setText(str(maxLat)) @pyqtSlot() def on_saveButton_clicked(self): ret = QFileDialog.getSaveFileName( parent=None, caption='Define file name and location', filter='OSM Files(*.osm)') fileName = ret[0] split = fileName.split('.') if len(split) > 0 and split[-1] == 'osm': pass else: fileName += '.osm' self.filenameEdit.setText(fileName) @pyqtSlot() def on_button_box_accepted(self): if self.filenameEdit.text() == '': QMessageBox.warning( self, self.tr("Warning!"), self.tr("Please, select a location to save the file.")) return # Initiating processing osmRequest = OSMRequest(self.filenameEdit.text()) osmRequest.setParameters(self.wEdit.text(), self.sEdit.text(), self.eEdit.text(), self.nEdit.text()) # Connecting end signal osmRequest.signals.processFinished.connect(self.processFinished) osmRequest.signals.sizeReported.connect(self.reportSize) osmRequest.signals.proxyOpened.connect(self.proxy) osmRequest.signals.errorOccurred.connect(self.errorOccurred) osmRequest.signals.userCanceled.connect(self.userCanceled) # Setting the progress bar self.progressMessageBar = self.iface.messageBar().createMessage( 'Downloading data...') self.progressBar = QProgressBar() self.progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progressBar) self.iface.messageBar().pushWidget(self.progressMessageBar, Qgis.Info) self.progressBar.setRange(0, 0) self.progressMessageBar.destroyed.connect(osmRequest.signals.cancel) # Starting process self.threadpool.start(osmRequest) @pyqtSlot(str) def proxy(self, proxy): self.progressMessageBar.setText('Proxy set to: ' + proxy) @pyqtSlot(str) def errorOccurred(self, message): QMessageBox.warning(self, 'Fatal!', message) self.close() @pyqtSlot() def userCanceled(self): QMessageBox.warning(self, 'Info!', 'Process canceled by user!') self.close() @pyqtSlot(float) def reportSize(self, size): self.size = size self.progressMessageBar.setText('Downloading: ' + "{0:.2f}".format(size) + ' megabytes from OSM servers...') @pyqtSlot(str) def processFinished(self, message): self.progressBar.setRange(0, 100) self.progressBar.setValue(100) self.progressMessageBar.setText('Downloaded ' + "{0:.2f}".format(self.size) + ' megabytes in total from OSM servers') QMessageBox.warning(self, 'Info!', message) if self.checkBox.isChecked(): self.iface.addVectorLayer(self.filenameEdit.text(), 'osm_data', 'ogr') self.close()