def _launchImport(self): ''' Launch the import ''' if not self._validateMapping(): return qgis_layer = self.qgislayers[self.cbbLayers.currentIndex()] self.close() # Progress bar + message progressMessageBar = PagLuxembourg.main.qgis_interface.messageBar().createMessage(QCoreApplication.translate('ImportShpDialog','Importing {}').format(self.shplayer.source())) progress = QProgressBar() progress.setMaximum(self.shplayer.featureCount()) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) PagLuxembourg.main.qgis_interface.messageBar().pushWidget(progressMessageBar, QgsMessageBar.INFO) # Start import session self._startImportSession() # Import the layer, and get the imported extent self._importLayer( self.shplayer, qgis_layer, self.mapping.asIndexFieldMappings(qgis_layer.dataProvider().fields(), self.shpfields), progress ) # Commit import session self._commitImport()
class progressBar: def __init__(self, parent, msg='', steps=0): ''' progressBar class instatiation method. It creates a QgsMessageBar with provided msg and a working QProgressBar :param parent: :param msg: string ''' self.iface = parent.iface widget = self.iface.messageBar().createMessage("fdtm plugin:", msg) self.progressBar = QProgressBar() self.progressBar.setRange(0, steps) #(1,steps) self.progressBar.setValue(0) self.progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) widget.layout().addWidget(self.progressBar) qApp.processEvents() self.iface.messageBar().pushWidget(widget, QgsMessageBar.INFO, 50) qApp.processEvents() def setStep(self, step): self.progressBar.setValue(step) qApp.processEvents() def stop(self, msg=''): ''' the progressbar is stopped with a succes message :param msg: string :return: ''' self.iface.messageBar().clearWidgets() message = self.iface.messageBar().createMessage("fdtm plugin:", msg) self.iface.messageBar().pushWidget(message, QgsMessageBar.SUCCESS, 3)
def startWorker(self): # create a new worker instance if self.worker is None: worker = UpdateRegistryWorker() # configure the QgsMessageBar messageBar = self.iface.messageBar().createMessage(u"Update Image Registry", u"Dieser Vorgang kann einige Minute dauern, bitte haben Sie geduld!") progressBar = QProgressBar() progressBar.setMinimum(0) progressBar.setMaximum(0) progressBar.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) cancelButton = QPushButton() cancelButton.setText('Cancel') cancelButton.clicked.connect(self.killWorker) messageBar.layout().addWidget(progressBar) self.progressBar = progressBar messageBar.layout().addWidget(cancelButton) self.iface.messageBar().pushWidget(messageBar, self.iface.messageBar().INFO) #self.iface.messageBar().widgetRemoved # messageBar self.messageBar = messageBar # start the worker in a new thread thread = QThread() worker.moveToThread(thread) worker.finished.connect(self.workerFinished) worker.error.connect(self.workerError) #worker.progress.connect(progressBar.setValue) thread.started.connect(worker.run) thread.start() self.thread = thread self.worker = worker
def start_worker_files(self, checked, src, dst, selected_images, local_config): # create a new worker instance worker = WorkerFiles(checked, src, dst, selected_images, local_config) # configure the QgsMessageBar messageBar = self.iface.messageBar().createMessage( 'List and copy files...', ) progressBarList = QProgressBar() progressBarCopy = QProgressBar() progressBarList.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressBarCopy.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) cancelButton = QPushButton() cancelButton.setText('Cancel') cancelButton.clicked.connect(worker.kill) messageBar.layout().addWidget(progressBarList) messageBar.layout().addWidget(progressBarCopy) messageBar.layout().addWidget(cancelButton) self.iface.messageBar().pushWidget(messageBar, self.iface.messageBar().INFO) self.messageBarFiles = messageBar # start the worker in a new thread thread = QThread() worker.moveToThread(thread) worker.finished.connect(self.finished_worker_files) worker.error.connect(self.workerError) worker.progressList.connect(progressBarList.setValue) worker.progressCopy.connect(progressBarCopy.setValue) thread.started.connect(worker.run) thread.start() self.thread_files = thread self.worker_files = worker
def start_worker(worker, iface, message, with_progress=True): # configure the QgsMessageBar message_bar_item = iface.messageBar().createMessage(message) progress_bar = QProgressBar() progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) if not with_progress: progress_bar.setMinimum(0) progress_bar.setMaximum(0) cancel_button = QPushButton() cancel_button.setText('Cancel') cancel_button.clicked.connect(worker.kill) message_bar_item.layout().addWidget(progress_bar) message_bar_item.layout().addWidget(cancel_button) iface.messageBar().pushWidget(message_bar_item, iface.messageBar().INFO) # start the worker in a new thread # let Qt take ownership of the QThread thread = QThread(iface.mainWindow()) worker.moveToThread(thread) worker.set_message.connect( lambda message: set_worker_message(message, message_bar_item)) worker.toggle_show_progress.connect( lambda show: toggle_worker_progress(show, progress_bar)) worker.toggle_show_cancel.connect( lambda show: toggle_worker_cancel(show, cancel_button)) worker.finished.connect(lambda result: worker_finished( result, thread, worker, iface, message_bar_item)) worker.error.connect(lambda e: worker_error(e)) worker.progress.connect(progress_bar.setValue) thread.started.connect(worker.run) thread.start() return thread, message_bar_item
def addLoadingMsg(self, countLayers, barText='Downloading datasets'): barText = self.tr(barText) progressMessageBar = self.iface.messageBar().createMessage(barText, '0/' + str(countLayers)) progress = QProgressBar() progress.setMaximum(countLayers) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) return progressMessageBar, progress
def addLoadingMsg(self, countLayers, barText='Downloading datasets'): barText = self.tr(barText) progressMessageBar = self.iface.messageBar().createMessage( barText, '0/' + str(countLayers)) progress = QProgressBar() progress.setMaximum(countLayers) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) return progressMessageBar, progress
class BusyBar(QThread): """ Adapted from: http://stackoverflow.com/questions/8007602/ looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e Looping progress bar create the signal that the thread will emit .. note:: This function creates a busy bar but I have not figured out how to \ attach it to a process. Therefore, it is currently functionally \ useless. """ changeValue = pyqtSignal(int) def __init__(self, text=""): QThread.__init__(self, parent=None) self.text = text self.stop = False self.proBar = QProgressBar() self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen) self.proBar.setRange(0, 100) self.proBar.setTextVisible(True) self.proBar.setFormat(self.text) self.proBar.setValue(0) self.proBar.setFixedSize(300, 40) self.proBar.setAlignment(Qt.AlignCenter) self.proBar.show() #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection) # Make the Busybar delete itself and the QProgressBar when done self.finished.connect(self.onFinished) def run(self): """ """ while not self.stop: # keep looping while self is visible # Loop sending mail for i in range(100): # emit the signal instead of calling setValue # also we can't read the progress bar value from the thread self.changeValue.emit(i) time.sleep(0.01) self.changeValue.emit(0) def onFinished(self): """ """ self.proBar.deleteLater() self.deleteLater() def Kill(self): """ """ self.stop = True
def executar(self): progressMessageBar = self.iface.messageBar().createMessage( u'ECO Downloader', u' Baixando Dados... Isso poderá levar alguns minutos.') progress = QProgressBar() progress.setMaximum(len(self.estacoes)) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) opcao = self.opcao if opcao == 1: post_data = {'cboTipoReg': '10'} # para chuvas elif opcao == 2: post_data = {'cboTipoReg': '8'} # para cotas elif opcao == 3: post_data = {'cboTipoReg': '9'} # para vazões elif opcao == 4: post_data = {'cboTipoReg': '12'} # qualidade da água elif opcao == 5: post_data = {'cboTipoReg': '13'} # resumo de descarga elif opcao == 6: post_data = {'cboTipoReg': '16'} # perfil transversal contagem = 0 for idx, est in enumerate(self.estacoes): time.sleep(1) progress.setValue(idx + 1) try: print '** %s ** - Procurando dados...' % (est, ) r = requests.post(self.montar_url_estacao(est), data=post_data) link = self.obter_link_arquivo(r) self.salvar_arquivo_texto(est, link) print u'** %s ** (Concluído)' % (est, ) contagem += 1 except: print u'** %s ** - ERRO: Estacão não possui dados ou verifique sua conexão e tente novamente.\n' % ( est, ) contagem = str(contagem) nEstacoes = str(len(self.estacoes)) self.iface.messageBar().clearWidgets() self.iface.messageBar().pushInfo( u'ECO Downloader', contagem + u' das ' + nEstacoes + u' estações selecionadas foram baixadas com sucesso.')
def launch(self): progressMessageBar = self.iface.messageBar().createMessage("Obteniendo informacion del catastro... ") progress = QProgressBar() progress.setMaximum(0) progress.setMinimum(0) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) self.parcelaService.procDone.connect(self.callback) self.parcelaService.start()
def export_features(self): """ Exportiert die Datenbanklayer als ESRI-Shapefile :return: """ directory = QFileDialog.getExistingDirectory() if not directory: return # Abfrage, ob Daten überschrieben werden sollen, wenn Verzeichnis nicht leer override = True if os.listdir(directory): reply = self.raise_message("dir_not_empty") if reply == QMessageBox.Yes: pass else: override = False # Verzeichnis leer oder override = True if override: # progress bar QgsMessageLog.logMessage("Exportiere nach " + directory, "KKG Plugin", QgsMessageLog.INFO) layers = QgsMapLayerRegistry.instance().mapLayers().values() progress_message_bar = self.iface.messageBar().createMessage("Exportiere...") progress = QProgressBar() progress.setMaximum(len(layers)) progress.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) progress_message_bar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progress_message_bar, self.iface.messageBar().INFO) # current extent extent = self.iface.mapCanvas().extent() for i in range(0, len(layers)): layer = layers[i] file_path = directory + "\\" + layer.name() errors = QgsVectorFileWriter.writeAsVectorFormat(layer, file_path, "UTF-8", None, "ESRI Shapefile", filterExtent=extent, symbologyExport=QgsVectorFileWriter.NoSymbology) if errors: QgsMessageLog.logMessage(layer.name() + " konnte nicht geschrieben werden.", "KKG Plugin", QgsMessageLog.WARNING) else: QgsMessageLog.logMessage(layer.name() + " erfolgreich geschrieben", "KKG Plugin", QgsMessageLog.INFO) progress.setValue(i + 1) self.iface.messageBar().clearWidgets() QgsMessageLog.logMessage("Export abgeschlossen", "KKG Plugin", QgsMessageLog.INFO) self._create_project_from_export(directory)
class BusyBar(QThread): """ Adapted from: http://stackoverflow.com/questions/8007602/ looping-qprogressbar-gives-error-qobjectinstalleventfilter-cannot-filter-e Looping progress bar create the signal that the thread will emit .. note:: This function creates a busy bar but I have not figured out how to \ attach it to a process. Therefore, it is currently functionally \ useless. """ changeValue = pyqtSignal(int) def __init__(self, text = "" ): QThread.__init__(self, parent = None) self.text = text self.stop = False self.proBar = QProgressBar() self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen ) self.proBar.setRange( 0, 100 ) self.proBar.setTextVisible( True ) self.proBar.setFormat( self.text ) self.proBar.setValue( 0 ) self.proBar.setFixedSize( 300 , 40 ) self.proBar.setAlignment(Qt.AlignCenter) self.proBar.show() #self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection) # Make the Busybar delete itself and the QProgressBar when done self.finished.connect(self.onFinished) def run(self): """ """ while not self.stop: # keep looping while self is visible # Loop sending mail for i in range(100): # emit the signal instead of calling setValue # also we can't read the progress bar value from the thread self.changeValue.emit( i ) time.sleep(0.01) self.changeValue.emit( 0 ) def onFinished(self): """ """ self.proBar.deleteLater() self.deleteLater() def Kill(self): """ """ self.stop = True
def ProgresBar(self): progressMessageBar = iface.messageBar().createMessage( "Doing something boring...") progress = QProgressBar() progress.setMaximum(10) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, iface.messageBar().INFO) for i in range(10): time.sleep(0.2) progress.setValue(i + 1) iface.messageBar().clearWidgets()
def _launchImport(self): ''' Launch the import ''' if not self._validateMapping(): return self.close() # Progress bar + message progressMessageBar = PagLuxembourg.main.qgis_interface.messageBar().createMessage(QCoreApplication.translate('ImportDxfDialog','Importing DXF')) progress = QProgressBar() progress.setMaximum(self._getEnabledLayerMappingCount()) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) progress2 = QProgressBar() progress2.setMaximum(self.dxflayer_points.featureCount() + self.dxflayer_linestrings.featureCount() + self.dxflayer_polygons.featureCount()) progress2.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress2) PagLuxembourg.main.qgis_interface.messageBar().pushWidget(progressMessageBar, QgsMessageBar.INFO) # Start import session self._startImportSession() for layer_mapping in self.mapping.layerMappings(): # Skip if not enabled if not layer_mapping.isEnabled(): continue # Progression message progressMessageBar.setText(QCoreApplication.translate('ImportDxfDialog','Importing {}').format(layer_mapping.sourceLayerName())) # QGIS layer qgis_layer = self._getQgisLayerFromTableName(layer_mapping.destinationLayerName()) layer_indexmapping = layer_mapping.asIndexFieldMappings(qgis_layer.dataProvider().fields()) progress2.setValue(0) # Import features according to geometry type if qgis_layer.geometryType() == QGis.Point: self._importLayer(self.dxflayer_points, qgis_layer, layer_indexmapping, progress2) elif qgis_layer.geometryType() == QGis.Line: self._importLayer(self.dxflayer_linestrings, qgis_layer, layer_indexmapping, progress2) elif qgis_layer.geometryType() == QGis.Polygon: self._importLayer(self.dxflayer_linestrings, qgis_layer, layer_indexmapping, progress2) self._importLayer(self.dxflayer_polygons, qgis_layer, layer_indexmapping, progress2) # Commit import session self._commitImport()
def createProgressbar(self, loopnumber): """ Create a progress bar when iterating over features """ progressMessageBar = self.messageBar.createMessage( unicode("Chargement des données...", "utf-8")) progress = QProgressBar() progress.setMinimum(0) progress.setMaximum(loopnumber) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.messageBar.pushWidget(progressMessageBar, self.messageBar.INFO) return progress
def _set_progressbar(self): """Set QGIS progress bar and display progress """ progressMessageBar = self.iface.messageBar().createMessage(self.tr("Zpracovávám objekty".decode("utf-8"))) progress = QProgressBar() progress.setMaximum(100) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget( progressMessageBar, self.iface.messageBar().INFO) progress.setValue(2) return progress
def __init__(self, iface, provincia,municipio,x,y,callback): #super(Ui_ProgressDialog, self).__init__(parent) self.thread = ParcelaService(provincia,municipio) self.thread.initCoords(x,y) self.iface = iface progressMessageBar = iface.messageBar().createMessage("Obteniendo informacion del catastro... ") progress = QProgressBar() progress.setMaximum(0) progress.setMinimum(0) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, iface.messageBar().INFO) self.thread.procDone.connect(self.fin) self.thread.start()
def OeQ_push_progressbar(title='Be patient!', message='Background calculations are going on...', timeout=0, maxcount=100): widget = iface.messageBar().createMessage(title, message) # set a new message bar progressbarwidget = QProgressBar() progressbarwidget.setAlignment(Qt.AlignLeft) progressbarwidget.setMaximum(maxcount) progressbarwidget.setValue(0) widget.layout().addWidget(progressbarwidget) # pass the progress bar to the message Bar baritem=iface.messageBar().pushWidget(widget, iface.messageBar().INFO) OeQ_unlockQgis() #print "THIS PRINTLN IS NECESSARY TO TRIGGER THE MESSAGEBAR" return {'widget':progressbarwidget,'baritem':baritem}
def __init__(self, parent, msg = ''): ''' progressBar class instatiation method. It creates a QgsMessageBar with provided msg and a working QProgressBar :param parent: :param msg: string ''' self.iface = parent.iface widget = self.iface.messageBar().createMessage("GooGIS plugin:",msg) progressBar = QProgressBar() progressBar.setRange(0,0) #(1,steps) progressBar.setValue(0) progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) widget.layout().addWidget(progressBar) QtGui.qApp.processEvents() self.iface.messageBar().pushWidget(widget, QgsMessageBar.INFO, 50) QtGui.qApp.processEvents()
class ProgressDialog(QDialog): """ Progress dialog """ def __init__(self, dialogName, parent=None): """ Constructor @param dialogName: @type dialogName: @param parent: @type parent: """ QDialog.__init__(self, parent) self.setWindowIcon(QIcon(":/main.png")) self.name = dialogName self.createDialog() def createDialog(self): """ Create qt dialog """ self.setWindowTitle("%s" % self.name) layout = QVBoxLayout() self.loadingLabel = QLabel("Loading...") self.imageLabel = QLabel() layout2 = QHBoxLayout() layout2.addWidget(self.imageLabel) layout2.addWidget(self.loadingLabel) self.progressBar = QProgressBar(self) self.progressBar.setMaximum(0) self.progressBar.setProperty("value", 0) self.progressBar.setAlignment(Qt.AlignCenter) self.progressBar.setObjectName("progressBar") layout.addLayout(layout2) layout.addWidget(self.progressBar) self.setLayout(layout) flags = Qt.WindowFlags() flags |= Qt.MSWindowsFixedSizeDialogHint self.setWindowFlags(flags)
def processToa(self): """Converts DN to TOA reflectance""" startTime = time.time() if self.dlg.cbOutput.isChecked() and os.path.exists(self.dlg.leOutput.text()): outputPath = self.dlg.leOutput.text() else: outputPath = os.path.dirname(self.dlg.leInput.text().split(',')[0]) if self.dlg.rbRefNorm.isChecked(): bitcode = '32' outname = '_refToa32.tif' elif self.dlg.rbRefMilli.isChecked(): bitcode = '16' outname = '_refToa16.tif' progressMessageBar = self.iface.messageBar().createMessage("DN to TOA conversion...") progress = QProgressBar() progress.setMaximum(100) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progress.setTextVisible(False) label = QLabel() label.setText(' {0}%'.format(0)) progressMessageBar.layout().addWidget(label) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) if self.dlg.comboBox.currentIndex() == 0: bandList = self.dlg.leInput.text().split(',') idBand = {int(os.path.splitext(os.path.basename(i))[0][-1])-1:i for i in bandList} for band in idBand.keys(): self.imgfile = idBand[band] nbBand = band self.history(outputPath, outname) for i in self.meta.dnToToa(self.imgfile, outname=outname, bitcode=bitcode, outpath=outputPath, nbBand=nbBand): progress.setValue(i) label.setText('{0}%'.format(i)) else: self.imgfile = self.dlg.leInput.text().split(',')[0] self.history(outputPath, outname) for i in self.meta.dnToToa(self.imgfile, outname=outname, bitcode=bitcode, outpath=outputPath): progress.setValue(i) label.setText('{0}%'.format(i)) self.iface.messageBar().clearWidgets() self.bar.pushMessage("Image processed !", level=QgsMessageBar.INFO, duration=3) endTime = time.time() self.dlg.teHistory.append('<b>reflectance processing duration:</b><br>{0} seconds<br>'.format(str(endTime - startTime)))
class MessageBarProgress: def __init__(self, algname=None): self.msg = [] self.progressMessageBar = \ iface.messageBar().createMessage(self.tr('Executing algorithm <i>{0}</i>'.format(algname if algname else ''))) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, iface.messageBar().INFO) def error(self, msg): self.msg.append(msg) def setText(self, text): pass def setPercentage(self, i): self.progress.setValue(i) def setInfo(self, _): pass def setCommand(self, _): pass def setDebugInfo(self, _): pass def setConsoleInfo(self, _): pass def close(self): if self.msg: dlg = MessageDialog() dlg.setTitle( QCoreApplication.translate('MessageBarProgress', 'Problem executing algorithm')) dlg.setMessage("<br>".join(self.msg)) dlg.exec_() iface.messageBar().clearWidgets() def tr(self, string, context=''): if context == '': context = 'MessageBarProgress' return QCoreApplication.translate(context, string)
class MessageBarProgress: def __init__(self, algname=None): self.msg = [] self.progressMessageBar = \ iface.messageBar().createMessage(self.tr('Executing algorithm <i>{0}</i>'.format(algname if algname else ''))) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, iface.messageBar().INFO) def error(self, msg): self.msg.append(msg) def setText(self, text): pass def setPercentage(self, i): self.progress.setValue(i) def setInfo(self, _): pass def setCommand(self, _): pass def setDebugInfo(self, _): pass def setConsoleInfo(self, _): pass def close(self): if self.msg: dlg = MessageDialog() dlg.setTitle(QCoreApplication.translate('MessageBarProgress', 'Problem executing algorithm')) dlg.setMessage("<br>".join(self.msg)) dlg.exec_() iface.messageBar().clearWidgets() def tr(self, string, context=''): if context == '': context = 'MessageBarProgress' return QCoreApplication.translate(context, string)
def run(self): """Create the output shapefile.""" gpsStatus = self.checkGpsStatus() if gpsStatus: pass #QMessageBox.warning(None, "Test", "Create GPS SHP") elif gpsStatus == None: QMessageBox.warning(None, "Verzeichnis", u"Es wurde kein Bildverzeichnis für diesen Film gefunden.") return else: QMessageBox.warning(None, "Bilder", u"Die vorhandenen Bilder enthalten keine GPS Information.") return check = QFile(self.shpFile) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shpFile): msg = 'Unable to delete existing shapefile "{}"' self.iface.messageBar().pushMessage(u"Error", u"Die Datei existiert bereits und kann nicht überschrieben werden (Eventuell in QGIS geladen!).", level=QgsMessageBar.CRITICAL, duration=10) return False #fields fields = QgsFields() fields.append(QgsField("bildnr", QVariant.Int)) fields.append(QgsField("lat", QVariant.Double)) fields.append(QgsField("lon", QVariant.Double)) fields.append(QgsField("alt", QVariant.Double)) writer = QgsVectorFileWriter(str(self.shpFile), "UTF-8", fields, QGis.WKBPoint, QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)) mb = self.iface.messageBar().createMessage(u"EXIF", u"Die EXIF Daten (Geo Koordinaten und Höhe) werden aus den Bildern ausgelesen") progress = QProgressBar() progress.setMinimum(0) progress.setMaximum(0) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) mb.layout().addWidget(progress) self.iface.messageBar().pushWidget(mb, QgsMessageBar.INFO) for feature in self.iter_points(): writer.addFeature(feature) del writer self.iface.messageBar().clearWidgets() self.iface.messageBar().pushMessage(u"EXIF", u"Die Shape Datei wurde erfolgreich erstellt und in QGIS geladen!", level=QgsMessageBar.SUCCESS, duration=10) return self.shpFile
def OeQ_push_progressbar(title='Be patient!', message='Background calculations are going on...', timeout=0, maxcount=100): widget = iface.messageBar().createMessage(title, message) # set a new message bar progressbarwidget = QProgressBar() progressbarwidget.setAlignment(Qt.AlignLeft) progressbarwidget.setMaximum(maxcount) progressbarwidget.setValue(0) widget.layout().addWidget(progressbarwidget) # pass the progress bar to the message Bar baritem = iface.messageBar().pushWidget(widget, iface.messageBar().INFO) OeQ_unlockQgis() #print "THIS PRINTLN IS NECESSARY TO TRIGGER THE MESSAGEBAR" return {'widget': progressbarwidget, 'baritem': baritem}
class MessageBarProgress: def __init__(self): self.progressMessageBar = \ iface.messageBar().createMessage(self.tr('Executing algorithm')) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, iface.messageBar().INFO) def error(self, msg): iface.messageBar().clearWidgets() iface.messageBar().pushMessage(self.tr('Error'), msg, level=QgsMessageBar.CRITICAL, duration=3) def setText(self, text): pass def setPercentage(self, i): self.progress.setValue(i) def setInfo(self, _): pass def setCommand(self, _): pass def setDebugInfo(self, _): pass def setConsoleInfo(self, _): pass def close(self): iface.messageBar().clearWidgets() def tr(self, string, context=''): if context == '': context = 'MessageBarProgress' return QCoreApplication.translate(context, string)
def __import_data(self): if self.project is None: return if not QgsProject.instance().readEntry("albion", "conn_info", "")[0]: return dir_ = QFileDialog.getExistingDirectory( None, u"Data directory", QgsProject.instance().readEntry("albion", "last_dir", "")[0], ) if not dir_: return QgsProject.instance().writeEntry("albion", "last_dir", dir_), progressMessageBar = self.__iface.messageBar().createMessage( "Loading {}...".format(dir_)) progress = QProgressBar() progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.__iface.messageBar().pushWidget(progressMessageBar, self.__iface.messageBar().INFO) self.project.import_data(dir_, ProgressBar(progress)) self.project.triangulate() self.project.create_section_view_0_90(4) self.__iface.messageBar().clearWidgets() collar = QgsMapLayerRegistry.instance().mapLayersByName("collar")[0] collar.reload() collar.updateExtents() self.__iface.setActiveLayer(collar) QApplication.instance().processEvents() while self.__iface.mapCanvas().isDrawing(): QApplication.instance().processEvents() self.__iface.zoomToActiveLayer() self.__iface.actionSaveProject().trigger() self.__viewer3d.widget().resetScene(self.project) self.__current_section.clear() self.__current_section.addItems(self.project.sections())
def run(self): import urllib2 stringa1 = "http://smartroadsense.it/open_data.zip" mapCanvas = self.iface.mapCanvas() #-------------------------------- progressMessageBar = self.iface.messageBar().createMessage("SmartRoadSense: Loading remote CSV Open Data. Please, wait...") progress = QProgressBar() progress.setMaximum(10) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) for i in range(10): time.sleep(1) progress.setValue(i + 1) self.iface.messageBar().clearWidgets() #-------------------------------- msg = ("Loading remote csv open data. Please, wait...") self.iface.messageBar().pushMessage("SmartRoadSense: ", msg, QgsMessageBar.INFO, 3) tempDir = unicode(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()) + "/python/plugins/smartroadsense/temp/" stringaUrl = stringa1 try: response = urllib2.urlopen(stringaUrl) print "downloading " + stringaUrl Zippo = response.read() except HTTPError, e: print "HTTP Error:",e.code , url
def start_worker(worker, iface, message, with_progress=True): # configure the QgsMessageBar message_bar = iface.messageBar().createMessage(message) progress_bar = QProgressBar() progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) if not with_progress: progress_bar.setMinimum(0) progress_bar.setMaximum(0) cancel_button = QPushButton() cancel_button.setText('Cancel') cancel_button.clicked.connect(worker.kill) message_bar.layout().addWidget(progress_bar) message_bar.layout().addWidget(cancel_button) iface.messageBar().pushWidget(message_bar, iface.messageBar().INFO) # start the worker in a new thread # let Qt take ownership of the QThread thread = QThread(iface.mainWindow()) worker.moveToThread(thread) worker.set_message.connect(lambda message: set_worker_message( message, message_bar_item)) worker.toggle_show_progress.connect(lambda show: toggle_worker_progress( show, progress_bar)) worker.toggle_show_cancel.connect(lambda show: toggle_worker_cancel( show, cancel_button)) worker.finished.connect(lambda result: worker_finished( result, thread, worker, iface, message_bar)) worker.error.connect(lambda e, exception_str: worker_error( e, exception_str, iface)) worker.progress.connect(progress_bar.setValue) thread.started.connect(worker.run) thread.start() return thread, message_bar
def worker_start(self, dir, url, id): """Start a worker instance on a background thread.""" worker = NaturalEarthRasterWorker(dir, url, id) message_bar = self.iface.messageBar().createMessage('') label = QLabel('Downloading theme {}...'.format(id)) label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progress_bar = QProgressBar() progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progress_bar.setMaximum(100) cancel_button = QPushButton() cancel_button.setText(self.tr('Cancel')) cancel_button.clicked.connect(worker.kill) message_bar.layout().addWidget(label) message_bar.layout().addWidget(progress_bar) message_bar.layout().addWidget(cancel_button) self.iface.messageBar().pushWidget(message_bar, self.iface.messageBar().INFO) self.message_bar = message_bar # start the worker in a new thread thread = QThread() worker.moveToThread(thread) # connect some odds and ends worker.finished.connect(self.worker_finished) worker.error.connect(self.worker_error) worker.progress.connect(progress_bar.setValue) thread.started.connect(worker.run) thread.start() self.thread = thread self.worker = worker
def worker_start(self, layer, field_name, iterations): """Start a worker instance on a background thread.""" worker = CartogramWorker(layer, field_name, iterations) message_bar = self.iface.messageBar().createMessage('') label = QLabel('Creating cartogram...') label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progress_bar = QProgressBar() progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progress_bar.setMaximum(iterations * layer.featureCount()) cancel_button = QPushButton() cancel_button.setText(self.tr('Cancel')) cancel_button.clicked.connect(worker.kill) message_bar.layout().addWidget(label) message_bar.layout().addWidget(progress_bar) message_bar.layout().addWidget(cancel_button) self.iface.messageBar().pushWidget(message_bar, self.iface.messageBar().INFO) self.message_bar = message_bar # start the worker in a new thread thread = QThread() worker.moveToThread(thread) # connect some odds and ends worker.finished.connect(self.worker_finished) worker.error.connect(self.worker_error) worker.progress.connect(progress_bar.setValue) thread.started.connect(worker.run) thread.start() self.thread = thread self.worker = worker
def CRC_Calculation(byteArray): numArray = [0, 2577006594, 2553349383, 27985157, 2607222541, 50138895, 55970314, 2597063176, 2647333657, 72424219, 100277790, 2623544860, 111940628, 2671121430, 2661093651, 117903633, 2425566001, 151597875, 144848438, 2436380212, 200555580, 2456697918, 2479175995, 174012729, 223881256, 2495752234, 2506698031, 217263405, 2520721189, 262481703, 235807266, 2543067680, 2317575009, 330916707, 303195750, 2340972132, 289696876, 2296278126, 2306173291, 284125545, 401111160, 2389866618, 2413395327, 373521789, 2358212469, 353728375, 348025458, 2367976048, 447762512, 2200588370, 2189514071, 454776149, 2178375517, 407723871, 434526810, 2155633240, 2273004361, 518081355, 524963406, 2261798476, 471614532, 2240169030, 2217558339, 498549057, 3208889281, 651805635, 661833414, 3202926276, 606391500, 3183398094, 3155544523, 630180297, 579393752, 3138574554, 3132743135, 589553117, 3119503317, 544593879, 568251090, 3091518160, 802222320, 3058364658, 3085039095, 779875829, 3031957501, 757989375, 747043578, 3038575352, 2988174313, 729934827, 707456750, 3014717164, 696050916, 2967921894, 2974671331, 685236705, 895525024, 2902106274, 2907809191, 885761445, 2919739309, 933081007, 909552298, 2947328680, 2829827001, 825342907, 815447742, 2835398332, 869053620, 2857809078, 2885530035, 845656497, 2784203665, 1013552019, 1036162710, 2757269140, 1049926812, 2802752670, 2795870619, 1061132697, 943229064, 2711783562, 2684980623, 965971341, 2740946821, 986023815, 997098114, 2733933184, 3582100097, 1276674691, 1303611270, 3559491460, 1323666828, 3615460750, 3604252811, 1330546825, 1212783000, 3520305562, 3497565343, 1239587997, 3543045781, 1253349015, 1260360594, 3531969424, 1158787504, 3700142514, 3709908151, 1153086645, 3732324029, 1206697663, 1179106234, 3755850680, 3638209193, 1094757035, 1089187758, 3648106412, 1136502180, 3660031398, 3683426467, 1108779169, 1604444640, 3325813218, 3348161767, 1577772261, 3301371629, 1566371567, 1559751658, 3312315368, 3261790969, 1542519547, 1515978750, 3284271100, 1494087156, 3231184374, 3241996531, 1487335665, 3476214481, 1453904595, 1459869654, 3466188756, 1414913500, 3452952030, 3429161179, 1442765017, 1392101832, 3412314570, 3402157263, 1397935309, 3382625989, 1342490311, 1370473410, 3358966720, 1791050048, 4082843970, 4075832391, 1802126405, 4054208077, 1748782671, 1771522890, 4027403080, 4144650841, 1854954075, 1866162014, 4137770844, 1819104596, 4126627158, 4099690579, 1841713233, 4199707249, 1674080883, 1650685814, 4227430260, 1630895484, 4172250494, 4177819771, 1620998265, 1738107240, 4261636458, 4289227887, 1714580589, 4244530789, 1701078631, 1691312994, 4250231648, 3772916257, 2037916195, 2027104038, 3779667748, 2072325420, 3793693998, 3820234795, 2049845289, 2099853624, 3836950842, 3843570751, 2088909885, 3863885365, 2144613943, 2122265394, 3890557744, 1886458128, 3924496658, 3896513559, 1910117397, 3944095261, 1921785375, 1931942682, 3938261784, 3988392457, 1948256779, 1972047630, 3960540940, 1994196228, 4014408966, 4008443907, 2004221953] num = 0 j = 0 progressMessageBar = define._messagBar.createMessage("Reading the file ...") progress = QProgressBar() progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) define._messagBar.pushWidget(progressMessageBar, define._messagBar.INFO) maxium = len(byteArray) progress.setMaximum(maxium) progress.setValue(0) for i in range(len(byteArray)): byte0 = None if isinstance(byteArray, bytearray): byte0 = Type.ByteFunc.d2b(num ^ ord(chr(byteArray[i]))) else: byte0 = Type.ByteFunc.d2b(num ^ ord(byteArray[i])) num = num >> 8 num = num ^ numArray[ord(byte0) % 36] progress.setValue(i) QApplication.processEvents() progress.setValue(maxium) define._messagBar.hide() resultByteArray = bytearray(4) for i in range(4): resultByteArray[i] = '0' resultByteArray[0] = Type.ByteFunc.d2b(num) resultByteArray[1] = Type.ByteFunc.d2b(num >> 8) resultByteArray[2] = Type.ByteFunc.d2b(num >> 16) resultByteArray[3] = Type.ByteFunc.d2b(num >> 24) stringBuilder = StringBuilder() for i in range(4): stringBuilder.Append(hex(ord(chr(resultByteArray[i]))).replace("0x", "").upper()) return stringBuilder.ToString()
class ExpandingProgressDialog(QProgressDialog): def __init__(self, parent=None): QProgressDialog.__init__(self, parent) self.progress = QProgressBar(self) self.progress.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.setBar(self.progress) def set_progress_text_visible(self, visible): self.progress.setTextVisible(visible) def set_progress_text(self, text): self.progress.setFormat(text) # overrides QProgressDialog.sizeHint def sizeHint(self): size = QProgressDialog.sizeHint(self) if size.width() < 400: size.setWidth(400) return size
class QgisMessageBarProgress: def __init__(self, text=""): self.progressMessageBar = \ iface.messageBar().createMessage(text) self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) iface.messageBar().pushWidget(self.progressMessageBar, iface.messageBar().INFO) def error(self, msg): iface.messageBar().clearWidgets() iface.messageBar().pushMessage("Error", msg, level=QgsMessageBar.CRITICAL, duration=3) def setPercentage(self, i): self.progress.setValue(i) def close(self): iface.messageBar().clearWidgets()
def dissolve(self, input_feats): # Function to dissolve input features to allow for buffering of multiple features feats = [] # Create and empty list of features and add all features to it. # We use feature 0 later and this ensures it exits. for each_feat in input_feats: feats.append(each_feat) # Do not run if geometry is empty, produce an error instead. if len(feats) > 0: # Need to create empty geometry to hold the dissolved features, we use the first feature to seed it. # Combine require a non-empty geometry to work (I could not get it to work). feat = feats[0] dissolved_geom = QgsGeometry() dissolved_geom = feat.geometry() # Progress bar for dissolving progressMessageBar = self.iface.messageBar().createMessage("Dissolving...") progress = QProgressBar() progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) maximum_progress = len(feats) progress.setMaximum(maximum_progress) i = 0 # Run through the features and dissolve them all. for each_feat in feats: geom = each_feat.geometry() dissolved_geom = geom.combine(dissolved_geom) i = i + 1 progress.setValue(i + 1) return_f = QgsFeature() return_f.setGeometry(dissolved_geom) self.iface.messageBar().clearWidgets() return return_f else: QMessageBox.warning(self.iface.mainWindow(), "Warning", "No features to dissolve.", QMessageBox.Ok) return input_feats
def _launchImport(self): ''' Launch the import ''' if not self._validateMapping(): return qgis_layer = self.qgislayers[self.cbbLayers.currentIndex()] self.close() # Progress bar + message progressMessageBar = PagLuxembourg.main.qgis_interface.messageBar( ).createMessage( QCoreApplication.translate('ImportShpDialog', 'Importing {}').format( self.shplayer.source())) progress = QProgressBar() progress.setMaximum(self.shplayer.featureCount()) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) PagLuxembourg.main.qgis_interface.messageBar().pushWidget( progressMessageBar, QgsMessageBar.INFO) # Start import session self._startImportSession() # Import the layer, and get the imported extent self._importLayer( self.shplayer, qgis_layer, self.mapping.asIndexFieldMappings( qgis_layer.dataProvider().fields(), self.shpfields), progress) # Commit import session self._commitImport()
def run(self, layerName=None): try: oLayer = qgis.utils.iface.activeLayer() if not oLayer: gErrorMsg = u"레이어를 먼저 선택해야 합니다." raise UserWarning # 종료 layerName = oLayer.name() layerType = oLayer.geometryType() crs = oLayer.crs() # if layerType != QGis.Point: # gErrorMsg = u"Point 형태의 레이어만 분석 가능합니다." # raise UserWarning # 종료 # ID 리스트 확보 oIDs = oLayer.allFeatureIds() # Progress 생성 progressMessageBar = self.iface.messageBar().createMessage( u"자료 정보 수집중...") progress = QProgressBar() progress.setMaximum(len(oIDs)) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) # centroid 모으기 centroidList = [] for i, oID in enumerate(oIDs): progress.setValue(i) iFeature = oLayer.getFeatures(QgsFeatureRequest(oID)).next() iGeom = iFeature.geometry().centroid() centroidList.append(iGeom) # Progress 제거 self.iface.messageBar().clearWidgets() # Memory Layer 생성 # "Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", or "MultiPolygon". tLayerOption = "{0}?crs={1}&index=yes".format( "LineString", crs.authid()) tLayer = QgsVectorLayer(tLayerOption, self.prefix + layerName, "memory") tProvider = tLayer.dataProvider() tLayer.startEditing() tProvider.addAttributes([ QgsField("iID", QVariant.Int), QgsField("jID", QVariant.Int), QgsField("Dist", QVariant.Double), QgsField("Group", QVariant.String) ]) # 최근린점 찾기 sumNearDist = 0.0 for iID, iGeom in zip(oIDs, centroidList): minDist = None nearID = None nearGeom = None for jID, jGeom in zip(oIDs, centroidList): if iID == jID: continue dist = iGeom.distance(jGeom) if minDist is None or dist < minDist: minDist = dist nearID = jID nearGeom = jGeom if not nearGeom is None: polyline = [] polyline.append(iGeom.vertexAt(0)) polyline.append(nearGeom.vertexAt(0)) tFeature = QgsFeature(tProvider.fields()) tFeature.setGeometry(QgsGeometry.fromPolyline(polyline)) tFeature.setAttribute(0, iID) tFeature.setAttribute(1, nearID) tFeature.setAttribute(2, minDist) tFeature.setAttribute(3, "Connection") tProvider.addFeatures([tFeature]) sumNearDist += minDist # ConvexHull multiPoint = [centroid.vertexAt(0) for centroid in centroidList] multiPointGeom = QgsGeometry.fromMultiPoint(multiPoint) convexHull = multiPointGeom.convexHull() tFeature = QgsFeature(tProvider.fields()) tFeature.setGeometry( QgsGeometry.fromPolyline(convexHull.asPolygon()[0])) tFeature.setAttribute(3, "ConvexHull") tProvider.addFeatures([tFeature]) # 메모리 레이어에 기록 tLayer.commitChanges() tLayer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(tLayer) qgis.utils.iface.mapCanvas().refresh() # 통계량 계산 extent = tLayer.extent() # 면적은 Convexhull로 A = convexHull.area() N = len(oIDs) ro = N / A r_exp = 1 / (2 * (ro**0.5)) #r_var = 0.26 / ((N*ro)**0.5) r_var = (4 - math.pi) / (4 * math.pi * ro * N ) #0.26 / ((N*ro)**0.5) r_obs = sumNearDist / N self.R = r_obs / r_exp #Z_r = (r_obs - r_exp) / (r_var**0.5) self.Z_r = 3.826 * (r_obs - r_exp) * (ro * N)**0.5 alert("R: %f, Z_r: %f" % (self.R, self.Z_r)) print("R: %f, Z_r: %f" % (self.R, self.Z_r)) except KeyError, e: alert(str(e) + u" 필드를 찾지 못함", QMessageBox.Warning)
def showNodes(self): """ Parse the geometry of a selected layer and show its vertices (nodes) """ mr = self.layerRegistry # Get the selected layer for which to show nodes selectedIndex = self.dlg.comboLayers.currentIndex() selectedLayer = self.dlg.comboLayers.itemData(selectedIndex) registeredLayers = self.layerRegistry.mapLayersByName('Noeuds') featuresCount = int(selectedLayer.featureCount()) # Remove the node layer if already existing if mr.mapLayersByName('Noeuds'): mr.removeMapLayer(mr.mapLayersByName('Noeuds')[0].id()) # Create memory layer to display nodes self.nodeLayer = QgsVectorLayer("Point?crs=EPSG:2056", "Noeuds", "memory") self.nodeLayerProvider = self.nodeLayer.dataProvider() # Create rendering style nodeSymbol = QgsMarkerSymbolV2.defaultSymbol( self.nodeLayer.geometryType()) nodeSymbol.setColor(QColor('#CC3300')) nodeSymbol.setSize(2.0) nodeRenderer = QgsSingleSymbolRendererV2(nodeSymbol) self.nodeLayer.setRendererV2(nodeRenderer) # Select features visible in current map canvas extent if self.dlg.chkSelectByCanvasExtent.checkState(): extent = self.canvas.extent() rect = QgsRectangle(extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()) request = QgsFeatureRequest() request.setFilterRect(rect) featureIterator = selectedLayer.getFeatures(request) # Select all features else: featureIterator = selectedLayer.getFeatures() # Create progress bar progressMessageBar = self.messageBar.createMessage( unicode("Création des noeuds...", "utf-8")) progress = QProgressBar() progress.setMinimum(0) progress.setMaximum(featuresCount) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.messageBar.pushWidget(progressMessageBar, self.iface.messageBar().INFO) # Iterate over feature k = 0 for feature in featureIterator: k += 1 progress.setValue(k) geom = feature.geometry() feat = QgsFeature() # Adapt procedure for each geometry type if (geom): type = geom.wkbType() # LineString if type == QGis.WKBLineString: for point in geom.asPolyline(): feat.setGeometry(QgsGeometry.fromPoint(point)) self.nodeLayerProvider.addFeatures([feat]) # MultiLineString elif type == QGis.WKBMultiLineString: for line in geom.asMultiPolyline(): for vertex in line: feat.setGeometry( QgsGeometry.fromPoint( QgsPoint(vertex[0], vertex[1]))) self.nodeLayerProvider.addFeatures([feat]) # Polygon elif type == QGis.WKBPolygon: polygons = geom.asPolygon() for polygon in polygons: for vertex in polygon: feat.setGeometry( QgsGeometry.fromPoint( QgsPoint(vertex[0], vertex[1]))) self.nodeLayerProvider.addFeatures([feat]) # MultiPolygon elif type == QGis.WKBMultiPolygon: multiPoly = geom.asMultiPolygon() for polygons in multiPoly: for polygon in polygons: for vertex in polygon: feat.setGeometry( QgsGeometry.fromPoint( QgsPoint(vertex[0], vertex[1]))) self.nodeLayerProvider.addFeatures([feat]) else: self.messageBar.pushMessage( "Cartotools : ", unicode("Type de géométrie non" + "supporté: " + str(type), "utf-8"), level=QgsMessageBar.CRITICAL) self.messageBar.clearWidgets() self.layerRegistry.addMapLayer(self.nodeLayer)
class DUdpReplay(QtHelper.EnhancedQDialog, Logger.ClassLogger): """ Http replay dialog """ def __init__(self, parent=None, offlineMode=False): """ Constructor @param parent: @type parent: """ super(DUdpReplay, self).__init__(parent) self.offlineMode = offlineMode self.defaultIp = "127.0.0.1" self.defaultPort = "80" self.newTest = '' self.newTestExec = '' self.newInputs = [] self.requests = [] self.responses = [] self.defaultTemplates = DefaultTemplates.Templates() self.testType = None self.createDialog() self.createConnections() self.createActions() self.createToolbar() def createActions(self): """ Create qt actions """ self.openAction = QtHelper.createAction(self, "&Open", self.importTrace, icon=QIcon(":/folder_add.png"), tip='Open network trace.') self.exportTUAction = QtHelper.createAction( self, "&Test Unit", self.exportToTU, icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE), tip='Export to Test Unit') self.exportTSAction = QtHelper.createAction( self, "&Test Suite", self.exportToTS, icon=QIcon(":/%s.png" % WWorkspace.TestSuite.TYPE), tip='Export to Test Suite') self.cancelAction = QtHelper.createAction(self, "&Cancel", self.reject, tip='Cancel') menu = QMenu(self) menu.addAction(self.exportTUAction) menu.addAction(self.exportTSAction) self.exportToAction = QtHelper.createAction( self, "&Export to", self.exportToTU, icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE), tip='Export to tests') self.exportToAction.setMenu(menu) self.exportToAction.setEnabled(False) def createDialog(self): """ Create dialog """ self.dockToolbar = QToolBar(self) self.dockToolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.setWindowTitle(WINDOW_TITLE) self.resize(500, 400) self.ipEdit = QLineEdit(self.defaultIp) ipRegExpVal = QRegExpValidator(self) ipRegExp = QRegExp("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") ipRegExpVal.setRegExp(ipRegExp) self.ipEdit.setValidator(ipRegExpVal) self.portEdit = QLineEdit(self.defaultPort) self.portEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) validatorPort = QIntValidator(self) self.portEdit.setValidator(validatorPort) self.progressBar = QProgressBar(self) self.progressBar.setMaximum(100) self.progressBar.setProperty("value", 0) self.progressBar.setAlignment(Qt.AlignCenter) self.progressBar.setObjectName("progressBar") self.guiSikuliGroupBox = QGroupBox("") self.guiSikuliGroupBox.setFlat(True) self.automaticAdp = QRadioButton("Automatic") self.automaticAdp.setChecked(True) self.defaultAdp = QRadioButton("Default") self.genericAdp = QRadioButton("Generic") vbox = QHBoxLayout() vbox.addWidget(self.automaticAdp) vbox.addWidget(self.defaultAdp) vbox.addWidget(self.genericAdp) vbox.addStretch(1) self.guiSikuliGroupBox.setLayout(vbox) layout = QVBoxLayout() layout.addWidget(self.dockToolbar) layout.addSpacing(12) paramLayout = QGridLayout() paramLayout.addWidget(QLabel("Destination IP:"), 0, 0, Qt.AlignRight) paramLayout.addWidget(self.ipEdit, 0, 1) paramLayout.addWidget(QLabel("Destination Port:"), 1, 0, Qt.AlignRight) paramLayout.addWidget(self.portEdit, 1, 1) paramLayout.addWidget(QLabel(self.tr("Gui adapter selector:")), 2, 0, Qt.AlignRight) paramLayout.addWidget(self.guiSikuliGroupBox, 2, 1) layout.addLayout(paramLayout) self.logsEdit = QTextEdit() self.logsEdit.setReadOnly(True) self.logsEdit.setTextInteractionFlags(Qt.NoTextInteraction) layout.addSpacing(12) layout.addWidget(self.logsEdit) layout.addSpacing(12) layout.addWidget(self.progressBar) self.setLayout(layout) def createToolbar(self): """ Create toolbar """ self.dockToolbar.setObjectName("File toolbar") self.dockToolbar.addAction(self.openAction) self.dockToolbar.addSeparator() self.dockToolbar.addAction(self.exportToAction) self.dockToolbar.addSeparator() self.dockToolbar.setIconSize(QSize(16, 16)) def createConnections(self): """ Create qt connections """ pass def autoScrollOnTextEdit(self): """ Automatic scroll on text edit """ cursor = self.logsEdit.textCursor() cursor.movePosition(QTextCursor.End) self.logsEdit.setTextCursor(cursor) def strip_html(self, txt): """ Strip html """ if "<" in txt: txt = txt.replace('<', '<') if ">" in txt: txt = txt.replace('>', '>') return txt def addLogSuccess(self, txt): """ Add log success in the text edit """ self.logsEdit.insertHtml( "<span style='color:darkgreen'>%s</span><br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def addLogWarning(self, txt): """ Add log warning in the text edit """ self.logsEdit.insertHtml( "<span style='color:darkorange'>%s</span><br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def addLogError(self, txt): """ Add log error in the text edit """ self.logsEdit.insertHtml("<span style='color:red'>%s</span><br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def addLog(self, txt): """ Append log to the logsEdit widget """ self.logsEdit.insertHtml("%s<br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def importTrace(self): """ Import network trace """ self.logsEdit.clear() self.testType = None if not self.offlineMode: if not RCI.instance().isAuthenticated(): self.addLogWarning( txt="<< Connect to the test center in first!") QMessageBox.warning(self, "Import", "Connect to the test center in first!") return self.exportToAction.setEnabled(False) self.newTest = '' self.progressBar.setMaximum(100) self.progressBar.setValue(0) if sys.version_info > (3, ): fileName = QFileDialog.getOpenFileName( self, self.tr("Open File"), "", "Network dump (*.cap;*.pcap;*.pcapng)") else: fileName = QFileDialog.getOpenFileName(self, self.tr("Open File"), "", "Network dump (*.cap)") # new in v18 to support qt5 if QtHelper.IS_QT5: _fileName, _type = fileName else: _fileName = fileName # end of new if not _fileName: return if sys.version_info < (3, ): extension = str(_fileName).rsplit(".", 1)[1] if not (extension == "cap"): self.addLogError(txt="<< File not supported %s" % _fileName) QMessageBox.critical(self, "Open", "File not supported") return _fileName = str(_fileName) capName = _fileName.rsplit("/", 1)[1] self.addLogSuccess(txt=">> Reading the file %s" % _fileName) self.readFileV2(fileName=_fileName) def exportToTS(self): """ Export to test suite """ self.testType = TS self.exportToTest(TS=True, TU=False) def exportToTU(self): """ Export to test unit """ self.testType = TU self.exportToTest(TS=False, TU=True) def searchUDP(self): """ Search UDP module in assistant """ # modules accessor ret = "SutAdapters" if self.automaticAdp.isChecked(): isGeneric = WWorkspace.Helper.instance().isGuiGeneric(name="GUI") if isGeneric: ret = "SutAdapters.Generic" elif self.defaultAdp.isChecked(): return ret elif self.genericAdp.isChecked(): ret = "SutAdapters.Generic" else: pass return ret def exportToTest(self, TS=True, TU=False): """ Export to test """ if not RCI.instance().isAuthenticated(): self.addLogWarning(txt="<< Connect to the test center in first!") QMessageBox.warning(self, "Import", "Connect to the test center in first!") return if TS: self.newTest = self.defaultTemplates.getTestDefinitionAuto() self.newTestExec = self.defaultTemplates.getTestExecutionAuto() if TU: self.newTest = self.defaultTemplates.getTestUnitDefinitionAuto() destIp = str(self.ipEdit.text()) destPort = str(self.portEdit.text()) self.newInputs = [] self.newInputs.append({ 'type': 'self-ip', 'name': 'BIND_IP', 'description': '', 'value': '0.0.0.0', 'color': '' }) self.newInputs.append({ 'type': 'int', 'name': 'BIND_PORT', 'description': '', 'value': '0', 'color': '' }) self.newInputs.append({ 'type': 'str', 'name': 'DEST_IP', 'description': '', 'value': '%s' % destIp, 'color': '' }) self.newInputs.append({ 'type': 'int', 'name': 'DEST_PORT', 'description': '', 'value': '%s' % destPort, 'color': '' }) self.newInputs.append({ 'type': 'bool', 'name': 'DEBUG', 'description': '', 'value': 'False', 'color': '' }) self.newInputs.append({ 'type': 'float', 'name': 'TIMEOUT', 'description': '', 'value': '5.0', 'color': '' }) adps = """self.ADP_UDP = %s.UDP.Client(parent=self, bindIp=input('BIND_IP'), bindPort=input('BIND_PORT'), destinationIp=input('DEST_IP'), destinationPort=input('DEST_PORT'), debug=input('DEBUG'), separatorDisabled=True)""" % self.searchUDP( ) # prepare steps steps = [] j = 0 for i in xrange(len(self.requests)): j = i + 1 sentrecv, req = self.requests[i] if sentrecv == 'sent': steps.append( 'self.step%s = self.addStep(expected="udp data sent", description="send udp data", summary="send udp data")' % j) else: steps.append( 'self.step%s = self.addStep(expected="udp data received", description="received udp data", summary="received udp data")' % j) tests = [] for i in xrange(len(self.requests)): j = i + 1 sentrecv, req = self.requests[i] (source, dest, source_port, dest_port, data) = req if sentrecv == 'sent': tests.append("# data to sent %s" % j) tests.append('self.step%s.start()' % j) if sys.version_info > (3, ): tests.append('rawSent = %s' % data.replace(b"'", b"\\'")) else: tests.append('rawSent = """%s"""' % data) tests.append('SentMsg = self.ADP_UDP.sendData(data=rawSent)') tests.append('if not SentMsg:') tests.append( '\tself.step%s.setFailed(actual="unable to send data")' % j) tests.append('else:') tests.append( '\tself.step%s.setPassed(actual="udp data sent succesfully")' % j) tests.append('') if sentrecv == 'recv': tests.append("# data to received %s" % j) tests.append('self.step%s.start()' % j) if sys.version_info > (3, ): tests.append('rawRecv = %s' % data.replace(b'"', b'\\"')) else: tests.append('rawRecv = """%s"""' % data) tests.append( 'RecvMsg = self.ADP_UDP.hasReceivedData(data=rawRecv, timeout=input("TIMEOUT"))' ) tests.append('if RecvMsg is None:') tests.append( '\tself.step%s.setFailed(actual="unable to received data")' % j) tests.append('else:') tests.append( '\tself.step%s.setPassed(actual="udp data received succesfully")' % j) tests.append('') if TS: init = """self.ADP_UDP.startListening() udpListening = self.ADP_UDP.isListening( timeout=input('TIMEOUT') ) if not udpListening: self.abort( 'unable to listing to the udp port %s' ) """ % str(self.portEdit.text()) if TU: init = """self.ADP_UDP.startListening() udpListening = self.ADP_UDP.isListening( timeout=input('TIMEOUT') ) if not udpListening: self.abort( 'unable to connect to the udp port %s' ) """ % str(self.portEdit.text()) if TS: cleanup = """self.ADP_UDP.stopListening() udpStopped = self.ADP_UDP.isStopped( timeout=input('TIMEOUT') ) if not udpStopped: self.error( 'unable to no more listen from the udp port %s' ) """ % str(self.portEdit.text()) if TU: cleanup = """self.ADP_UDP.stopListening() udpStopped = self.ADP_UDP.isStopped( timeout=input('TIMEOUT') ) if not udpStopped: self.error( 'unable to no more listen from the udp port %s' ) """ % str(self.portEdit.text()) self.newTest = self.newTest.replace( "<<PURPOSE>>", 'self.setPurpose(purpose="Replay UDP")') self.newTest = self.newTest.replace("<<ADPS>>", adps) if TS: self.newTest = self.newTest.replace("<<STEPS>>", '\n\t\t'.join(steps)) if TU: self.newTest = self.newTest.replace("<<STEPS>>", '\n\t'.join(steps)) self.newTest = self.newTest.replace("<<INIT>>", init) self.newTest = self.newTest.replace("<<CLEANUP>>", cleanup) if TS: self.newTest = self.newTest.replace("<<TESTS>>", '\n\t\t'.join(tests)) if TU: self.newTest = self.newTest.replace("<<TESTS>>", '\n\t'.join(tests)) self.accept() def readFileV2(self, fileName): """ Read pcap file Support pcap-ng too """ fd = open(fileName, 'rb') fileFormat, fileHead = PcapParse.extractFormat(fd) if fileFormat == PcapParse.FileFormat.PCAP: self.trace("pcap file detected") pcapFile = PcapReader.PcapFile(fd, fileHead).read_packet self.readFilePacket(pcapFile=pcapFile) elif fileFormat == PcapParse.FileFormat.PCAP_NG: self.trace("pcap-png file detected") pcapFile = PcapngReader.PcapngFile(fd, fileHead).read_packet self.readFilePacket(pcapFile=pcapFile) else: self.addLogError(txt="<< Error to open the network trace") self.error('unable to open the network trace: file format = %s' % fileFormat) QMessageBox.critical(self, "Import", "File not supported") def readFilePacket(self, pcapFile): """ Read file packet by packet """ ip_expected = str(self.ipEdit.text()) port_expected = int(self.portEdit.text()) # read packet) packets = pcapFile() ethernetPackets = list(packets) self.addLogSuccess(txt="<< Total packets detected: %s " % len(ethernetPackets)) # extract udp packet according to the expected ip and port self.requests = [] i = 1 self.progressBar.setMaximum(len(ethernetPackets)) self.progressBar.setValue(0) for pkt in ethernetPackets: self.progressBar.setValue(i) i += 1 pktDecoded = PcapParse.decodePacket(pkt, getTcp=False, getUdp=True) if pktDecoded is not None: (source, dest, source_port, dest_port, data) = pktDecoded # skip when no data exists if dest == ip_expected and int(dest_port) == int( port_expected) and len(data) > 0: self.requests.append(('sent', pktDecoded)) if source == ip_expected and int(source_port) == int( port_expected) and len(data) > 0: self.requests.append(('recv', pktDecoded)) self.addLogSuccess(txt="<< Number of UDP packets detected: %s" % len(self.requests)) if self.requests: self.addLogSuccess("<< File decoded with success!") self.addLogWarning( "<< Click on the export button to generate the test!") self.exportToAction.setEnabled(True) else: self.addLogWarning("<< No udp extracted!")
class MyCustomDialog(QDialog): def __init__(self): super(MyCustomDialog, self).__init__() layout = QVBoxLayout(self) # Create a progress bar and a button and add them to the main layout self.progressBarUpdate = QProgressBar(self) self.progressBarUpdate.setAlignment(Qt.AlignCenter) layout.addWidget(self.progressBarUpdate) pushButtonUpdate = QPushButton("Start", self) layout.addWidget(pushButtonUpdate) pushButtonCancel = QPushButton("Cancel", self) layout.addWidget(pushButtonCancel) pushButtonUpdate.clicked.connect(self.check_folder_exists) # Set data for download and saving in path self.location = os.path.abspath(os.path.join('temp', 'example-app-0.3.win32.zip')) self.url = 'http://sophus.bplaced.net/download/example-app-0.3.win32.zip' self.download_task = Download_Thread(self.location, self.url) self.download_task.notify_progress.connect(self.on_progress) self.download_task.finished_thread.connect(self.on_finished) self.download_task.error_http.connect(self.on_HTTPError) self.download_task.finished_download.connect(self.on_finish_download) pushButtonCancel.clicked.connect(self.on_finished) def on_start(self): self.progressBarUpdate.setRange(0, 0) self.download_task.start() def on_finish_download(self): msg_box = QMessageBox() QMessageBox.question(msg_box, ' Message ', "The file has been fully downloaded.", msg_box.Ok) def on_HTTPError(self): reply = QMessageBox.question(self, ' Error ', "The file could not be downloaded. Will they do it again?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.on_start() else: event.ignore() def on_progress(self, i): self.progressBarUpdate.setRange(0, 100) self.progressBarUpdate.setValue(i) def check_folder_exists(self): location = os.path.abspath(os.path.join('temp')) if not os.path.exists(location): os.makedirs(location) print "Folder was created" self.on_start() else: print "Folder already exists" self.on_start() def on_finished(self): self.progressBarUpdate.setValue(0) self.close() def closeEvent(self, event): self.download_task.stop()
class ObstacleTable(QSortFilterProxyModel): MocMultiplier = 1 SelectionMode = SelectionModeType.Automatic def __init__(self, surfacesList, fileWriter=None): QSortFilterProxyModel.__init__(self) ObstacleTable.SelectionMode = SelectionModeType.Automatic self.manualPolygon = None self.surfacesList = surfacesList self.surfaceType = None self.source = QStandardItemModel() self.setSourceModel(self.source) # tableView.hideColumn(self.IndexObjectId) # tableView.hideColumn(self.IndexLayerId) # tableView.hideColumn(self.IndexX) # tableView.hideColumn(self.IndexY) # tableView.hideColumn(self.IndexLat) # tableView.hideColumn(self.IndexLon) # tableView.hideColumn(self.IndexSurface) self.hideColumnLabels = [ ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId, ObstacleTableColumnType.X, ObstacleTableColumnType.Y, ObstacleTableColumnType.Lat, ObstacleTableColumnType.Lon, ObstacleTableColumnType.Surface ] self.fixedColumnLabels = [ ObstacleTableColumnType.ObjectId, ObstacleTableColumnType.LayerId, ObstacleTableColumnType.Name, ObstacleTableColumnType.X, ObstacleTableColumnType.Y, ObstacleTableColumnType.Lat, ObstacleTableColumnType.Lon, ObstacleTableColumnType.AltM, ObstacleTableColumnType.AltFt, ObstacleTableColumnType.TreesM, ObstacleTableColumnType.TreesFt ] self.IndexObjectId = 0 self.IndexLayerId = 1 self.IndexName = 2 self.IndexX = 3 self.IndexY = 4 self.IndexLat = 5 self.IndexLon = 6 self.IndexAltM = 7 self.IndexAltFt = 8 self.IndexTreesM = 9 self.IndexTreesFt = 10 self.IndexOcaM = -1 self.IndexOcaFt = -1 self.IndexOchM = -1 self.IndexOchFt = -1 self.IndexObstArea = -1 self.IndexDistInSecM = -1 self.IndexMocAppliedM = -1 self.IndexMocAppliedFt = -1 self.IndexMocMultiplier = -1 self.IndexMocReqM = -1 self.IndexMocReqFt = -1 self.IndexDoM = -1 self.IndexDrM = -1 self.IndexDzM = -1 self.IndexDxM = -1 self.IndexDsocM = -1 self.IndexHeightLossM = -1 self.IndexHeightLossFt = -1 self.IndexAcAltM = -1 self.IndexAcAltFt = -1 self.IndexAltReqM = -1 self.IndexAltReqFt = -1 self.IndexCritical = -1 self.IndexMACG = -1 self.IndexPDG = -1 self.IndexSurfAltM = -1 self.IndexSurfAltFt = -1 self.IndexDifferenceM = -1 self.IndexDifferenceFt = -1 self.IndexIlsX = -1 self.IndexIlsY = -1 self.IndexEqAltM = -1 self.IndexEqAltFt = -1 self.IndexSurfaceName = -1 self.IndexDisregardable = -1 self.IndexCloseIn = -1 self.IndexTag = -1 self.IndexSurface = -1 self.IndexArea = -1 self.IndexHLAppliedM = -1 self.setHeaderLabels() self.setFilterKeyColumn(self.IndexSurface) self.setSortRole(Qt.UserRole + 1) self.layoutChanged.connect(self.setVerticalHeader) self.btnLocate = None self.tblObstacles = None def FilterDisregardableObstacles(self, state): if state: self.setFilterKeyColumn(self.IndexDisregardable) self.setFilterFixedString("Yes") self.setFilterKeyColumn(self.IndexSurface) def setSurfaceType(self, surfaceType): self.surfaceType = surfaceType def setFilterFixedString(self, filterString): QSortFilterProxyModel.setFilterFixedString(self, filterString) self.setVerticalHeader() if self.btnLocate != None and self.tblObstacles != None: selectedIndexes = self.tblObstacles.selectedIndexes() if len(selectedIndexes) == 0: self.btnLocate.setEnabled(False) else: self.btnLocate.setEnabled(True) def setLocateBtn(self, btnLocate): self.btnLocate = btnLocate self.btnLocate.setEnabled(False) self.btnLocate.clicked.connect(self.btnLocateClicked) def btnLocateClicked(self): if self.tblObstacles == None: return selectedIndexes = self.tblObstacles.selectedIndexes() self.locate(selectedIndexes) def tblObstaclesClicked(self, idx): if len(self.tblObstacles.selectedIndexes()) > 0: self.btnLocate.setEnabled(True) def setTableView(self, tblObstacles): self.tblObstacles = tblObstacles self.tblObstacles.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblObstacles.setSortingEnabled(True) self.tblObstacles.clicked.connect(self.tblObstaclesClicked) self.tblObstacles.verticalHeader().sectionClicked.connect( self.tblObstaclesClicked) pass def setHeaderLabels(self): # print self.setHeaderData(1, Qt.Vertical, 1, Qt.DisplayRole) pass def setVerticalHeader(self): for i in range(self.rowCount()): self.setHeaderData(i, Qt.Vertical, i + 1, Qt.DisplayRole) def setHiddenColumns(self, tableView): tableView.hideColumn(self.IndexObjectId) tableView.hideColumn(self.IndexLayerId) tableView.hideColumn(self.IndexX) tableView.hideColumn(self.IndexY) tableView.hideColumn(self.IndexLat) tableView.hideColumn(self.IndexLon) tableView.hideColumn(self.IndexSurface) def getExtentForLocate(self, sourceRow): extent = None surfaceType = None if self.IndexSurface < 0: surfaceType = self.surfaceType else: surfaceType = self.source.item(sourceRow, self.IndexSurface).text() surfaceLayers = QgisHelper.getSurfaceLayers(self.surfaceType) for sfLayer in surfaceLayers: lId = sfLayer.name() if lId.contains(surfaceType): extent = sfLayer.extent() break return extent def clear(self): self.source.clear() self.source.setHorizontalHeaderLabels(self.fixedColumnLabels) # self.setHeaderLabels() def locate(self, selectedRowIndexes): if selectedRowIndexes == None or len(selectedRowIndexes) <= 0: return sourceRow = self.mapToSource(selectedRowIndexes[0]).row() objectId = int(self.source.item(sourceRow, self.IndexObjectId).text()) layerId = self.source.item(sourceRow, self.IndexLayerId).text() QgisHelper.selectFeature(layerId, objectId) layer = QgsMapLayerRegistry.instance().mapLayer(layerId) crs = define._canvas.mapSettings().destinationCrs() if crs.mapUnits() == QGis.Meters: x = float(self.source.item(sourceRow, self.IndexX).text()) y = float(self.source.item(sourceRow, self.IndexY).text()) extent = QgsRectangle(x - 350, y - 350, x + 350, y + 350) else: x, result1 = self.source.item(sourceRow, self.IndexLon).data().toDouble() y, result2 = self.source.item(sourceRow, self.IndexLat).data().toDouble() extent = QgsRectangle(x - 0.005, y - 0.005, x + 0.005, y + 0.005) point = QgsPoint(x, y) # extent = self.getExtentForLocate(sourceRow) if extent is None: return QgisHelper.zoomExtent(point, extent, 2) pass def loadObstacles(self, surfaceLayers): if self.source.rowCount() > 0: self.source.clear() self.source.setHorizontalHeaderLabels(self.fixedColumnLabels) demEvaluateAg = None existingDemFlag = False obstacleLayersDEM = QgisHelper.getSurfaceLayers(SurfaceTypes.DEM) obstacleLayers = QgisHelper.getSurfaceLayers(SurfaceTypes.Obstacles) if obstacleLayersDEM != None and len(obstacleLayersDEM) > 0: if QMessageBox.question( None, "Question", "Do you want to use DEM for evaluating Obstacle?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes: self.loadObstaclesDEM(obstacleLayersDEM, surfaceLayers) if obstacleLayers != None and len(obstacleLayers) > 0: # if QMessageBox.question(None, "Question", "Do you want to use DEM for evaluating Obstacle?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: self.loadObstaclesVector(obstacleLayers, surfaceLayers) return True def loadObstaclesDEM(self, obstacleLayersDEM, surfaceLayers): progressMessageBar = define._messagBar.createMessage( "Loading DEM Obstacles...") self.progress = QProgressBar() self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(self.progress) define._messagBar.pushWidget(progressMessageBar, define._messagBar.INFO) maxium = 0 offset = 0.0 self.progress.setValue(0) wCount = 0 hCount = 0 for ly in obstacleLayersDEM: demDataProvider = ly.dataProvider() boundDem = demDataProvider.extent() xMin = boundDem.xMinimum() xMax = boundDem.xMaximum() yMin = boundDem.yMinimum() yMax = boundDem.yMaximum() bound = QgisHelper.getIntersectExtent( ly, QgsGeometry.fromRect(boundDem), surfaceLayers) # boundGeom = QgsGeometry.fromRect(bound) if bound == None: continue block = ly.dataProvider().block(0, ly.extent(), ly.width(), ly.height()) xMinimum = ly.dataProvider().extent().xMinimum() yMaximum = ly.dataProvider().extent().yMaximum() yMinimum = ly.dataProvider().extent().yMinimum() xMaximum = ly.dataProvider().extent().xMaximum() xOffSet = ly.extent().width() / ly.width() yOffSet = ly.extent().height() / ly.height() offset = xOffSet if bound.xMinimum() < xMinimum: wStartNumber = 0 xStartValue = xMinimum else: wStartNumber = int((bound.xMinimum() - xMinimum) / xOffSet) xStartValue = bound.xMinimum() if yMaximum < bound.yMaximum(): hStartNumber = 0 yStartValue = yMaximum else: hStartNumber = int((yMaximum - bound.yMaximum()) / yOffSet) yStartValue = bound.yMaximum() if bound.xMaximum() > xMaximum: xEndValue = xMaximum else: xEndValue = bound.xMaximum() if yMinimum > bound.yMinimum(): yEndValue = yMinimum else: yEndValue = bound.yMinimum() wCount = int(math.fabs(xEndValue - xStartValue) / xOffSet) hCount = int(math.fabs(yEndValue - yStartValue) / yOffSet) pixelCount = hCount maxium += pixelCount cellSizeWnd = cellsizeWnd(offset, wCount * hCount, maxium * 0.04) cellSizeWnd.setWindowTitle("Input Cell Size") result = cellSizeWnd.exec_() cellRate = 1 if result == 1: offset = cellSizeWnd.cellsize maxium = cellSizeWnd.cellCount + 2 cellRate = cellSizeWnd.cellRate # print cellSizeWnd.textedit1.text() if maxium == 0: return False self.progress.setMaximum(maxium) trees = define._treesDEM tolerance = define._toleranceDEM for obstacleLayer in obstacleLayersDEM: obstacleUnits = obstacleLayer.crs().mapUnits() demDataProvider = obstacleLayer.dataProvider() boundDem = demDataProvider.extent() bound = QgisHelper.getIntersectExtent( obstacleLayer, QgsGeometry.fromRect(boundDem), surfaceLayers) if bound == None: continue boundGeom = QgsGeometry.fromRect(bound) if not boundGeom.intersects(QgsGeometry.fromRect(boundDem)): continue block = obstacleLayer.dataProvider().block(1, obstacleLayer.extent(), obstacleLayer.width(), obstacleLayer.height()) xMinimum = obstacleLayer.extent().xMinimum() yMaximum = obstacleLayer.extent().yMaximum() yMinimum = obstacleLayer.extent().yMinimum() xMaximum = obstacleLayer.extent().xMaximum() xOffSet = obstacleLayer.extent().width() / obstacleLayer.width() yOffSet = obstacleLayer.extent().height() / obstacleLayer.height() if bound.xMinimum() < xMinimum: hStartNumber = 0 xStartValue = xMinimum else: hStartNumber = int((bound.xMinimum() - xMinimum) / xOffSet) xStartValue = bound.xMinimum() if yMaximum < bound.yMaximum(): wStartNumber = 0 yStartValue = yMaximum else: wStartNumber = int((yMaximum - bound.yMaximum()) / yOffSet) yStartValue = bound.yMaximum() if bound.xMaximum() > xMaximum: xEndValue = xMaximum else: xEndValue = bound.xMaximum() if yMinimum > bound.yMinimum(): yEndValue = yMinimum else: yEndValue = bound.yMinimum() wCount = int(math.fabs(xEndValue - xStartValue) / offset) hCount = int(math.fabs(yEndValue - yStartValue) / offset) xPixelWidth = 0.0 yPixelWidth = 0.0 featureID = 0 # i = 0 # k = 0 # altitudeList = [] # self.progress.setValue(0) # while i <= hCount - 1: # j = 0 # while j <= wCount - 1: # if block.isNoData(j * int(cellRate) + wStartNumber, i* int(cellRate) + hStartNumber): # self.progress.setValue(k) # QApplication.processEvents() # j += 1 # k += 1 # altitudeList.append(None) # continue # altitude = block.value(j * int(cellRate) + wStartNumber, i * int(cellRate) + hStartNumber) # altitudeList.append(altitude) # self.progress.setValue(k) # QApplication.processEvents() # j += 1 # k += 1 # i += 1 i = 0 k = 0 name = "DEM" semiXoffset = xOffSet / 2 semiYoffset = yOffSet / 2 while i <= hCount - 1: j = 0 while j <= wCount - 1: if block.isNoData(j * cellRate + wStartNumber, i * cellRate + hStartNumber): self.progress.setValue(k) QApplication.processEvents() j += 1 k += 1 continue altitude = block.value(j * cellRate + wStartNumber, i * cellRate + hStartNumber) # # if block.isNoData(j * int(cellRate) + wStartNumber, i* int(cellRate) + hStartNumber): # # j += 1 # # self.progress.setValue(self.progress.value() + 1) # # QApplication.processEvents() # # continue # # altitude = block.value(j* int(cellRate) + wStartNumber, i* int(cellRate)+ hStartNumber) # altitude = altitudeList[k] # if altitude == None: # self.progress.setValue(k) # QApplication.processEvents() # j += 1 # k += 1 # continue point = QgsPoint( xStartValue + (i * cellRate) * xOffSet + semiXoffset, yStartValue - (j * cellRate - 1) * yOffSet - semiYoffset) position = Point3D() positionDegree = Point3D() if define._canvas.mapUnits() == QGis.Meters: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): position = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: position = Point3D(point.x(), point.y(), altitude) else: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): positionDegree = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: positionDegree = Point3D(point.x(), point.y(), altitude) obstacle = Obstacle(name, position, obstacleLayer.id(), featureID, None, trees, ObstacleTable.MocMultiplier, tolerance) obstacle.positionDegree = positionDegree if self.manualPolygon != None: if not self.manualPolygon.contains(obstacle.Position): continue self.checkObstacle(obstacle) self.progress.setValue(k) QApplication.processEvents() j += 1 featureID += 1 k += 1 i += 1 self.progress.setValue(maxium) define._messagBar.hide() self.manualPolygon = None def loadObstaclesVector(self, obstacleLayers, surfaceLayers): progressMessageBar = define._messagBar.createMessage( "Loading Vector Obstacles...") self.progress = QProgressBar() self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(self.progress) define._messagBar.pushWidget(progressMessageBar, define._messagBar.INFO) maxium = 0 self.progress.setValue(0) for ly in obstacleLayers: maxium += ly.featureCount() if maxium == 0: return False self.progress.setMaximum(maxium) for obstacleLayer in obstacleLayers: obstacleUnits = obstacleLayer.crs().mapUnits() features = QgisHelper.getFeaturesInLayerExtent( define._canvas, obstacleLayer, surfaceLayers, SelectionModeType.Automatic) # print len(features) for feature in features: name = feature.attribute("Name").toString() altitude = feature.attribute("Altitude").toFloat()[0] trees = define._trees tolerance = define._tolerance point = feature.geometry().asPoint() position = Point3D() positionDegree = Point3D() if define._canvas.mapUnits() == QGis.Meters: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): position = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: position = Point3D(point.x(), point.y(), altitude) else: if define._canvas.mapSettings().destinationCrs( ) != obstacleLayer.crs(): positionDegree = QgisHelper.CrsTransformPoint( point.x(), point.y(), obstacleLayer.crs(), define._canvas.mapSettings().destinationCrs(), altitude) else: positionDegree = Point3D(point.x(), point.y(), altitude) featureId = feature.id() layerId = obstacleLayer.id() obstacle = Obstacle(name, position, layerId, featureId, None, trees, ObstacleTable.MocMultiplier, tolerance) obstacle.positionDegree = positionDegree # obstacle.positionDegree = positionDegree self.checkObstacle(obstacle) self.progress.setValue(self.progress.value() + 1) QApplication.processEvents() QApplication.processEvents() self.progress.setValue(maxium) define._messagBar.hide() self.manualPolygon = None def addObstacleToModel(self, obstacle, checkResult=None): standardItemList = [] # obstacle.positionDegree = QgisHelper.Meter2Degree(obstacle.Position.x(), obstacle.Position.y()) standardItem = QStandardItem(str(obstacle.featureId)) standardItem.setData(obstacle.featureId) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.layerId)) standardItem.setData(obstacle.layerId) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.name)) standardItem.setData(obstacle.name) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.Position.x())) standardItem.setData(obstacle.Position.x()) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.Position.y())) standardItem.setData(obstacle.Position.y()) standardItemList.append(standardItem) value = QVariant(QgisHelper.strDegree(obstacle.positionDegree.y())) standardItem = QStandardItem(value.toString()) standardItem.setData(obstacle.positionDegree.y()) standardItemList.append(standardItem) strV = QgisHelper.strDegree(obstacle.positionDegree.y()) value = QVariant(QgisHelper.strDegree(obstacle.positionDegree.x())) standardItem = QStandardItem(value.toString()) standardItem.setData(obstacle.positionDegree.x()) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.Position.z())) standardItem.setData(obstacle.Position.z()) standardItemList.append(standardItem) standardItem = QStandardItem( str(Unit.ConvertMeterToFeet(obstacle.Position.z()))) standardItem.setData(Unit.ConvertMeterToFeet(obstacle.Position.z())) standardItemList.append(standardItem) standardItem = QStandardItem(str(obstacle.trees)) standardItem.setData(obstacle.trees) standardItemList.append(standardItem) standardItem = QStandardItem( str(Unit.ConvertMeterToFeet(obstacle.trees))) standardItem.setData(Unit.ConvertMeterToFeet(obstacle.trees)) standardItemList.append(standardItem) # for i in range(len(standardItemList), self.source.columnCount()): # standardItemList.append(QStandardItem("None")) self.source.appendRow(standardItemList) standardItem = QStandardItem(str(obstacle.mocMultiplier)) standardItem.setData(obstacle.mocMultiplier) self.source.setItem(self.source.rowCount() - 1, self.IndexMocMultiplier, standardItem) def checkObstacle(self, obstacle): pass def CompareObstacleRows(self, newRow, row, ignore): pass def method_0(self, obstacle_0): colCount = self.columnCount() objectId = range(colCount) objectId[0] = (obstacle_0.featureId) objectId[1] = (obstacle_0.name) objectId[2] = (obstacle_0.position.x()) objectId[3] = (obstacle_0.position.y()) objectId[4] = (obstacle_0.Position.z()) position = obstacle_0.position objectId[6] = (Unit.ConvertMeterToFeet(position.z())) objectId[7] = (obstacle_0.trees) objectId[8] = (Unit.ConvertMeterToFeet(obstacle_0.Trees)) if (self.IndexMocMultiplier > -1): objectId[self.IndexMocMultiplier] = obstacle_0.MocMultiplier return objectId def method_1(self, object_0): pass
def view(self): """create view and import layers""" layer = QgsMapLayerRegistry.instance().mapLayer(self.current_layers[0]) uri = QgsDataSourceURI(layer.source()) mtch = re.match(r'(.+)_([^_]+)_rev_(head|\d+)', uri.schema()) schema = mtch.group(1) assert (schema) dlg = QDialog() layout = QVBoxLayout(dlg) button_box = QDialogButtonBox(dlg) button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) button_box.accepted.connect(dlg.accept) button_box.rejected.connect(dlg.reject) user_msg1 = QgsMessageBar(dlg) user_msg1.pushInfo( "Select:", "one [many] for single [multiple] " "revisions. Fetching may take time.") pcur = versioning_base.Db(psycopg2.connect(self.pg_conn_info())) pcur.execute("SELECT rev, commit_msg, branch, date, author " "FROM " + schema + ".revisions") revs = pcur.fetchall() pcur.close() tblw = QTableWidget(dlg) tblw.setRowCount(len(revs)) tblw.setColumnCount(6) tblw.setSortingEnabled(True) tblw.setHorizontalHeaderLabels([ 'Select', 'Revision', 'Commit Message', 'Branch', 'Date', 'Author' ]) tblw.verticalHeader().setVisible(False) for i, rev in enumerate(revs): for j, item in enumerate(rev): chkBoxItem = QTableWidgetItem() chkBoxItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) chkBoxItem.setCheckState(Qt.Unchecked) tblw.setItem(i, 0, chkBoxItem) tblw.setItem(i, j + 1, QTableWidgetItem(str(item))) layout.addWidget(user_msg1) layout.addWidget(tblw) layout.addWidget(button_box) dlg.resize(650, 300) if not dlg.exec_(): return rows = set() revision_number_list = [] for i in range(len(revs)): if tblw.item(i, 0).checkState(): print "Revision " + str(i + 1) + " will be fetched" revision_number_list.append(i + 1) rows.add(tblw.item(i, 0).row()) progressMessageBar = self.iface.messageBar().createMessage( "Querying " "the database for revision(s) " + str(revision_number_list)) progress = QProgressBar() progress.setMaximum(len(rows)) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) progress.setValue(0) for i, row in enumerate(rows): progress.setValue(i + 1) branch = revs[row][2] rev = revs[row][0] versioning_base.add_revision_view(uri.connectionInfo(), schema, branch, rev) grp_name = branch + ' revision ' + str(rev) grp_idx = self.iface.legendInterface().addGroup(grp_name) for layer_id in reversed(self.current_layers): layer = QgsMapLayerRegistry.instance().mapLayer(layer_id) new_uri = QgsDataSourceURI(layer.source()) new_uri.setDataSource( schema + '_' + branch + '_rev_' + str(rev), new_uri.table(), new_uri.geometryColumn(), new_uri.sql(), new_uri.keyColumn()) display_name = QgsMapLayerRegistry.instance().mapLayer( layer_id).name() src = new_uri.uri().replace('()', '') new_layer = self.iface.addVectorLayer(src, display_name, 'postgres') self.iface.legendInterface().moveLayer(new_layer, grp_idx) self.iface.messageBar().clearWidgets()
class CatalogDialogTool(QObject): """ Tool for managing the search and export functionality """ def __init__(self, iface, dialog_ui, bbox_tool): """ Constructor for the dialog tool :param iface: The QGIS Interface :param dialog_ui: The dialog GUI :param bbox_tool The bounding box tool :return: dialog tool """ QObject.__init__(self, None) self.iface = iface self.dialog_ui = dialog_ui self.bbox_tool = bbox_tool self.progress_bar = None self.progress_message_bar = None self.progress_message_bar_widget = None self.search_thread_pool = QThreadPool() self.search_lock = Lock() self.export_thread_pool = QThreadPool() self.export_lock = Lock() self.query = None self.previous_credentials = None self.export_file = None self.footprint_layer = None self.filters = CatalogFilters(self.dialog_ui) self.dialog_ui.aoi_button.clicked.connect(self.aoi_button_clicked) self.dialog_ui.reset_button.clicked.connect(self.reset_button_clicked) self.dialog_ui.export_button.clicked.connect(self.export_button_clicked) self.bbox_tool.released.connect(self.search) self.model = None def init_progress_bar(self, progress_max): """ Sets up the progress bar for search functionality :return: None """ if not self.progress_message_bar: self.progress_message_bar = self.iface.messageBar().createMessage("Querying for data") self.progress_bar = QProgressBar() self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(progress_max) self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignCenter) self.progress_message_bar.layout().addWidget(self.progress_bar) self.progress_message_bar_widget = self.iface.messageBar().pushWidget(self.progress_message_bar, self.iface.messageBar().INFO) def init_layers(self): """ Sets up the layers for rendering the items :return: None """ if self.footprint_layer: QgsMapLayerRegistry.instance().removeMapLayer(self.footprint_layer.id()) self.footprint_layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "Catalog Footprints", "memory") self.footprint_layer.setCrs(QgsCoordinateReferenceSystem(4326), True) self.footprint_layer.dataProvider().addAttributes(CatalogAcquisitionFeature.get_fields()) QgsMapLayerRegistry.instance().addMapLayer(self.footprint_layer) def clear_widgets(self): """ Clears the progress bar :return: None """ self.progress_bar = None self.progress_message_bar = None if self.progress_message_bar_widget: self.iface.messageBar().popWidget(self.progress_message_bar_widget) self.progress_message_bar_widget = None def is_searching(self): """ Check to see if the system is still searching (checks if there's work in the search thread pool) :return: True if searching; False otherwise """ return self.get_search_active_thread_count() > 0 def is_exporting(self): """ Check to see if the system is still exporting (checks if there's work in the export thread pool) :return: True if searching; False otherwise """ return self.get_export_active_thread_count() > 0 def get_search_active_thread_count(self): """ Gets the number of active threads in the search thread pool :return: """ with self.search_lock: return self.search_thread_pool.activeThreadCount() def get_export_active_thread_count(self): """ Gets the number of active threads in the export thread pool :return: """ with self.export_lock: return self.export_thread_pool.activeThreadCount() def aoi_button_clicked(self): """ Validates and runs the search if validation successful :return: None """ # can't run search during export if self.is_exporting(): self.iface.messageBar().pushMessage("Error", "Cannot run search while export is running.", level=QgsMessageBar.CRITICAL) # can't run multiple search elif self.is_searching(): self.iface.messageBar().pushMessage("Error", "Cannot run a new search while a search is running.", level=QgsMessageBar.CRITICAL) else: self.bbox_tool.reset() self.iface.mapCanvas().setMapTool(self.bbox_tool) def reset_button_clicked(self): """ Resets filters. :return: None """ self.reset() def export_button_clicked(self): """ Validates and runs the export if validation successful :return: None """ # can't run export during search if self.is_searching(): self.iface.messageBar().pushMessage("Error", "Cannot run export while search is running.", level=QgsMessageBar.CRITICAL) # can't run multiple exports elif self.is_exporting(): self.iface.messageBar().pushMessage("Error", "Cannot run a new export while a export is running.", level=QgsMessageBar.CRITICAL) else: self.export() def search(self, top, bottom, left, right): self.search_thread_pool.waitForDone(0) # validate credentials if they changed errors = [] username, password, api_key, max_items_to_return = SettingsOps.get_settings() credentials = [username, password, api_key] if not self.previous_credentials or self.previous_credentials != credentials: SettingsOps.validate_stored_info(username, password, api_key, max_items_to_return, errors) self.previous_credentials = credentials # validate filters if not errors: self.filters.validate(errors) if errors: self.iface.messageBar().pushMessage("Error", "The following errors occurred: " + "<br />".join(errors), level=QgsMessageBar.CRITICAL) else: self.init_layers() self.dialog_ui.tab_widget.setCurrentIndex(RESULTS_TAB_INDEX) next_x_list = self.drange_list(float(left) + INCREMENTAL_INTERVAL, float(right), INCREMENTAL_INTERVAL) next_y_list = self.drange_list(float(bottom) + INCREMENTAL_INTERVAL, float(top), INCREMENTAL_INTERVAL) self.init_progress_bar(len(next_x_list) * len(next_y_list)) self.model = CatalogTableModel(self.dialog_ui.table_view) self.dialog_ui.table_view.setModel(self.model) self.dialog_ui.table_view.selectionModel().selectionChanged.connect(self.selection_changed) if not self.query: self.query = GBDQuery(username=username, password=password, api_key=api_key) filters = self.filters.get_query_filters() time_begin = self.filters.get_datetime_begin() time_end = self.filters.get_datetime_end() current_x = float(left) current_y = float(bottom) for next_x in next_x_list: for next_y in next_y_list: search_runnable = CatalogSearchRunnable(self.query, self.model, self, top=next_y, left=current_x, right=next_x, bottom=current_y, time_begin=time_begin, time_end=time_end, filters=filters) search_runnable.task_object.task_complete.connect(self.on_search_complete) self.search_thread_pool.start(search_runnable) current_y = next_y current_y = bottom current_x = next_x def reset(self): self.filters.remove_all() def export(self): self.export_thread_pool.waitForDone(0) acquisitions = None if self.model is not None: acquisitions = self.model.data if not acquisitions: self.iface.messageBar().pushMessage("Error", "No data to export.", level=QgsMessageBar.CRITICAL) else: # open file ui select_file_ui = QFileDialog() starting_file = self.export_file or os.path.expanduser("~") export_file = select_file_ui.getSaveFileName(None, "Choose output file", starting_file, SELECT_FILTER) if export_file: self.export_file = export_file self.init_progress_bar(0) export_runnable = CatalogExportRunnable(acquisitions, self.export_file) export_runnable.task_object.task_complete.connect(self.on_export_complete) self.export_thread_pool.start(export_runnable) @pyqtSlot() def on_search_complete(self): thread_count = self.get_search_active_thread_count() if self.progress_message_bar: self.progress_bar.setValue(self.progress_bar.value() + 1) if thread_count == 0: self.clear_widgets() self.dialog_ui.table_view.resizeColumnsToContents() @pyqtSlot() def on_export_complete(self): thread_count = self.get_export_active_thread_count() if self.progress_message_bar: self.progress_bar.setValue(self.progress_bar.value() + 1) if thread_count == 0: self.clear_widgets() self.iface.messageBar().pushMessage("Info", 'File export has completed to "%s".' % self.export_file) def selection_changed(self, selected, deselected): self.footprint_layer.startEditing() # draw footprints for selected rows selected_rows = set() for index in selected.indexes(): selected_rows.add(index.row()) for row in selected_rows: acquisition = self.model.get(row) feature_id = self.model.generate_feature_id() self.model.set_feature_id(acquisition, feature_id) feature = CatalogAcquisitionFeature(feature_id, acquisition) self.footprint_layer.dataProvider().addFeatures([feature]) # remove footprints for deselected rows deselected_rows = set() for index in deselected.indexes(): deselected_rows.add(index.row()) feature_ids_to_remove = [] for row in deselected_rows: acquisition = self.model.get(row) feature_id = self.model.get_feature_id(acquisition) feature_ids_to_remove.append(feature_id) self.model.remove_feature_id(acquisition) if feature_ids_to_remove: self.footprint_layer.dataProvider().deleteFeatures(feature_ids_to_remove) self.footprint_layer.commitChanges() self.footprint_layer.updateExtents() self.footprint_layer.triggerRepaint() def drange_list(self, start, stop, step): drange_list = [] r = start while r < stop: drange_list.append(r) r += step if not drange_list: drange_list.append(stop) return drange_list
class SearchWidget(QFrame): """Widget, appeared, when Ctrl+F pressed. Has different forms for different search modes """ Normal = "normal" Good = "good" Bad = "bad" Incorrect = "incorrect" visibilityChanged = pyqtSignal(bool) """ visibilityChanged(visible) **Signal** emitted, when widget has been shown or hidden """ # pylint: disable=W0105 searchInDirectoryStartPressed = pyqtSignal(type(re.compile("")), list, unicode) """ searchInDirectoryStartPressed(regEx, mask, path) **Signal** emitted, when 'search in directory' button had been pressed """ # pylint: disable=W0105 searchInDirectoryStopPressed = pyqtSignal() """ searchInDirectoryStopPressed() **Signal** emitted, when 'stop search in directory' button had been pressed """ # pylint: disable=W0105 replaceCheckedStartPressed = pyqtSignal(unicode) """ replaceCheckedStartPressed(replText) **Signal** emitted, when 'replace checked' button had been pressed """ # pylint: disable=W0105 replaceCheckedStopPressed = pyqtSignal() """ replaceCheckedStartPressed() **Signal** emitted, when 'stop replacing checked' button had been pressed """ # pylint: disable=W0105 searchRegExpChanged = pyqtSignal(type(re.compile(""))) """ searchRegExpValidStateChanged(regEx) **Signal** emitted, when search regexp has been changed. If reg exp is invalid - regEx object contains empty pattern """ # pylint: disable=W0105 searchNext = pyqtSignal() """ searchNext() **Signal** emitted, when 'Search Next' had been pressed """ # pylint: disable=W0105 searchPrevious = pyqtSignal() """ searchPrevious() **Signal** emitted, when 'Search Previous' had been pressed """ # pylint: disable=W0105 replaceFileOne = pyqtSignal(unicode) """ replaceFileOne(replText) **Signal** emitted, when 'Replace' had been pressed """ # pylint: disable=W0105 replaceFileAll = pyqtSignal(unicode) """ replaceFileAll(replText) **Signal** emitted, when 'Replace All' had been pressed """ # pylint: disable=W0105 def __init__(self, plugin): QFrame.__init__(self, core.workspace()) self._mode = None self.plugin = plugin from PyQt4 import uic # lazy import for better startup performance uic.loadUi(os.path.join(os.path.dirname(__file__), "SearchWidget.ui"), self) self.cbSearch.setCompleter(None) self.cbReplace.setCompleter(None) self.cbMask.setCompleter(None) self.fsModel = QDirModel(self.cbPath.lineEdit()) self.fsModel.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot) self.cbPath.lineEdit().setCompleter(QCompleter(self.fsModel, self.cbPath.lineEdit())) # TODO QDirModel is deprecated but QCompleter does not yet handle # QFileSystemodel - please update when possible.""" self.cbSearch.setCompleter(None) self.pbSearchStop.setVisible(False) self.pbReplaceCheckedStop.setVisible(False) self._progress = QProgressBar(self) self._progress.setAlignment(Qt.AlignCenter) self._progress.setToolTip(self.tr("Search in progress...")) self._progress.setMaximumSize(QSize(80, 16)) core.mainWindow().statusBar().insertPermanentWidget(1, self._progress) self._progress.setVisible(False) # cd up action self.tbCdUp = QToolButton(self.cbPath.lineEdit()) self.tbCdUp.setIcon(QIcon(":/enkiicons/go-up.png")) self.tbCdUp.setCursor(Qt.ArrowCursor) self.tbCdUp.installEventFilter(self) # for drawing button self.cbSearch.installEventFilter(self) # for catching Tab and Shift+Tab self.cbReplace.installEventFilter(self) # for catching Tab and Shift+Tab self.cbPath.installEventFilter(self) # for catching Tab and Shift+Tab self.cbMask.installEventFilter(self) # for catching Tab and Shift+Tab self._closeShortcut = QShortcut(QKeySequence("Esc"), self) self._closeShortcut.setContext(Qt.WidgetWithChildrenShortcut) self._closeShortcut.activated.connect(self.hide) # connections self.cbSearch.lineEdit().textChanged.connect(self._onSearchRegExpChanged) self.cbSearch.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbReplace.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbPath.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbMask.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbRegularExpression.stateChanged.connect(self._onSearchRegExpChanged) self.cbCaseSensitive.stateChanged.connect(self._onSearchRegExpChanged) self.tbCdUp.clicked.connect(self._onCdUpPressed) core.mainWindow().hideAllWindows.connect(self.hide) core.workspace().currentDocumentChanged.connect( lambda old, new: self.setVisible(self.isVisible() and new is not None) ) def show(self): """Reimplemented function. Sends signal """ super(SearchWidget, self).show() self.visibilityChanged.emit(self.isVisible()) def hide(self): """Reimplemented function. Sends signal, returns focus to workspace """ super(SearchWidget, self).hide() core.workspace().focusCurrentDocument() self.visibilityChanged.emit(self.isVisible()) def setVisible(self, visible): """Reimplemented function. Sends signal """ super(SearchWidget, self).setVisible(visible) self.visibilityChanged.emit(self.isVisible()) def _regExEscape(self, text): """Improved version of re.escape() Doesn't escape space, comma, underscore. Escapes \n and \t """ text = re.escape(text) # re.escape escapes space, comma, underscore, but, it is not necessary and makes text not readable for symbol in " ,_='\"/:@#%&": text = text.replace("\\" + symbol, symbol) text = text.replace("\\\n", "\\n") text = text.replace("\\\t", "\\t") return text def _makeEscapeSeqsVisible(self, text): """Replace invisible \n and \t with escape sequences """ text = text.replace("\t", "\\t") text = text.replace("\n", "\\n") return text def setMode(self, mode): """Change search mode. i.e. from "Search file" to "Replace directory" """ if self._mode == mode and self.isVisible(): if core.workspace().currentDocument() is not None and not core.workspace().currentDocument().hasFocus(): self.cbSearch.lineEdit().selectAll() self.cbSearch.setFocus() self._mode = mode # Set Search and Replace text if ( core.workspace().currentDocument() is not None and core.workspace().currentDocument().hasFocus() and core.workspace().currentDocument().selectedText() ): searchText = core.workspace().currentDocument().selectedText() self.cbReplace.setEditText(self._makeEscapeSeqsVisible(searchText)) if self.cbRegularExpression.checkState() == Qt.Checked: searchText = self._regExEscape(searchText) self.cbSearch.setEditText(searchText) if ( not self.cbReplace.lineEdit().text() and self.cbSearch.lineEdit().text() and not self.cbRegularExpression.checkState() == Qt.Checked ): self.cbReplace.setEditText(self.cbSearch.lineEdit().text()) # Move focus to Search edit self.cbSearch.setFocus() self.cbSearch.lineEdit().selectAll() # Set search path if mode & ModeFlagDirectory and not (self.isVisible() and self.cbPath.isVisible()): try: searchPath = os.path.abspath(unicode(os.path.curdir)) self.cbPath.setEditText(searchPath) except OSError: # current directory might have been deleted pass # Set widgets visibility flag according to state widgets = ( self.wSearch, self.pbPrevious, self.pbNext, self.pbSearch, self.wReplace, self.wPath, self.pbReplace, self.pbReplaceAll, self.pbReplaceChecked, self.wOptions, self.wMask, ) # wSear pbPrev pbNext pbSear wRepl wPath pbRep pbRAll pbRCHK wOpti wMask visible = { ModeSearch: (1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0), ModeReplace: (1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0), ModeSearchDirectory: (1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1), ModeReplaceDirectory: (1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1), ModeSearchOpenedFiles: (1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1), ModeReplaceOpenedFiles: (1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1), } for i, widget in enumerate(widgets): widget.setVisible(visible[mode][i]) # Search next button text if mode == ModeReplace: self.pbNext.setText("Next") else: self.pbNext.setText(u"Next↵") # Finaly show all with valid size self.show() # show before updating widgets and labels self._updateLabels() self._updateWidgets() def eventFilter(self, object_, event): """ Event filter for mode switch tool button Draws icons in the search and path lineEdits """ if event.type() == QEvent.Paint and object_ is self.tbCdUp: # draw CdUp button in search path QLineEdit toolButton = object_ lineEdit = self.cbPath.lineEdit() lineEdit.setContentsMargins(lineEdit.height(), 0, 0, 0) height = lineEdit.height() availableRect = QRect(0, 0, height, height) if toolButton.rect() != availableRect: toolButton.setGeometry(availableRect) painter = QPainter(toolButton) toolButton.icon().paint(painter, availableRect) return True elif event.type() == QEvent.KeyPress: # Tab and Shift+Tab in QLineEdits if event.key() == Qt.Key_Tab: self._moveFocus(1) return True elif event.key() == Qt.Key_Backtab: self._moveFocus(-1) return True return QFrame.eventFilter(self, object_, event) def _onReturnPressed(self): """Return or Enter pressed on widget. Search next or Replace next """ if self.pbReplace.isVisible(): self.pbReplace.click() elif self.pbNext.isVisible(): self.pbNext.click() elif self.pbSearch.isVisible(): self.pbSearch.click() elif self.pbSearchStop.isVisible(): self.pbSearchStop.click() def _moveFocus(self, step): """Move focus forward or backward according to step. Standard Qt Keyboard focus algorithm doesn't allow circular navigation """ allFocusableWidgets = (self.cbSearch, self.cbReplace, self.cbPath, self.cbMask) visibleWidgets = [widget for widget in allFocusableWidgets if widget.isVisible()] try: focusedIndex = visibleWidgets.index(QApplication.focusWidget()) except ValueError: print >>sys.stderr, "Invalid focused widget in Search Widget" return nextFocusedIndex = (focusedIndex + step) % len(visibleWidgets) visibleWidgets[nextFocusedIndex].setFocus() visibleWidgets[nextFocusedIndex].lineEdit().selectAll() def _updateLabels(self): """Update 'Search' 'Replace' 'Path' labels geometry """ width = 0 if self.lSearch.isVisible(): width = max(width, self.lSearch.minimumSizeHint().width()) if self.lReplace.isVisible(): width = max(width, self.lReplace.minimumSizeHint().width()) if self.lPath.isVisible(): width = max(width, self.lPath.minimumSizeHint().width()) self.lSearch.setMinimumWidth(width) self.lReplace.setMinimumWidth(width) self.lPath.setMinimumWidth(width) def _updateWidgets(self): """Update geometry of widgets with buttons """ width = 0 if self.wSearchRight.isVisible(): width = max(width, self.wSearchRight.minimumSizeHint().width()) if self.wReplaceRight.isVisible(): width = max(width, self.wReplaceRight.minimumSizeHint().width()) if self.wPathRight.isVisible(): width = max(width, self.wPathRight.minimumSizeHint().width()) self.wSearchRight.setMinimumWidth(width) self.wReplaceRight.setMinimumWidth(width) self.wPathRight.setMinimumWidth(width) def _updateComboBoxes(self): """Update comboboxes with last used texts """ searchText = self.cbSearch.currentText() replaceText = self.cbReplace.currentText() maskText = self.cbMask.currentText() # search if searchText: index = self.cbSearch.findText(searchText) if index == -1: self.cbSearch.addItem(searchText) # replace if replaceText: index = self.cbReplace.findText(replaceText) if index == -1: self.cbReplace.addItem(replaceText) # mask if maskText: index = self.cbMask.findText(maskText) if index == -1: self.cbMask.addItem(maskText) def _searchPatternTextAndFlags(self): """Get search pattern and flags """ pattern = self.cbSearch.currentText() if not self.cbRegularExpression.checkState() == Qt.Checked: pattern = re.escape(pattern) flags = 0 if not self.cbCaseSensitive.checkState() == Qt.Checked: flags = re.IGNORECASE return pattern, flags def getRegExp(self): """Read search parameters from controls and present it as a regular expression """ pattern, flags = self._searchPatternTextAndFlags() return re.compile(pattern, flags) def isSearchRegExpValid(self): """Try to compile search pattern to check if it is valid Returns bool result and text error """ pattern, flags = self._searchPatternTextAndFlags() try: re.compile(pattern, flags) except re.error, ex: return False, unicode(ex) return True, None
class TemplateOsrm(object): """ Template class to be subclassed by each OSRM dialog class. It contains some methods used by the five next class. """ def display_error(self, error, code): msg = { 1: "An error occured when trying to contact the OSRM instance", 2: "OSRM plugin error report : Too many errors occured " "when trying to contact the OSRM instance at {} - " "Route calculation has been stopped".format(self.host), } self.iface.messageBar().clearWidgets() self.iface.messageBar().pushMessage( "Error", msg[code] + "(see QGis log for error traceback)", duration=10) QgsMessageLog.logMessage( 'OSRM-plugin error report :\n {}'.format(error), level=QgsMessageLog.WARNING) def make_prog_bar(self): progMessageBar = self.iface.messageBar().createMessage( "Creation in progress...") self.progress = QProgressBar() self.progress.setMaximum(10) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progMessageBar.layout().addWidget(self.progress) self.iface.messageBar().pushWidget( progMessageBar, self.iface.messageBar().INFO) @staticmethod @lru_cache(maxsize=30) def query_url(url): r = urllib2.urlopen(url) return json.loads(r.read(), strict=False) def print_about(self): mbox = QMessageBox(self.iface.mainWindow()) mbox.setIcon(QMessageBox.Information) mbox.setWindowTitle('About') mbox.setTextFormat(Qt.RichText) mbox.setText( "<p><b>(Unofficial) OSRM plugin for qgis</b><br><br>" "Author: mthh, 2015<br>Licence : GNU GPL v2<br><br><br>Underlying " "routing engine is <a href='http://project-osrm.org'>OSRM</a>" "(Open Source Routing Engine) :<br>- Based on <a href='http://" "www.openstreetmap.org/copyright'>OpenStreetMap</a> " "dataset<br>- Easy to start a local instance<br>" "- Pretty fast engine (based on contraction hierarchies and mainly" " writen in C++)<br>- Mainly authored by D. Luxen and C. " "Vetter<br>(<a href='http://project-osrm.org'>http://project-osrm" ".org</a> or <a href='https://github.com/Project-OSRM/osrm" "-backend#references-in-publications'>on GitHub</a>)<br></p>") mbox.open() def store_origin(self, point): """ Method to store a click on the QGIS canvas """ if '4326' not in self.canvas.mapSettings().destinationCrs().authid(): crsSrc = self.canvas.mapSettings().destinationCrs() xform = QgsCoordinateTransform( crsSrc, QgsCoordinateReferenceSystem(4326)) point = xform.transform(point) self.origin = point self.canvas.unsetMapTool(self.originEmit) self.lineEdit_xyO.setText(str(point))
def run(self): # Plugin uses selected layer, hope to add layer selection later. active_vl = self.iface.activeLayer() # We check for selected features to auto-populate the "use selected feature" box in the dialog. sel_feats = '' if active_vl is not None: sel_feats = active_vl.selectedFeatures() result = 0 """Run method that performs all the real work""" # Logic if to run the dialog if active_vl is None: sel_feats = '' QMessageBox.warning(self.iface.mainWindow(), "Warning", "No layer selected.", QMessageBox.Ok) result = 0 elif active_vl.type() == QgsMapLayer.RasterLayer: sel_feats = '' QMessageBox.warning(self.iface.mainWindow(), "Warning", "Raster layer selected.", QMessageBox.Ok) result = 0 elif active_vl.type() == QgsMapLayer.PluginLayer: sel_feats = '' QMessageBox.warning(self.iface.mainWindow(), "Warning", "Plugin layer selected, please save as a regular layer and try again.", QMessageBox.Ok) result = 0 elif active_vl is not None: self.dlg.populatedialogue(active_vl.name()) if len(sel_feats) == 0: # If selected layer has selected features populate the box. # If not make it impossible to populate the box. self.dlg.selectedfeats(0) else: self.dlg.selectedfeats(1) self.dlg.show() result = self.dlg.exec_() else: sel_feats = '' QMessageBox.warning(self.iface.mainWindow(), "Warning", "Could not process layer.", QMessageBox.Ok) result = 0 # If ok was clicked in the dialog, continue: if result == 1: buffer_crs_object = self.iface.activeLayer().crs() # Check the current CRS of the layer buffer_crs = buffer_crs_object.authid() # Apply that to the created layer if recognised buffer_input_crs = "Polygon?crs=%s" % buffer_crs # Create empty memory vector layer for buffers layer_name = active_vl.name() vl = QgsVectorLayer(buffer_input_crs, "%s_MultiRingBuffer" % layer_name, "memory") vl_pr = vl.dataProvider() # Distance feature for buffer distance vl_pr.addAttributes([QgsField("distance", QVariant.String)]) vl.updateFields() # Switch between sequential and central buffer styles. # A toggle was added, but it seems too complex of a question for most users. buffer_style = "sequential" #if self.dlg.ui.central.isChecked(): # buffer_style = "central" #else: # buffer_style = "sequential" # Inputs from the dialog: dissolve_test = self.dlg.ui.dissovle_button_2.isChecked() if dissolve_test == 0: dissolve_bool = 0 else: dissolve_bool = 1 segments_to_approximate = self.dlg.ui.segmentsToApproximate.value() num_of_rings = self.dlg.ui.numberOfRings.value() buffer_distance = self.dlg.ui.bufferDistance.value() use_sel_feats_test = self.dlg.ui.selectedfeats.isChecked() if use_sel_feats_test == 0: use_sel_feats = 0 else: use_sel_feats = 1 # We use "sel_feats" to populate a box in the dialog, but if all features wanted, we need to re-populate it # with all the features in the layer. if use_sel_feats == 0: iterate = active_vl.getFeatures() sel_feats = [] for feature in iterate: sel_feats.append(feature) # Dissolve the features if selected. if dissolve_bool == 1: sel2feats = [] add_feat = self.dissolve(sel_feats) # Our buffer loops require a list (as sel_feats originally is), so we append the features to a list. sel2feats.append(add_feat) else: sel2feats = sel_feats # Progress bar. progressMessageBar = self.iface.messageBar().createMessage("Buffering...") progress = QProgressBar() progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) maximum_progress = len(sel2feats) * num_of_rings progress.setMaximum(maximum_progress) i = 0 # Run if there are features in the layer if len(sel_feats) > 0: # Buffer a feature then buffer the buffer (used) if buffer_style == "sequential": new_buff_feats = [] distance = buffer_distance while num_of_rings > 0: to_buffer = [] for each_feat in sel2feats: geom = each_feat.geometry() buff = geom.buffer(buffer_distance, segments_to_approximate) new_f = QgsFeature() new_f.setGeometry(buff) to_buffer.append(new_f) new_f_geom = new_f.geometry() new_f_clipped = new_f_geom.difference(geom) new_f2 = QgsFeature() new_f2.setGeometry(new_f_clipped) new_f2.setAttributes([distance]) new_buff_feats.append(new_f2) i = i + 1 progress.setValue(i + 1) sel2feats = to_buffer num_of_rings = num_of_rings - 1 distance = distance + buffer_distance vl_pr.addFeatures(new_buff_feats) QgsMapLayerRegistry.instance().addMapLayer(vl) # Sequential buffers of the original feature with larger buffers if buffer_style == "central": orig_buffer_distance = buffer_distance buffered = [] for each_feat in sel2feats: num_to_buffer = num_of_rings to_clip = each_feat.geometry() buffer_distance = orig_buffer_distance while num_to_buffer > 0: geom = each_feat.geometry() buff = geom.buffer(buffer_distance, segments_to_approximate) new_f = QgsFeature() new_f_clipped = buff.difference(to_clip) new_f.setGeometry(new_f_clipped) new_f.setAttributes([buffer_distance]) buffered.append(new_f) buffer_distance = buffer_distance + orig_buffer_distance num_to_buffer = num_to_buffer - 1 to_clip = to_clip.combine(buff) i = i + 1 progress.setValue(i + 1) vl_pr.addFeatures(buffered) QgsMapLayerRegistry.instance().addMapLayer(vl) self.iface.messageBar().clearWidgets()
class SearchWidget(QFrame): """Widget, appeared, when Ctrl+F pressed. Has different forms for different search modes """ Normal = 'normal' Good = 'good' Bad = 'bad' Incorrect = 'incorrect' visibilityChanged = pyqtSignal(bool) """ visibilityChanged(visible) **Signal** emitted, when widget has been shown or hidden """ # pylint: disable=W0105 searchInDirectoryStartPressed = pyqtSignal(type(re.compile('')), list, unicode) """ searchInDirectoryStartPressed(regEx, mask, path) **Signal** emitted, when 'search in directory' button had been pressed """ # pylint: disable=W0105 searchInDirectoryStopPressed = pyqtSignal() """ searchInDirectoryStopPressed() **Signal** emitted, when 'stop search in directory' button had been pressed """ # pylint: disable=W0105 replaceCheckedStartPressed = pyqtSignal(unicode) """ replaceCheckedStartPressed(replText) **Signal** emitted, when 'replace checked' button had been pressed """ # pylint: disable=W0105 replaceCheckedStopPressed = pyqtSignal() """ replaceCheckedStartPressed() **Signal** emitted, when 'stop replacing checked' button had been pressed """ # pylint: disable=W0105 searchRegExpChanged = pyqtSignal(type(re.compile(''))) """ searchRegExpValidStateChanged(regEx) **Signal** emitted, when search regexp has been changed. If reg exp is invalid - regEx object contains empty pattern """ # pylint: disable=W0105 searchNext = pyqtSignal() """ searchNext() **Signal** emitted, when 'Search Next' had been pressed """ # pylint: disable=W0105 searchPrevious = pyqtSignal() """ searchPrevious() **Signal** emitted, when 'Search Previous' had been pressed """ # pylint: disable=W0105 replaceFileOne = pyqtSignal(unicode) """ replaceFileOne(replText) **Signal** emitted, when 'Replace' had been pressed """ # pylint: disable=W0105 replaceFileAll = pyqtSignal(unicode) """ replaceFileAll(replText) **Signal** emitted, when 'Replace All' had been pressed """ # pylint: disable=W0105 def __init__(self, plugin): QFrame.__init__(self, core.workspace()) self._mode = None self.plugin = plugin from PyQt4 import uic # lazy import for better startup performance uic.loadUi(os.path.join(os.path.dirname(__file__), 'SearchWidget.ui'), self) self.cbSearch.setCompleter(None) self.cbReplace.setCompleter(None) self.cbMask.setCompleter(None) self.fsModel = QDirModel(self.cbPath.lineEdit()) self.fsModel.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot) self.cbPath.lineEdit().setCompleter( QCompleter(self.fsModel, self.cbPath.lineEdit())) # TODO QDirModel is deprecated but QCompleter does not yet handle # QFileSystemodel - please update when possible.""" self.cbSearch.setCompleter(None) self.pbSearchStop.setVisible(False) self.pbReplaceCheckedStop.setVisible(False) self._progress = QProgressBar(self) self._progress.setAlignment(Qt.AlignCenter) self._progress.setToolTip(self.tr("Search in progress...")) self._progress.setMaximumSize(QSize(80, 16)) core.mainWindow().statusBar().insertPermanentWidget(1, self._progress) self._progress.setVisible(False) # cd up action self.tbCdUp = QToolButton(self.cbPath.lineEdit()) self.tbCdUp.setIcon(QIcon(":/enkiicons/go-up.png")) self.tbCdUp.setCursor(Qt.ArrowCursor) self.tbCdUp.installEventFilter(self) # for drawing button self.cbSearch.installEventFilter( self) # for catching Tab and Shift+Tab self.cbReplace.installEventFilter( self) # for catching Tab and Shift+Tab self.cbPath.installEventFilter(self) # for catching Tab and Shift+Tab self.cbMask.installEventFilter(self) # for catching Tab and Shift+Tab self._closeShortcut = QShortcut(QKeySequence("Esc"), self) self._closeShortcut.setContext(Qt.WidgetWithChildrenShortcut) self._closeShortcut.activated.connect(self.hide) # connections self.cbSearch.lineEdit().textChanged.connect( self._onSearchRegExpChanged) self.cbSearch.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbReplace.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbPath.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbMask.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbRegularExpression.stateChanged.connect( self._onSearchRegExpChanged) self.cbCaseSensitive.stateChanged.connect(self._onSearchRegExpChanged) self.cbWholeWord.stateChanged.connect(self._onSearchRegExpChanged) self.tbCdUp.clicked.connect(self._onCdUpPressed) self.pbNext.pressed.connect(self.searchNext) self.pbPrevious.pressed.connect(self.searchPrevious) self.pbSearchStop.pressed.connect(self.searchInDirectoryStopPressed) self.pbReplaceCheckedStop.pressed.connect( self.replaceCheckedStopPressed) core.mainWindow().hideAllWindows.connect(self.hide) core.workspace().escPressed.connect(self.hide) core.workspace().currentDocumentChanged.connect( \ lambda old, new: self.setVisible(self.isVisible() and new is not None)) def show(self): """Reimplemented function. Sends signal """ super(SearchWidget, self).show() self.visibilityChanged.emit(self.isVisible()) def hide(self): """Reimplemented function. Sends signal, returns focus to workspace """ super(SearchWidget, self).hide() core.workspace().focusCurrentDocument() self.visibilityChanged.emit(self.isVisible()) def setVisible(self, visible): """Reimplemented function. Sends signal """ super(SearchWidget, self).setVisible(visible) self.visibilityChanged.emit(self.isVisible()) def _regExEscape(self, text): """Improved version of re.escape() Doesn't escape space, comma, underscore. Escapes \n and \t """ text = re.escape(text) # re.escape escapes space, comma, underscore, but, it is not necessary and makes text not readable for symbol in (' ,_=\'"/:@#%&'): text = text.replace('\\' + symbol, symbol) text = text.replace('\\\n', '\\n') text = text.replace('\\\t', '\\t') return text def _makeEscapeSeqsVisible(self, text): """Replace invisible \n and \t with escape sequences """ text = text.replace('\\', '\\\\') text = text.replace('\t', '\\t') text = text.replace('\n', '\\n') return text def setMode(self, mode): """Change search mode. i.e. from "Search file" to "Replace directory" """ if self._mode == mode and self.isVisible(): if core.workspace().currentDocument() is not None and \ not core.workspace().currentDocument().hasFocus(): self.cbSearch.lineEdit().selectAll() self.cbSearch.setFocus() self._mode = mode # Set Search and Replace text document = core.workspace().currentDocument() if document is not None and \ document.hasFocus() and \ document.qutepart.selectedText: searchText = document.qutepart.selectedText self.cbReplace.setEditText(self._makeEscapeSeqsVisible(searchText)) if self.cbRegularExpression.checkState() == Qt.Checked: searchText = self._regExEscape(searchText) self.cbSearch.setEditText(searchText) if not self.cbReplace.lineEdit().text() and \ self.cbSearch.lineEdit().text() and \ not self.cbRegularExpression.checkState() == Qt.Checked: replaceText = self.cbSearch.lineEdit().text().replace('\\', '\\\\') self.cbReplace.setEditText(replaceText) # Move focus to Search edit self.cbSearch.setFocus() self.cbSearch.lineEdit().selectAll() # Set search path if mode & MODE_FLAG_DIRECTORY and \ not (self.isVisible() and self.cbPath.isVisible()): try: searchPath = os.path.abspath(unicode(os.path.curdir)) self.cbPath.setEditText(searchPath) except OSError: # current directory might have been deleted pass # Set widgets visibility flag according to state widgets = (self.wSearch, self.pbPrevious, self.pbNext, self.pbSearch, self.wReplace, self.wPath, \ self.pbReplace, self.pbReplaceAll, self.pbReplaceChecked, self.wOptions, self.wMask) # wSear pbPrev pbNext pbSear wRepl wPath pbRep pbRAll pbRCHK wOpti wMask visible = \ {MODE_SEARCH : (1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0,), MODE_REPLACE: (1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0,), MODE_SEARCH_DIRECTORY: (1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1,), MODE_REPLACE_DIRECTORY: (1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1,), MODE_SEARCH_OPENED_FILES: (1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,), MODE_REPLACE_OPENED_FILES: (1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1,)} for i, widget in enumerate(widgets): widget.setVisible(visible[mode][i]) # Search next button text if mode == MODE_REPLACE: self.pbNext.setText('Next') else: self.pbNext.setText(u'Next↵') # Finaly show all with valid size self.show() # show before updating widgets and labels self._updateLabels() self._updateWidgets() def eventFilter(self, object_, event): """ Event filter for mode switch tool button Draws icons in the search and path lineEdits """ if event.type( ) == QEvent.Paint and object_ is self.tbCdUp: # draw CdUp button in search path QLineEdit toolButton = object_ lineEdit = self.cbPath.lineEdit() lineEdit.setContentsMargins(lineEdit.height(), 0, 0, 0) height = lineEdit.height() availableRect = QRect(0, 0, height, height) if toolButton.rect() != availableRect: toolButton.setGeometry(availableRect) painter = QPainter(toolButton) toolButton.icon().paint(painter, availableRect) return True elif event.type( ) == QEvent.KeyPress: # Tab and Shift+Tab in QLineEdits if event.key() == Qt.Key_Tab: self._moveFocus(1) return True elif event.key() == Qt.Key_Backtab: self._moveFocus(-1) return True return QFrame.eventFilter(self, object_, event) def _onReturnPressed(self): """Return or Enter pressed on widget. Search next or Replace next """ if self.pbReplace.isVisible(): self.pbReplace.click() elif self.pbNext.isVisible(): self.pbNext.click() elif self.pbSearch.isVisible(): self.pbSearch.click() elif self.pbSearchStop.isVisible(): self.pbSearchStop.click() def _moveFocus(self, step): """Move focus forward or backward according to step. Standard Qt Keyboard focus algorithm doesn't allow circular navigation """ allFocusableWidgets = (self.cbSearch, self.cbReplace, self.cbPath, self.cbMask) visibleWidgets = [widget for widget in allFocusableWidgets \ if widget.isVisible()] try: focusedIndex = visibleWidgets.index(QApplication.focusWidget()) except ValueError: print >> sys.stderr, 'Invalid focused widget in Search Widget' return nextFocusedIndex = (focusedIndex + step) % len(visibleWidgets) visibleWidgets[nextFocusedIndex].setFocus() visibleWidgets[nextFocusedIndex].lineEdit().selectAll() def _updateLabels(self): """Update 'Search' 'Replace' 'Path' labels geometry """ width = 0 if self.lSearch.isVisible(): width = max(width, self.lSearch.minimumSizeHint().width()) if self.lReplace.isVisible(): width = max(width, self.lReplace.minimumSizeHint().width()) if self.lPath.isVisible(): width = max(width, self.lPath.minimumSizeHint().width()) self.lSearch.setMinimumWidth(width) self.lReplace.setMinimumWidth(width) self.lPath.setMinimumWidth(width) def _updateWidgets(self): """Update geometry of widgets with buttons """ width = 0 if self.wSearchRight.isVisible(): width = max(width, self.wSearchRight.minimumSizeHint().width()) if self.wReplaceRight.isVisible(): width = max(width, self.wReplaceRight.minimumSizeHint().width()) if self.wPathRight.isVisible(): width = max(width, self.wPathRight.minimumSizeHint().width()) self.wSearchRight.setMinimumWidth(width) self.wReplaceRight.setMinimumWidth(width) self.wPathRight.setMinimumWidth(width) def updateComboBoxes(self): """Update comboboxes with last used texts """ searchText = self.cbSearch.currentText() replaceText = self.cbReplace.currentText() maskText = self.cbMask.currentText() # search if searchText: index = self.cbSearch.findText(searchText) if index == -1: self.cbSearch.addItem(searchText) # replace if replaceText: index = self.cbReplace.findText(replaceText) if index == -1: self.cbReplace.addItem(replaceText) # mask if maskText: index = self.cbMask.findText(maskText) if index == -1: self.cbMask.addItem(maskText) def _searchPatternTextAndFlags(self): """Get search pattern and flags """ pattern = self.cbSearch.currentText() pattern = pattern.replace( u'\u2029', '\n') # replace unicode paragraph separator with habitual \n if not self.cbRegularExpression.checkState() == Qt.Checked: pattern = re.escape(pattern) if self.cbWholeWord.checkState() == Qt.Checked: pattern = r'\b' + pattern + r'\b' flags = 0 if not self.cbCaseSensitive.checkState() == Qt.Checked: flags = re.IGNORECASE return pattern, flags def getRegExp(self): """Read search parameters from controls and present it as a regular expression """ pattern, flags = self._searchPatternTextAndFlags() return re.compile(pattern, flags) def isSearchRegExpValid(self): """Try to compile search pattern to check if it is valid Returns bool result and text error """ pattern, flags = self._searchPatternTextAndFlags() try: re.compile(pattern, flags) except re.error, ex: return False, unicode(ex) return True, None
def view(self): """create view and import layers""" layer = QgsMapLayerRegistry.instance().mapLayer( self.current_layers[0] ) uri = QgsDataSourceURI(layer.source()) mtch = re.match(r'(.+)_([^_]+)_rev_(head|\d+)', uri.schema()) schema = mtch.group(1) assert(schema) # Disconnect signals previously connected upon calling this function # The first time this function is called will throw an error because no # previous connections to the slots were made try: #print "Disconnecting ..." self.q_view_dlg.tblw.itemChanged.disconnect() self.q_view_dlg.diffmode_chk.stateChanged.disconnect() except: #print "Failed disconnection" pass # Make sure combobox is initalized correctly self.q_view_dlg.diffmode_chk.setCheckState(Qt.Unchecked) self.q_view_dlg.diffmode_chk.setEnabled(False) pcur = versioning_base.Db( psycopg2.connect(self.pg_conn_info()) ) pcur.execute("SELECT rev, author, date::timestamp(0), branch, commit_msg " "FROM "+schema+".revisions ORDER BY rev ASC") revs = pcur.fetchall() pcur.close() self.q_view_dlg.tblw.setRowCount(len(revs)) self.q_view_dlg.tblw.setColumnCount(5) self.q_view_dlg.tblw.setHorizontalHeaderLabels(['Rev#', 'Author', 'Date', 'Branch', 'Commit Message']) for i, rev in enumerate(revs): for j, item in enumerate(rev): self.q_view_dlg.tblw.setItem(i,j,QTableWidgetItem( str(item) )) # set rev# checkable if j == 0: self.q_view_dlg.tblw.item(i,j).setCheckState(Qt.Unchecked) self.q_view_dlg.tblw.itemChanged.connect(self.enable_diffmode) self.q_view_dlg.tblw.resizeRowsToContents() self.q_view_dlg.tblw.resizeColumnsToContents() self.q_view_dlg.diffmode_chk.stateChanged.connect(self.check_branches) if not self.q_view_dlg.exec_(): return rows = set() revision_number_list = [] branches = [] for i in range(len(revs)): if self.q_view_dlg.tblw.item(i,0).checkState(): print "Revision "+ self.q_view_dlg.tblw.item(i,0).text() +" will be fetched" revision_number_list.append(int(self.q_view_dlg.tblw.item(i,0).text())) branches.append(self.q_view_dlg.tblw.item(i,3).text()) rows.add(self.q_view_dlg.tblw.item(i,0).row()) progressMessageBar = self.iface.messageBar().createMessage("Querying " "the database for revision(s) "+str(revision_number_list)) progress = QProgressBar() progress.setMaximum(len(rows)) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) progress.setValue(0) # if diffmode, create one layer with feature differences between the # two revisions; else checkout the full data sets for the specified # revisions and put them in separate layers (original behaviour) rev_begin = 0 rev_end = 0 empty_layers = [] grp_name='' if self.q_view_dlg.diffmode_chk.isChecked(): print "Diffmode checked" # revision_number_list necessarily has only two items in diffmode rev_begin = revision_number_list[0] rev_end = revision_number_list[1] if rev_begin > rev_end: rev_begin, rev_end = rev_end, rev_begin # if the two revisions are not on the same branch, exit if revs[rev_begin - 1][3] != revs[rev_end - 1][3]: print "Revisions are not on the same branch, exiting" #print "Rev_begin " + str(rev_begin) + " is on " + revs[rev_begin - 1][3] #print "Rev_end " + str(rev_end) + " is on " + revs[rev_end - 1][3] return else : print "Revisions are on the same branch" #print "Rev_begin " + str(rev_begin) + " is on " + revs[rev_begin - 1][3] #print "Rev_end " +str(rev_end) + " is on " + revs[rev_end - 1][3] grp_name = "Compare revisions "+str(rev_begin)+" vs "+ str(rev_end) grp_idx = self.iface.legendInterface().addGroup( grp_name ) for i, layer_id in enumerate(reversed(self.current_layers)): progress.setValue(i+1) layer = QgsMapLayerRegistry.instance().mapLayer(layer_id) new_uri = QgsDataSourceURI(layer.source()) select_str = versioning_base.diff_rev_view_str( uri.connectionInfo(), schema, new_uri.table(), branches[0], rev_begin, rev_end ) # change data source uri to point to select sql # schema needs to be set to empty new_uri.setDataSource("", "("+select_str+")", new_uri.geometryColumn(), new_uri.sql(), new_uri.keyColumn()) display_name = QgsMapLayerRegistry.instance().mapLayer(layer_id).name() #print "new_uri.uri() = " + new_uri.uri() tmp_pg_layer = self.iface.addVectorLayer( new_uri.uri(), display_name, 'postgres') #print "Number of features in layer " + display_name + " = " + str(tmp_pg_layer.featureCount()) # if layer has no feature, delete tmp layer and resume for loop if not(tmp_pg_layer.featureCount()): QgsMapLayerRegistry.instance().removeMapLayer( tmp_pg_layer.id() ) empty_layers.append(str(display_name)) continue mem_uri = self.mem_layer_uri(tmp_pg_layer) #print "mem_uri = " + mem_uri if mem_uri == "Unknown": return new_mem_layer = self.iface.addVectorLayer( mem_uri, display_name + '_diff', 'memory') pr = new_mem_layer.dataProvider() source_layer_features = [f for f in tmp_pg_layer.getFeatures()] #print "Got features from source vector layer" QgsMapLayerRegistry.instance().removeMapLayer( tmp_pg_layer.id() ) #print "Removed tmp layer" pr.addFeatures(source_layer_features) #print "Copied source features to mem layer" # Style layer to show features as a function of whether they were # - added/created ('a') # - updated ('u') # - deleted ('d') # For all feature types, so do once # Code from http://snorf.net/blog/2014/03/04/symbology-of-vector-layers-in-qgis-python-plugins # For colors, use the names at http://www.w3schools.com/HTML/html_colornames.asp, but lowercase only; tested with "aliceblue" # define some rules: label, expression, color name, size, (min scale, max scale) modification_type_rules = ( ('Intermediate', '"diff_status" LIKE \'i\'', 'aliceblue', 2.0, None), ('Created', '"diff_status" LIKE \'a\'', 'chartreuse', 3.0, None), ('Updated', '"diff_status" LIKE \'u\'', 'sandybrown', 3.0, None), ('Deleted', '"diff_status" LIKE \'d\'', 'red', 3.0, None),) symbol = QgsSymbolV2.defaultSymbol(new_mem_layer.geometryType()) renderer = QgsRuleBasedRendererV2(symbol) root_rule = renderer.rootRule() for label, expression, color_name, size, scale in modification_type_rules: # create a clone (i.e. a copy) of the default rule rule = root_rule.children()[0].clone() # set the label, expression and color rule.setLabel(label) rule.setFilterExpression(expression) rule.symbol().setColor(QColor(color_name)) ##rule.symbol().setSize(size) # works only for POINT layers # set the scale limits if they have been specified ##if scale is not None: ## rule.setScaleMinDenom(scale[0]) ## rule.setScaleMaxDenom(scale[1]) # append the rule to the list of rules root_rule.appendChild(rule) # delete the default rule root_rule.removeChildAt(0) new_mem_layer.setRendererV2(renderer) # refresh map and legend self.iface.mapCanvas().refresh() self.iface.legendInterface().refreshLayerSymbology(new_mem_layer) self.iface.legendInterface().moveLayer( new_mem_layer, grp_idx) else: print "Diffmode unchecked" for i, row in enumerate(rows): progress.setValue(i+1) branch = revs[row][3] rev = revs[row][0] grp_name = branch+' revision '+str(rev) grp_idx = self.iface.legendInterface().addGroup( grp_name ) for layer_id in reversed(self.current_layers): layer = QgsMapLayerRegistry.instance().mapLayer(layer_id) new_uri = QgsDataSourceURI(layer.source()) select_str, where_str = versioning_base.rev_view_str( self.pg_conn_info(), schema, new_uri.table(), branches[0], rev) new_uri.setSql(where_str) new_uri.setDataSource("", "("+select_str+")", new_uri.geometryColumn(), new_uri.sql(), new_uri.keyColumn()) display_name = QgsMapLayerRegistry.instance().mapLayer(layer_id).name() src = new_uri.uri().replace('()','') new_layer = self.iface.addVectorLayer( src, display_name, 'postgres') self.iface.legendInterface().moveLayer( new_layer, grp_idx) self.iface.messageBar().clearWidgets() #print "len (self.current_layers) = " + str(len (self.current_layers)) #print "len(empty_layers) = " + str(len(empty_layers)) if empty_layers and len(empty_layers) == len (self.current_layers): print "No layers in layer group" self.iface.messageBar().pushMessage("Notice", "No layers will be shown; deleted the \"" +grp_name +"\" layer group", level=QgsMessageBar.WARNING, duration = 15) self.iface.legendInterface().removeGroup(grp_idx) elif empty_layers : print "Empty layers" self.iface.messageBar().pushMessage("Notice", "No modified features between revisions "+str(rev_begin)+" " "and "+str(rev_end)+" for layer(s) "+str(empty_layers)+". ", level=QgsMessageBar.WARNING, duration = 15)
class GroundRadiationMonitoringDockWidget(QtGui.QDockWidget, FORM_CLASS): closingPlugin = pyqtSignal() def __init__(self, parent=None): """Constructor.""" super(GroundRadiationMonitoringDockWidget, 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.settings = QSettings("CTU", "GRMplugin") self.iface = iface # Set filters for QgsMapLayerComboBoxes self.raster_box.setFilters(QgsMapLayerProxyModel.RasterLayer) self.track_box.setFilters(QgsMapLayerProxyModel.LineLayer) self.load_raster.clicked.connect(self.onLoadRaster) self.load_track.clicked.connect(self.onLoadTrack) self.save_button.setEnabled(False) self.report_button.clicked.connect(self.onReportButton) #self.dir_button.clicked.connect(self.onCsvButton) self.shp_button.clicked.connect(self.onShpButton) self.save_button.clicked.connect(self.onExportRasterValues) def closeEvent(self, event): self.closingPlugin.emit() event.accept() def onLoadRaster(self): """Open 'Add raster layer dialog'.""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') fileName = QFileDialog.getOpenFileName( self, self.tr(u'Open raster'), self.tr(u'{}').format(lastUsedFilePath), QgsProviderRegistry.instance().fileRasterFilters()) if fileName: self.iface.addRasterLayer(fileName, QFileInfo(fileName).baseName()) self.settings.setValue(sender, os.path.dirname(fileName)) def onLoadTrack(self): """Open 'Add track layer dialog'.""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') fileName = QFileDialog.getOpenFileName( self, self.tr(u'Open track'), self.tr(u'{}').format(lastUsedFilePath), QgsProviderRegistry.instance().fileVectorFilters()) if fileName: self.iface.addVectorLayer(fileName, QFileInfo(fileName).baseName(), "ogr") self.settings.setValue(sender, os.path.dirname(fileName)) name, fileExtension = os.path.splitext(fileName) if fileExtension not in QgsProviderRegistry.instance( ).fileVectorFilters(): return # TODO: make this work for multiple layer loading if self.iface.activeLayer().geometryType() != QGis.Line: self.sendMessage( u'Info', u'{} does not have lineString type.'.format( QFileInfo(fileName).baseName()), 'INFO') def onReportButton(self): """Get destination of report, csv and shape file. Set path and name for csv and shape file by default as file path for report file. Set default name for report file same as track layer name""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') self.saveReportName = QFileDialog.getSaveFileName( self, self.tr(u'Select destination file'), self.tr(u'{}{}.txt').format(lastUsedFilePath, os.path.sep), filter="TXT (*.txt)") self.saveShpName = self.tr(u'{}.shp').format( self.saveReportName.split('.')[0]) self.report_file.setText(self.tr(u'{}').format(self.saveReportName)) if self.saveReportName: self.shp_file.setText(self.tr(u'{}').format(self.saveShpName)) self.settings.setValue(sender, os.path.dirname(self.saveReportName)) # Enable the saveButton if file is chosen if not self.report_file.text(): self.save_button.setEnabled(False) else: self.save_button.setEnabled(True) def onShpButton(self): """Get destination of shp file.""" sender = u'{}-lastUserFilePath'.format(self.sender().objectName()) lastUsedFilePath = self.settings.value(sender, '') self.saveShpName = QFileDialog.getSaveFileName( self, self.tr(u'Select destination file'), self.tr(u'{}{}.shp').format(lastUsedFilePath, os.path.sep), filter="ESRI Shapefile (*.shp)") self.shp_file.setText(u'{}'.format(self.saveShpName)) if self.saveShpName: self.settings.setValue(sender, os.path.dirname(self.saveShpName)) if not (self.report_file.text() and self.shp_file.text()): self.save_button.setEnabled(False) else: self.save_button.setEnabled(True) def onExportRasterValues(self): """Export sampled raster values to output CSV file. Prints error when user selected length of segment or speed is not positive real number and computation is not performed. When no raster or track vector layer given, than computation is not performed. If shapefile that will be created has the same name as one of the layers in map canvas, that layer will be removed from map layer registry. """ noSamplingFlag = False if not self.vertex_dist.text().strip(): distanceBetweenVertices = 0 noSamplingFlag = True if noSamplingFlag == False: try: distanceBetweenVertices = float( self.vertex_dist.text().replace(',', '.')) except ValueError: self.sendMessage( u'Error', u'"{}" is not a number. (distance between vertices)'. format(self.vertex_dist.text()), 'CRITICAL') return if distanceBetweenVertices <= 0 and noSamplingFlag == False: self.sendMessage( u'Error', u'"{}" is not a positive number. (distance between vertices)'. format(distanceBetweenVertices), 'CRITICAL') return if not self.speed.text(): self.sendMessage(u'Error', u'No speed given.', 'CRITICAL') return try: speed = float(self.speed.text().replace(',', '.')) except ValueError: self.sendMessage( u'Error', u'"{}" is not a number. (speed)'.format(self.speed.text()), 'CRITICAL') return if speed <= 0: self.sendMessage( u'Error', u'"{}" is not a positive number. (speed)'.format(speed), 'CRITICAL') return if not self.raster_box.currentLayer( ) or not self.track_box.currentLayer(): self.sendMessage(u'Error', u'No raster/track layer chosen.', 'CRITICAL') return # remove layers with same name as newly created layer for lyr in QgsMapLayerRegistry.instance().mapLayers().values(): if lyr.source() == self.saveShpName: QgsMapLayerRegistry.instance().removeMapLayer(lyr.id()) self.saveCsvName = None if self.create_csv.isChecked(): self.saveCsvName = self.tr(u'{}.csv').format( self.saveShpName.split('.')[0]) self.computeThread = GroundRadiationMonitoringComputation( self.raster_box.currentLayer().id(), self.track_box.currentLayer().id(), self.saveReportName, self.saveCsvName, self.saveShpName, distanceBetweenVertices, speed, self.unit_box.currentText()) self.saveShpNameOriginal = self.saveShpName self.saveReportNameOriginal = self.saveReportName self.saveCsvNameOriginal = self.saveCsvName self.computeThread.computeEnd.connect(self.addNewLayer) self.computeThread.computeStat.connect(self.setStatus) self.computeThread.computeProgress.connect(self.progressBar) self.computeThread.computeMessage.connect(self.sendMessage) if not self.computeThread.isRunning(): self.computeThread.start() self.save_button.setEnabled(False) def onCancelButton(self): """Show message box with question on canceling. Cancel computation.""" reply = QMessageBox.question( self, u'Ground Radiation Monitoring', u"Cancel computation?{ls}(All created files will be lost.)".format( ls=2 * os.linesep), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) if reply == QMessageBox.Yes: GroundRadiationMonitoringComputation.abortThread( self.computeThread) # kill progress bar if it is still on (if computation is still on) try: self.progress.setParent(None) self.iface.messageBar().popWidget(self.progressMessageBar) except: pass self.cleanCreatedFiles() if not (self.report_file.text() and self.shp_file.text()): self.save_button.setEnabled(False) else: self.save_button.setEnabled(True) def cleanCreatedFiles(self): """Remove created files.""" # remove layers with same name as newly created layer (if is created # and added to map canvas) so shape file could be removed for lyr in QgsMapLayerRegistry.instance().mapLayers().values(): if lyr.source() == self.saveShpNameOriginal: QgsMapLayerRegistry.instance().removeMapLayer(lyr.id()) # remove created files if os.path.isfile(self.saveReportNameOriginal): os.remove(self.saveReportNameOriginal) try: if os.path.isfile(self.saveCsvNameOriginal): os.remove(self.saveCsvNameOriginal) except: pass if os.path.isfile(self.saveShpNameOriginal): os.remove(self.saveShpNameOriginal) if os.path.isfile(self.saveShpNameOriginal.split('.')[0] + '.shx'): os.remove(self.saveShpNameOriginal.split('.')[0] + '.shx') if os.path.isfile(self.saveShpNameOriginal.split('.')[0] + '.dbf'): os.remove(self.saveShpNameOriginal.split('.')[0] + '.dbf') if os.path.isfile(self.saveShpNameOriginal.split('.')[0] + '.prj'): os.remove(self.saveShpNameOriginal.split('.')[0] + '.prj') def progressBar(self): """Initializing progress bar. """ self.progressMessageBar = iface.messageBar().createMessage( u"Ground Radiation Monitoring:", u" Computing...") self.progress = QProgressBar() self.progress.setMaximum(100) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.cancelButton = QtGui.QPushButton() self.cancelButton.setText('Cancel') self.progressMessageBar.layout().addWidget(self.cancelButton) self.progressMessageBar.layout().addWidget(self.progress) msgBar = self.iface.messageBar() msgBar.pushWidget(self.progressMessageBar, iface.messageBar().INFO) #hide x button msgBar.findChildren(QToolButton)[0].setHidden(True) self.cancelButton.clicked.connect(self.onCancelButton) def setStatus(self, num, text): """Update progress status. :num: progress percent """ self.progress.setFormat(text) self.progress.setValue(num) def addNewLayer(self): """End computeThread. Ask to add new layer of computed points to map canvas. """ # Message box reply = QMessageBox.question( self, u'Ground Radiation Monitoring', u"Add new layer to map canvas?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) # add map layer to map canvas if reply == QMessageBox.Yes: newLayer = iface.addVectorLayer( u'{f}'.format(f=self.saveShpNameOriginal), u'{f}'.format( f=QFileInfo(self.saveShpNameOriginal).baseName()), "ogr") self.iface.messageBar().popWidget(self.progressMessageBar) self.save_button.setEnabled(True) def sendMessage(self, caption, message, type): if type == 'CRITICAL': self.iface.messageBar().pushMessage(self.tr(u'{}').format(caption), self.tr(u'{}').format(message), level=QgsMessageBar.CRITICAL, duration=5) elif type == 'INFO': self.iface.messageBar().pushMessage(self.tr(u'{}').format(caption), self.tr(u'{}').format(message), level=QgsMessageBar.INFO, duration=5)
def accept(self): """Event handler for when OK is pressed.""" LOGGER.debug('run the tools') self.get_user_options() if self.site_layer is None: self.show_site_layer_information_message() return if self.parcel_layer is None: self.show_parcel_layer_information_message() return # check if no feature is selected if (not self.layer_has_selection(self.site_layer) and self.selected_sites_only.isChecked()): self.show_no_selection_warning() return if self.output_directory is '' or not os.path.exists( self.output_directory): self.show_output_directory_information_message() return message_bar = self.iface.messageBar().createMessage( self.tr('Download SG Diagram'), self.tr('Please stand by while download process is in progress.'), self.iface.mainWindow()) progress_bar = QProgressBar() progress_bar.setMaximumWidth(150) progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) message_bar.layout().addWidget(progress_bar) self.iface.messageBar().pushWidget( message_bar, self.iface.messageBar().INFO) self.message_bar = message_bar self.save_state() self.close() def progress_callback(current, maximum, message=None): """GUI based callback implementation for showing progress. :param current: Current progress. :type current: int :param maximum: Maximum range (point at which task is complete. :type maximum: int :param message: Optional message to display in the progress bar :type message: str, QString """ if message is not None: message_bar.setText(message) if progress_bar is not None: progress_bar.setMaximum(maximum) progress_bar.setValue(current) report = download_sg_diagrams( self.database_manager, self.site_layer, self.parcel_layer, self.sg_code_field, self.output_directory, self.all_features, callback=progress_callback) # Get rid of the message bar again. self.iface.messageBar().popWidget(message_bar) #QgsMapLayerRegistry.instance().addMapLayers([layer]) self.iface.messageBar().pushMessage( self.tr('Download completed.'), self.tr('Your files are available in %s.' % self.output_directory), level=QgsMessageBar.INFO, duration=10) write_log(report, self.log_file) self.show_log(report, self.log_file)
class SGMapTool(QgsMapTool): """A map tool that lets you click on a parcel to download its SG Diagram. """ def __init__(self, iface, provinces_layer): """Constructor. :param iface: A QGIS QgisInterface instance. :type iface: QgisInterface :param provinces_layer: A layer containing provincial boundaries. :type provinces_layer: QgsVectorLayer """ canvas = iface.mapCanvas() QgsMapTool.__init__(self, canvas) self.canvas = canvas self.iface = iface self.provinces_layer = provinces_layer self.message_bar = None self.progress_bar = None def canvasPressEvent(self, event): """Slot called when a mouse press occurs on the canvas. :param event: Canvas event containing position of click, which button was clicked etc. """ pass def canvasMoveEvent(self, event): """Slot called when a mouse move event occurs on the canvas. :param event: Canvas event containing position of click, which button was clicked etc. """ pass def setup_messagebar(self): """Setup a QgsMessageBar for use from callback and user notifications. """ if self.message_bar is not None: return self.message_bar = self.iface.messageBar().createMessage( self.tr('SG Diagram Downloader'), self.tr('Please stand by while download process is in progress.'), self.iface.mainWindow()) # Set up message bar for progress reporting self.progress_bar = QProgressBar() self.progress_bar.setMaximumWidth(150) self.progress_bar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.message_bar.layout().addWidget(self.progress_bar) self.iface.messageBar().pushWidget( self.message_bar, self.iface.messageBar().INFO) def canvasReleaseEvent(self, event): """Slot called when the mouse button is released on the canvas. :param event: Canvas event containing position of click, which button was clicked etc. """ if not event.button() == Qt.LeftButton: return def progress_callback(current, maximum, message=None): """GUI based callback implementation for showing progress. :param current: Current progress. :type current: int :param maximum: Maximum range (point at which task is complete. :type maximum: int :param message: Optional message to display in the progress bar :type message: str, QString """ if message is not None: self.message_bar.setText(message) if self.progress_bar is not None: self.progress_bar.setMaximum(maximum) self.progress_bar.setValue(current) self.iface.messageBar().pushMessage( self.tr('SG Downloader.'), self.tr('Preparing for download'), level=QgsMessageBar.INFO) # No need to check that it is a valid, polygon layer # as the QAction for this map tool already does that layer = self.canvas.currentLayer() place = self.toMapCoordinates(event.pos()) rectangle = point_to_rectangle(place) request = QgsFeatureRequest(QgsFeatureRequest.FilterRect) # Ensure only those features really intersecting the rect are returned request.setFlags(QgsFeatureRequest.ExactIntersect) request.setFilterRect(rectangle) polygons = layer.getFeatures(request) feature = QgsFeature() fetch_list = [] all_fields = layer.pendingFields() text_fields = [] # Ignore any columns that don't contain text data for field in all_fields: if field.typeName() == 'TEXT': text_fields.append(field) self.setup_messagebar() sg_field = None while polygons.nextFeature(feature): geom = feature.geometry() attributes = feature.attributes() matched = False sg_code = None if sg_field is None: for field in text_fields: value = str(feature[field.name()]) if not is_valid_sg_code(value): continue sg_field = field.name() fetch_list.append(value) else: # We already know which column has SG codes value = str(feature[sg_field]) fetch_list.append(value) if len(fetch_list) == 0: self.iface.messageBar().pushMessage( self.tr('SG Downloader.'), self.tr('No parcels found with a valid 21 Digit code'), level=QgsMessageBar.WARNING, duration=10) return province = province_for_point(place, self.provinces_layer) result = '' output_path = diagram_directory() for sg_code in fetch_list: result += download_sg_diagram( sg_code, province, output_path, progress_callback) log = file('sg_downloader.log', 'a') log.write(result) log.close()
def _launchImport(self): ''' Launch the import ''' if not self._validateMapping(): return self.close() # Progress bar + message progressMessageBar = PagLuxembourg.main.qgis_interface.messageBar( ).createMessage( QCoreApplication.translate('ImportDxfDialog', 'Importing DXF')) progress = QProgressBar() progress.setMaximum(self._getEnabledLayerMappingCount()) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) progress2 = QProgressBar() progress2.setMaximum(self.dxflayer_points.featureCount() + self.dxflayer_linestrings.featureCount() + self.dxflayer_polygons.featureCount()) progress2.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress2) PagLuxembourg.main.qgis_interface.messageBar().pushWidget( progressMessageBar, QgsMessageBar.INFO) # Start import session self._startImportSession() for layer_mapping in self.mapping.layerMappings(): # Skip if not enabled if not layer_mapping.isEnabled(): continue # Progression message progressMessageBar.setText( QCoreApplication.translate( 'ImportDxfDialog', 'Importing {}').format(layer_mapping.sourceLayerName())) # QGIS layer qgis_layer = self._getQgisLayerFromTableName( layer_mapping.destinationLayerName()) layer_indexmapping = layer_mapping.asIndexFieldMappings( qgis_layer.dataProvider().fields()) progress2.setValue(0) # Import features according to geometry type if qgis_layer.geometryType() == QGis.Point: self._importLayer(self.dxflayer_points, qgis_layer, layer_indexmapping, progress2) elif qgis_layer.geometryType() == QGis.Line: self._importLayer(self.dxflayer_linestrings, qgis_layer, layer_indexmapping, progress2) elif qgis_layer.geometryType() == QGis.Polygon: self._importLayer(self.dxflayer_linestrings, qgis_layer, layer_indexmapping, progress2) self._importLayer(self.dxflayer_polygons, qgis_layer, layer_indexmapping, progress2) # Commit import session self._commitImport()
def view(self): """create view and import layers""" layer = QgsMapLayerRegistry.instance().mapLayer( self.current_layers[0] ) uri = QgsDataSourceURI(layer.source()) mtch = re.match(r'(.+)_([^_]+)_rev_(head|\d+)', uri.schema()) schema = mtch.group(1) assert(schema) dlg = QDialog() layout = QVBoxLayout(dlg) button_box = QDialogButtonBox(dlg) button_box.setStandardButtons( QDialogButtonBox.Cancel|QDialogButtonBox.Ok) button_box.accepted.connect(dlg.accept) button_box.rejected.connect(dlg.reject) user_msg1 = QgsMessageBar(dlg) user_msg1.pushInfo("Select:", "one [many] for single [multiple] " "revisions. Fetching may take time.") pcur = versioning_base.Db( psycopg2.connect(self.pg_conn_info()) ) pcur.execute("SELECT rev, commit_msg, branch, date, author " "FROM "+schema+".revisions") revs = pcur.fetchall() pcur.close() tblw = QTableWidget( dlg ) tblw.setRowCount(len(revs)) tblw.setColumnCount(6) tblw.setSortingEnabled(True) tblw.setHorizontalHeaderLabels(['Select','Revision', 'Commit Message', 'Branch', 'Date', 'Author']) tblw.verticalHeader().setVisible(False) for i, rev in enumerate(revs): for j, item in enumerate(rev): chkBoxItem = QTableWidgetItem() chkBoxItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) chkBoxItem.setCheckState(Qt.Unchecked) tblw.setItem(i, 0, chkBoxItem) tblw.setItem(i, j+1, QTableWidgetItem( str(item) )) layout.addWidget( user_msg1 ) layout.addWidget( tblw ) layout.addWidget( button_box ) dlg.resize( 650, 300 ) if not dlg.exec_() : return rows = set() revision_number_list = [] for i in range(len(revs)): if tblw.item(i,0).checkState(): print "Revision "+ str(i + 1) +" will be fetched" revision_number_list.append(i + 1) rows.add(tblw.item(i,0).row()) progressMessageBar = self.iface.messageBar().createMessage("Querying " "the database for revision(s) "+str(revision_number_list)) progress = QProgressBar() progress.setMaximum(len(rows)) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO) progress.setValue(0) for i, row in enumerate(rows): progress.setValue(i+1) branch = revs[row][2] rev = revs[row][0] versioning_base.add_revision_view(uri.connectionInfo(), schema, branch, rev ) grp_name = branch+' revision '+str(rev) grp_idx = self.iface.legendInterface().addGroup( grp_name ) for layer_id in reversed(self.current_layers): layer = QgsMapLayerRegistry.instance().mapLayer(layer_id) new_uri = QgsDataSourceURI(layer.source()) new_uri.setDataSource(schema+'_'+branch+'_rev_'+str(rev), new_uri.table(), new_uri.geometryColumn(), new_uri.sql(), new_uri.keyColumn()) display_name = QgsMapLayerRegistry.instance().mapLayer(layer_id).name() src = new_uri.uri().replace('()','') new_layer = self.iface.addVectorLayer( src, display_name, 'postgres') self.iface.legendInterface().moveLayer( new_layer, grp_idx) self.iface.messageBar().clearWidgets()
class MdbLayer: """ Pretend we are a data provider """ dirty = False doing_attr_update = False def __init__(self, mdb_path, mdb_table, mdb_columns='*', mdb_hide_columns=''): """ Initialize the layer by reading a Access mdb file, creating a memory layer, and adding records to it :param mdb_path: Path to the database you wish to access. :type mdb_path: str :param mdb_table: Table name of the table to open. :type mdb_table: str :param mdb_columns: Comma separated list of columns to use for this layer. Defaults to all (*). :type mdb_columns: str :param mdb_hide_columns: Comma separated list of columns to hide for this layer. Use in combination with mdb_columns='*' :type mdb_hide_columns: str """ self.mdb_path = mdb_path self.mdb_table = mdb_table self.mdb_columns = mdb_columns self.mdb_hide_columns = [ x.strip() for x in mdb_hide_columns.split(",") ] self.record_count = 0 self.progress = object self.old_pk_values = {} self.read_only = READ_ONLY # connect to the database constr = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};DBQ=" + self.mdb_path try: conn = pyodbc.connect(constr, timeout=3) self.cur = conn.cursor() except Exception as e: logger("Couldn't connect. Error: {}".format(e)) return # determine primary key(s) if table table = self.cur.tables(table=self.mdb_table).fetchone() if table.table_type == 'TABLE': self.pk_cols = [ row[8] for row in self.cur.statistics(self.mdb_table) if row[5] == 'PrimaryKey' ] elif table.table_type == 'VIEW': self.pk_cols = [] else: logger("Database object type '{}' not supported".format( table.table_type)) return # get record count try: self.cur.execute("SELECT COUNT(*) FROM {}".format(self.mdb_table)) self.record_count = self.cur.fetchone()[0] except Exception as e: self.iface.messageBar().pushWarning( "MDB Layer", "There's a problem with this table or query. Error: {}".format( e)) return # get records from the table sql = "SELECT {} FROM {}".format(self.mdb_columns, self.mdb_table) self.cur.execute(sql) # create a dictionary with fieldname:type # QgsField only supports: String / Int / Double # falling back to string for: bytearray, bool, datetime.datetime, datetime.date, datetime.time, ? field_name_types = [] field_type_map = { str: QVariant.String, unicode: QVariant.String, int: QVariant.Int, float: QVariant.Double } # create a list with a QgsFields for every db column for column in self.cur.description: if column[0] not in self.mdb_hide_columns: if column[1] in field_type_map: field_name_types.append( QgsField(column[0], field_type_map[column[1]])) else: field_name_types.append( QgsField(column[0], QVariant.String)) self.read_only = True # no reliably editing for other data types # create the layer, add columns self.lyr = QgsVectorLayer("None", 'mdb_' + mdb_table, 'memory') provider = self.lyr.dataProvider() provider.addAttributes(field_name_types) self.lyr.updateFields() # add the records self.add_records() # set read only or make connections/triggers # if there are no primary keys there is no way to edit if self.read_only or not self.pk_cols: self.lyr.setReadOnly() else: self.lyr.beforeCommitChanges.connect(self.before_commit) # add the layer the map QgsMapLayerRegistry.instance().addMapLayer(self.lyr) def add_records(self): """ Add records to the memory layer by stepping through the query result """ self.setup_progressbar( "Loading {} records from table {}...".format( self.record_count, self.lyr.name()), self.record_count) provider = self.lyr.dataProvider() for i, row in enumerate(self.cur): feature = QgsFeature() feature.setGeometry(QgsGeometry()) feature.setAttributes([flds for flds in row]) provider.addFeatures([feature]) self.update_progressbar(i) iface.messageBar().clearWidgets() iface.messageBar().pushMessage("Ready", "{} records added to {}".format( str(self.record_count), self.lyr.name()), level=QgsMessageBar.INFO) def before_commit(self): """" Just before a definitive commit (update to the memory layer) try updating the database""" # fixme: implement rollback on db fail # Update attribute values # --------------------------------------------------------------------- # changes: { fid: {pk1: value, pk2: value, etc}} changes = self.lyr.editBuffer().changedAttributeValues() field_names = [field.name() for field in self.lyr.pendingFields()] row_count = 0 for fid, attributes in changes.iteritems(): feature = self.lyr.dataProvider().getFeatures( QgsFeatureRequest(fid)).next() fields = [field_names[att_id] + " = (?)" for att_id in attributes] params = tuple(attributes.values()) # assemble SQL query where_clause, params = self.get_where_clause(feature, params) sql = "UPDATE {} SET {}".format(self.mdb_table, ", ".join(fields)) sql += where_clause logger(sql + " : " + str(params)) self.cur.execute(sql, params) row_count += self.cur.rowcount self.cur.commit() logger("changed: " + str(row_count)) # Delete features: 'DELETE * FROM spoor WHERE pk = id # --------------------------------------------------------------------- row_count = 0 fids = self.lyr.editBuffer().deletedFeatureIds() for feature in self.lyr.dataProvider().getFeatures( QgsFeatureRequest().setFilterFids(fids)): where_clause, params = self.get_where_clause(feature) # assemble SQL query sql = "DELETE * FROM {}".format(self.mdb_table) sql += where_clause logger(sql + " : " + str(params)) self.cur.execute(sql, params) row_count += self.cur.rowcount self.cur.commit() logger("deleted: " + str(row_count)) # Add features # --------------------------------------------------------------------- # fixme: implement def get_where_clause(self, feature, params=()): """ Return where_clause with pk fields and updated params""" where_clause = [] for pk in self.pk_cols: params += (feature[pk], ) where_clause.append(pk + " = (?)") where_clause = " WHERE " + " AND ".join(where_clause) return where_clause, params def setup_progressbar(self, message, maximum): if not SHOW_PROGRESSBAR: return progress_message_bar = iface.messageBar().createMessage(message) self.progress = QProgressBar() self.progress.setMaximum(maximum) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progress_message_bar.layout().addWidget(self.progress) iface.messageBar().pushWidget(progress_message_bar, iface.messageBar().INFO) def update_progressbar(self, progress): if SHOW_PROGRESSBAR: self.progress.setValue(progress)
class DHttpReplay(QtHelper.EnhancedQDialog, Logger.ClassLogger): """ Http replay dialog """ def __init__(self, parent=None, offlineMode=False): """ Constructor @param parent: @type parent: """ super(DHttpReplay, self).__init__(parent) self.offlineMode = offlineMode self.defaultIp = "127.0.0.1" self.defaultPort = "80" self.newTest = '' self.newTestExec = '' self.newInputs = [] self.requests = [] self.responses = [] self.defaultTemplates = DefaultTemplates.Templates() self.testType = None self.createDialog() self.createConnections() self.createActions() self.createToolbar() def createActions(self): """ Create qt actions """ self.openAction = QtHelper.createAction(self, "&Open", self.importTrace, icon=QIcon(":/folder_add.png"), tip='Open network trace.') self.exportTUAction = QtHelper.createAction( self, "&Test Unit", self.exportToTU, icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE), tip='Export to Test Unit') self.exportTSAction = QtHelper.createAction( self, "&Test Suite", self.exportToTS, icon=QIcon(":/%s.png" % WWorkspace.TestSuite.TYPE), tip='Export to Test Suite') self.cancelAction = QtHelper.createAction(self, "&Cancel", self.reject, tip='Cancel') menu = QMenu(self) menu.addAction(self.exportTUAction) menu.addAction(self.exportTSAction) self.exportToAction = QtHelper.createAction( self, "&Export to", self.exportToTU, icon=QIcon(":/%s.png" % WWorkspace.TestUnit.TYPE), tip='Export to tests') self.exportToAction.setMenu(menu) self.exportToAction.setEnabled(False) def createDialog(self): """ Create dialog """ self.dockToolbar = QToolBar(self) self.dockToolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.setWindowTitle(WINDOW_TITLE) self.resize(500, 400) self.ipEdit = QLineEdit(self.defaultIp) ipRegExpVal = QRegExpValidator(self) ipRegExp = QRegExp("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") ipRegExpVal.setRegExp(ipRegExp) self.ipEdit.setValidator(ipRegExpVal) self.portEdit = QLineEdit(self.defaultPort) self.portEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) validatorPort = QIntValidator(self) self.portEdit.setValidator(validatorPort) self.progressBar = QProgressBar(self) self.progressBar.setMaximum(100) self.progressBar.setProperty("value", 0) self.progressBar.setAlignment(Qt.AlignCenter) self.progressBar.setObjectName("progressBar") self.guiSikuliGroupBox = QGroupBox("") self.guiSikuliGroupBox.setFlat(True) self.automaticAdp = QRadioButton("Automatic") self.automaticAdp.setChecked(True) self.defaultAdp = QRadioButton("Default") self.genericAdp = QRadioButton("Generic") vbox = QHBoxLayout() vbox.addWidget(self.automaticAdp) vbox.addWidget(self.defaultAdp) vbox.addWidget(self.genericAdp) vbox.addStretch(1) self.guiSikuliGroupBox.setLayout(vbox) layout = QVBoxLayout() layout.addWidget(self.dockToolbar) layout.addSpacing(12) paramLayout = QGridLayout() paramLayout.addWidget(QLabel("Destination IP:"), 0, 0, Qt.AlignRight) paramLayout.addWidget(self.ipEdit, 0, 1) paramLayout.addWidget(QLabel("Destination Port:"), 1, 0, Qt.AlignRight) paramLayout.addWidget(self.portEdit, 1, 1) paramLayout.addWidget(QLabel(self.tr("Gui adapter selector:")), 2, 0, Qt.AlignRight) paramLayout.addWidget(self.guiSikuliGroupBox, 2, 1) layout.addLayout(paramLayout) self.logsEdit = QTextEdit() self.logsEdit.setReadOnly(True) self.logsEdit.setTextInteractionFlags(Qt.NoTextInteraction) layout.addSpacing(12) layout.addWidget(self.logsEdit) layout.addSpacing(12) layout.addWidget(self.progressBar) self.setLayout(layout) def createToolbar(self): """ Create toolbar """ self.dockToolbar.setObjectName("File toolbar") self.dockToolbar.addAction(self.openAction) self.dockToolbar.addSeparator() self.dockToolbar.addAction(self.exportToAction) self.dockToolbar.addSeparator() self.dockToolbar.setIconSize(QSize(16, 16)) def createConnections(self): """ Create qt connections """ pass def autoScrollOnTextEdit(self): """ Automatic scroll on text edit """ cursor = self.logsEdit.textCursor() cursor.movePosition(QTextCursor.End) self.logsEdit.setTextCursor(cursor) def strip_html(self, txt): """ Strip html """ if "<" in txt: txt = txt.replace('<', '<') if ">" in txt: txt = txt.replace('>', '>') return txt def addLogSuccess(self, txt): """ Add log success in the text edit """ self.logsEdit.insertHtml( "<span style='color:darkgreen'>%s</span><br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def addLogWarning(self, txt): """ Add log warning in the text edit """ self.logsEdit.insertHtml( "<span style='color:darkorange'>%s</span><br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def addLogError(self, txt): """ Add log error in the text edit """ self.logsEdit.insertHtml("<span style='color:red'>%s</span><br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def addLog(self, txt): """ Append log to the logsEdit widget """ self.logsEdit.insertHtml("%s<br />" % unicode(self.strip_html(txt))) self.autoScrollOnTextEdit() def importTrace(self): """ Import network trace """ self.logsEdit.clear() self.testType = None if not self.offlineMode: if not RCI.instance().isAuthenticated(): self.addLogWarning( txt="<< Connect to the test center in first!") QMessageBox.warning(self, "Import", "Connect to the test center in first!") return self.exportToAction.setEnabled(False) self.newTest = '' self.progressBar.setMaximum(100) self.progressBar.setValue(0) if sys.version_info > (3, ): fileName = QFileDialog.getOpenFileName( self, self.tr("Open File"), "", "Network dump (*.cap;*.pcap;*.pcapng)") else: fileName = QFileDialog.getOpenFileName(self, self.tr("Open File"), "", "Network dump (*.cap)") # new in v18 to support qt5 if QtHelper.IS_QT5: _fileName, _type = fileName else: _fileName = fileName # end of new if not _fileName: return if sys.version_info < (3, ): extension = str(_fileName).rsplit(".", 1)[1] if not (extension == "cap"): self.addLogError(txt="<< File not supported %s" % _fileName) QMessageBox.critical(self, "Open", "File not supported") return _fileName = str(_fileName) capName = _fileName.rsplit("/", 1)[1] self.addLogSuccess(txt=">> Reading the file %s" % _fileName) if sys.version_info > (3, ): self.readFileV2(fileName=_fileName) else: self.readFile(fileName=_fileName) def exportToTS(self): """ Export to test suite """ self.testType = TS self.exportToTest(TS=True, TU=False) def exportToTU(self): """ Export to test unit """ self.testType = TU self.exportToTest(TS=False, TU=True) def searchHTTP(self): """ Search HTTP module in assistant """ # modules accessor ret = "SutAdapters" if self.automaticAdp.isChecked(): isGeneric = WWorkspace.Helper.instance().isGuiGeneric(name="GUI") if isGeneric: ret = "SutAdapters.Generic" elif self.defaultAdp.isChecked(): return ret elif self.genericAdp.isChecked(): ret = "SutAdapters.Generic" else: pass return ret def exportToTest(self, TS=True, TU=False): """ Export to test """ if not RCI.instance().isAuthenticated(): self.addLogWarning(txt="<< Connect to the test center in first!") QMessageBox.warning(self, "Import", "Connect to the test center in first!") return if TS: self.newTest = self.defaultTemplates.getTestDefinitionAuto() self.newTestExec = self.defaultTemplates.getTestExecutionAuto() if TU: self.newTest = self.defaultTemplates.getTestUnitDefinitionAuto() destIp = str(self.ipEdit.text()) destPort = str(self.portEdit.text()) self.newInputs = [] self.newInputs.append({ 'type': 'self-ip', 'name': 'BIND_IP', 'description': '', 'value': '0.0.0.0', 'color': '' }) self.newInputs.append({ 'type': 'int', 'name': 'BIND_PORT', 'description': '', 'value': '0', 'color': '' }) self.newInputs.append({ 'type': 'str', 'name': 'DEST_IP', 'description': '', 'value': '%s' % destIp, 'color': '' }) self.newInputs.append({ 'type': 'int', 'name': 'DEST_PORT', 'description': '', 'value': '%s' % destPort, 'color': '' }) self.newInputs.append({ 'type': 'bool', 'name': 'DEBUG', 'description': '', 'value': 'False', 'color': '' }) self.newInputs.append({ 'type': 'float', 'name': 'TIMEOUT', 'description': '', 'value': '5.0', 'color': '' }) adps = """self.ADP_HTTP = %s.HTTP.Client(parent=self, bindIp=input('BIND_IP'), bindPort=input('BIND_PORT'), destinationIp=input('DEST_IP'), destinationPort=input('DEST_PORT'), debug=input('DEBUG'))""" % self.searchHTTP( ) # prepare steps steps = [] j = 0 for i in xrange(len(self.requests)): j = i + 1 if sys.version_info > (3, ): # python3 support (source, dest, source_port, dest_port, buf_req, reqDecoded) = self.requests[i] http_method = str(reqDecoded['method'], 'utf8') http_status = 'no' http_reason = '' else: http_method = self.requests[i]['tcp-object'].method http_status = 'no' http_reason = '' try: if sys.version_info > (3, ): # python3 support (sourceRsp, destRsp, sourcePortRsp, destPortRsp, bufReqRsp, reqDecodedRsp) = self.responses[i] http_status = str(reqDecodedRsp['code']) http_reason = str(reqDecodedRsp['phrase'], 'utf8') else: http_status = self.responses[i]['tcp-object'].status http_reason = self.responses[i]['tcp-object'].reason except Exception as e: print(e) steps.append( 'self.step%s = self.addStep(expected="%s %s response", description="send %s request", summary="send %s request")' % (j, http_status, http_reason, http_method, http_method)) tests = [] for i in xrange(len(self.requests)): j = i + 1 if sys.version_info > (3, ): # python3 support (source, dest, source_port, dest_port, buf_req, reqDecoded) = self.requests[i] tests.append("# request %s" % j) tests.append('self.step%s.start()' % j) if sys.version_info > (3, ): # python3 support lines_req = buf_req.splitlines() else: lines_req = self.requests[i]['tcp-data'].splitlines() if sys.version_info > (3, ): # python3 support tests.append('rawHttp = [%s]' % lines_req[0].replace(b'"', b'\\"')) else: tests.append('rawHttp = ["%s"]' % lines_req[0].replace(b'"', b'\\"')) for lreq in lines_req[1:]: if sys.version_info > (3, ): # python3 support tests.append('rawHttp.append(%s)' % lreq.replace(b'"', b'\\"')) else: tests.append('rawHttp.append("%s")' % lreq.replace(b'"', b'\\"')) tests.append('') tests.append( 'req_tpl = self.ADP_HTTP.constructTemplateRequest(rawHttp=rawHttp)' ) tests.append('req = self.ADP_HTTP.sendRequest(tpl=req_tpl)') try: tests.append('') if sys.version_info > (3, ): # python3 support (sourceRsp, destRsp, sourcePortRsp, destPortRsp, bufReqRsp, reqDecodedRsp) = self.responses[i] lines_res = bufReqRsp.splitlines() else: lines_res = self.responses[i]['tcp-data'].splitlines() if sys.version_info > (3, ): # python3 support tests.append('rawHttpRsp = [%s]' % lines_res[0].replace(b"'", b"\\'")) else: tests.append('rawHttpRsp = ["%s"]' % lines_res[0].replace(b'"', b'\\"')) for lres in lines_res[1:]: if sys.version_info > (3, ): # python3 support tests.append('rawHttpRsp.append(%s)' % lres.replace(b"'", b"\\'")) else: tests.append('rawHttpRsp.append("%s")' % lres.replace(b'"', b'\\"')) except Exception as e: self.error("unable to append response: %s" % e) tests.append( 'rsp_tpl = self.ADP_HTTP.constructTemplateResponse(rawHttp=rawHttpRsp)' ) tests.append( "rsp = self.ADP_HTTP.hasReceivedResponse(expected=rsp_tpl, timeout=input('TIMEOUT'))" ) tests.append('if rsp is None:') tests.append( '\tself.step%s.setFailed(actual="incorrect response")' % j) tests.append('else:') tests.append('\tself.step%s.setPassed(actual="ok")' % j) tests.append('') if TS: init = """self.ADP_HTTP.connect() connected = self.ADP_HTTP.isConnected( timeout=input('TIMEOUT') ) if not connected: self.abort( 'unable to connect to the tcp port %s' ) """ % str(self.portEdit.text()) if TU: init = """self.ADP_HTTP.connect() connected = self.ADP_HTTP.isConnected( timeout=input('TIMEOUT') ) if not connected: self.abort( 'unable to connect to the tcp port %s' ) """ % str(self.portEdit.text()) if TS: cleanup = """self.ADP_HTTP.disconnect() disconnected = self.ADP_HTTP.isDisconnected( timeout=input('TIMEOUT') ) if not disconnected: self.error( 'unable to disconnect from the tcp port %s' ) """ % str(self.portEdit.text()) if TU: cleanup = """self.ADP_HTTP.disconnect() disconnected = self.ADP_HTTP.isDisconnected( timeout=input('TIMEOUT') ) if not disconnected: self.error( 'unable to disconnect from the tcp port %s' ) """ % str(self.portEdit.text()) self.newTest = self.newTest.replace( "<<PURPOSE>>", 'self.setPurpose(purpose="Replay HTTP")') self.newTest = self.newTest.replace("<<ADPS>>", adps) if TS: self.newTest = self.newTest.replace("<<STEPS>>", '\n\t\t'.join(steps)) if TU: self.newTest = self.newTest.replace("<<STEPS>>", '\n\t'.join(steps)) self.newTest = self.newTest.replace("<<INIT>>", init) self.newTest = self.newTest.replace("<<CLEANUP>>", cleanup) if TS: self.newTest = self.newTest.replace("<<TESTS>>", '\n\t\t'.join(tests)) if TU: self.newTest = self.newTest.replace("<<TESTS>>", '\n\t'.join(tests)) self.accept() def decodeHttpRequest(self, data): """ Decode http request Content chunked not yet implemented """ http = {"type": "request"} lines = data.splitlines() try: request_line = lines[0] except Exception: self.error("unable to decode http request: %s" % lines) return None try: http["method"] = request_line.split(b" ", 2)[0] http["uri"] = request_line.split(b" ", 2)[1] http["version"] = request_line.split(b" ", )[2] except Exception: self.error( "unable to decode status code in the http response: %s" % request_line) return None http["body"] = data.split(b"\r\n\r\n")[1] headers = [] contentLenght = 0 contentChunked = False for hdr in data.split(b"\r\n\r\n")[0].splitlines()[1:]: if len(hdr): k, v = hdr.split(b":", 1) if k.lower() == b"content-length": contentLenght = int(v) if k.lower() == b"transfer-encoding": if v.lowert() == b"chunked": contentChunked = True headers.append(hdr) http["headers"] = headers if len(http["body"]) != contentLenght: return None # need more data return http def decodeHttpResponse(self, data): """ Decode http response without body """ http = {"type": "response"} lines = data.splitlines() try: status_line = lines[0] except Exception: self.error("unable to decode http response: %s" % lines) return None try: http["code"] = int(status_line.split(b" ")[1]) http["phrase"] = status_line.split(b" ", 2)[2] except Exception: self.error( "unable to decode status code in the http response: %s" % status_line) return None http["headers"] = lines[1:] return http def readFileV2(self, fileName): """ Read pcap file Support pcap-ng too """ fd = open(fileName, 'rb') fileFormat, fileHead = PcapParse.extractFormat(fd) if fileFormat == PcapParse.FileFormat.PCAP: self.trace("pcap file detected") pcapFile = PcapReader.PcapFile(fd, fileHead).read_packet self.readFilePacket(pcapFile=pcapFile) elif fileFormat == PcapParse.FileFormat.PCAP_NG: self.trace("pcap-png file detected") pcapFile = PcapngReader.PcapngFile(fd, fileHead).read_packet self.readFilePacket(pcapFile=pcapFile) else: self.addLogError(txt="<< Error to open the network trace") self.error('unable to open the network trace: file format = %s' % fileFormat) QMessageBox.critical(self, "Import", "File not supported") def __readRequest(self, buffer, data, request, output): """ Read request """ buffer += data if b'\r\n\r\n' in data: reqDecoded = self.decodeHttpRequest(data=buffer) if reqDecoded is not None: output.append(request + (reqDecoded, )) buffer = b'' else: print("need more data: decode request failed") else: print("need more data, no body separator detected on request") def readFilePacket(self, pcapFile): """ Read file packet by packet """ ip_expected = str(self.ipEdit.text()) port_expected = int(self.portEdit.text()) # read packet) packets = pcapFile() ethernetPackets = list(packets) self.addLogSuccess(txt="<< Number of packets detected: %s " % len(ethernetPackets)) # extract tcp packet according to the expected ip and port tcpPacketsSent = [] tcpPacketsRecv = [] i = 1 self.progressBar.setMaximum(len(ethernetPackets)) self.progressBar.setValue(0) for pkt in ethernetPackets: self.progressBar.setValue(i) i += 1 pktDecoded = PcapParse.decodePacket(pkt, getTcp=True, getUdp=False) if pktDecoded is not None: (source, dest, source_port, dest_port, data) = pktDecoded # skip when no data exists if dest == ip_expected and int(dest_port) == int( port_expected) and len(data) > 0: tcpPacketsSent.append(pktDecoded) if source == ip_expected and int(source_port) == int( port_expected) and len(data) > 0: tcpPacketsRecv.append(pktDecoded) self.addLogSuccess(txt="<< Number of TCP packets sent: %s " % len(tcpPacketsSent)) self.addLogSuccess(txt="<< Number of TCP packets received: %s " % len(tcpPacketsRecv)) # decode https requests self.requests = [] buf_req = b'' i = 1 self.progressBar.setMaximum(len(tcpPacketsSent)) self.progressBar.setValue(0) # decode the complete packet for req in tcpPacketsSent: self.progressBar.setValue(i) i += 1 (source, dest, source_port, dest_port, data) = req if buf_req: buf_req += data if b'\r\n\r\n' in data: reqDecoded = self.decodeHttpRequest(data=buf_req) if reqDecoded is not None: self.requests.append((source, dest, source_port, dest_port, buf_req, reqDecoded)) buf_req = b'' else: if isRequest(data): buf_req += data if b'\r\n\r\n' in data: reqDecoded = self.decodeHttpRequest(data=buf_req) if reqDecoded is not None: self.requests.append( (source, dest, source_port, dest_port, buf_req, reqDecoded)) buf_req = b'' self.addLogSuccess(txt="<< Number of HTTP requests extracted: %s " % len(self.requests)) # decode https response self.responses = [] buf_rsp = b'' i = 1 self.progressBar.setMaximum(len(tcpPacketsRecv)) self.progressBar.setValue(0) # decode just headers for response for req in tcpPacketsRecv: self.progressBar.setValue(i) i += 1 (source, dest, source_port, dest_port, data) = req if buf_rsp: buf_rsp += data # try to decode response without body if b'\r\n\r\n' in data: rspDecoded = self.decodeHttpResponse(data=buf_rsp) if rspDecoded is not None: self.responses.append((source, dest, source_port, dest_port, buf_rsp, rspDecoded)) buf_rsp = b'' else: # is http response ? if data.startswith(b'HTTP/'): buf_rsp += data if b'\r\n\r\n' in data: rspDecoded = self.decodeHttpResponse(data=buf_rsp) if rspDecoded is not None: self.responses.append( (source, dest, source_port, dest_port, buf_rsp, rspDecoded)) buf_rsp = b'' self.addLogSuccess(txt="<< Number of HTTP responses extracted: %s " % len(self.responses)) if self.requests: self.addLogSuccess("<< Read the file finished with success!") self.addLogWarning( "<< Click on the export button to generate the test!") self.exportToAction.setEnabled(True) else: self.addLogWarning("<< No http extracted!") def readFile(self, fileName): """ Read the file passed as argument Old function with dtpkt and python2.7 """ self.requests = [] self.responses = [] ip_expected = socket.inet_aton(str(self.ipEdit.text())) port_expected = str(self.portEdit.text()) try: f = open(fileName, 'rb') pcap = dpkt.pcap.Reader(f) tot_pkts = len(list(pcap)) except Exception as e: self.addLogError(txt="<< Error to open the network trace") self.error('unable to open the network trace: %s' % str(e)) QMessageBox.critical(self, "Import", "File not supported") return else: self.addLogSuccess(txt="<< Total packets detected: %s " % tot_pkts) self.progressBar.setMaximum(tot_pkts) # decode http request i = 1 buf_req = '' for ts, buf in pcap: self.progressBar.setValue(i) i += 1 # read ethernet layer eth = dpkt.ethernet.Ethernet(buf) if eth.type == dpkt.ethernet.ETH_TYPE_IP: # continue with ip decoding layer ip = eth.data if ip.dst == ip_expected: ip_layer = (ip.src, ip.dst) if ip.p == dpkt.ip.IP_PROTO_TCP: tcp = ip.data if tcp.dport == int(port_expected) and len( tcp.data) > 0: tcp_layer = (tcp.sport, tcp.dport) buf_req += tcp.data try: http_req = dpkt.http.Request(buf_req) except dpkt.dpkt.NeedData as e: pass except dpkt.UnpackError as e: pass else: self.requests.append({ 'ip-src': ip.src, 'ip-dst': ip.dst, 'port-src': tcp.sport, 'port-dst': tcp.dport, 'tcp-data': buf_req, 'tcp-object': http_req }) self.addLogWarning( txt="<< %s http request(s) extracted" % len(self.requests)) buf_req = '' # decode http responses i = 1 self.progressBar.setValue(0) for ts, buf in pcap: self.progressBar.setValue(i) i += 1 # read ethernet layer eth = dpkt.ethernet.Ethernet(buf) if eth.type == dpkt.ethernet.ETH_TYPE_IP: # continue with ip decoding layer ip = eth.data if ip.src == ip_expected: ip_layer = (ip.src, ip.dst) if ip.p == dpkt.ip.IP_PROTO_TCP: tcp = ip.data if tcp.sport == int(port_expected) and len( tcp.data) > 0: tcp_layer = (tcp.sport, tcp.dport) if (tcp.data).startswith('HTTP/'): try: new_res = "%s\r\n\r\n" % ( tcp.data).splitlines()[0] http_res = dpkt.http.Response(new_res) except dpkt.dpkt.NeedData as e: pass except dpkt.UnpackError as e: pass else: self.responses.append({ 'ip-src': ip.src, 'ip-dst': ip.dst, 'port-src': tcp.sport, 'port-dst': tcp.dport, 'tcp-data': new_res, 'tcp-object': http_res }) self.addLogWarning( txt= "<< %s http response(s) extracted" % len(self.responses)) if self.requests: self.addLogSuccess("<< File decoded with success!") self.addLogWarning( "<< Click on the export button to generate the test!") self.exportToAction.setEnabled(True) else: self.addLogWarning("<< No http extracted!")
class communications: def __init__(self, iface, progress, progressMessageBar, plugin_name): self.iface = iface self.progress = progress self.progressMessageBar = progressMessageBar self.plugin_name = plugin_name # Afficher un message à l'utilisateur def show_message(self, level, message): self.write_qgis_logs(level, message) # Si c'est level info, ne l'afficher que dans le status bar if (level == "info"): self.show_message_statusBar(message) # Si c'est level warning ou plus, afficher dans la Message bar if (level == "warning"): self.show_message_messageBar(level, "[WARNING] " + message) if (level == "critical"): self.show_message_messageBar(level, "[ERREUR] " + message) # Afficher un message dans la "Status Bar" def show_message_statusBar(self, message): self.iface.mainWindow().statusBar().showMessage(message) # Afficher un message dans le "Message Bar" def show_message_messageBar(self, level, message): if (level == "warning"): self.warning_message_bar(message) self.clear_message_bar_delay() if (level == "critical"): self.critical_message_bar(message) self.clear_message_bar_delay() # Si c'est un message "warning" def warning_message_bar(self, message): self.progressMessageBar = self.iface.messageBar().createMessage( message) self.progress = QProgressBar() self.progress.setMaximum(19) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) self.iface.messageBar().pushWidget(self.progressMessageBar, self.iface.messageBar().WARNING) # Si c'est un message "critique" ! def critical_message_bar(self, message): self.progressMessageBar = self.iface.messageBar().createMessage( message) self.progress = QProgressBar() self.progress.setMaximum(19) self.progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.progressMessageBar.layout().addWidget(self.progress) self.iface.messageBar().pushWidget(self.progressMessageBar, self.iface.messageBar().CRITICAL) # Délais avant d'effacer la Message Bar def clear_message_bar_delay(self): # Attendre 8 secondes avant d'effacer le contenu de la Status Bar et d'enlever la Message Bar self.timer = QTimer() self.timer.setInterval(8000) # 1000 ms = 1 secondes self.timer.setSingleShot(True) # Quand le timer fini, appeller la fonction pour effacer self.timer.timeout.connect(self.clear_message_bar) self.timer.start() # Suppression de la Message Bar et du Status Bar def clear_message_bar(self): self.iface.messageBar().clearWidgets() self.iface.mainWindow().statusBar().clearMessage() # Écriture des logs de QGIS def write_qgis_logs(self, level, message): if (level == "info"): QgsMessageLog.logMessage(message, self.plugin_name, level=QgsMessageLog.INFO) if (level == "warning"): QgsMessageLog.logMessage(message, self.plugin_name, level=QgsMessageLog.WARNING) if (level == "critical"): QgsMessageLog.logMessage(message, self.plugin_name, level=QgsMessageLog.CRITICAL)
class MessageBoxDialog(QDialog): """ Message box dialog """ Download = pyqtSignal(str) DownloadCanceled = pyqtSignal() def __init__(self, dialogName, parent = None): """ Constructor @param dialogName: @type dialogName: @param parent: @type parent: """ QDialog.__init__(self, parent) self.setWindowIcon( QIcon(":/main.png") ) self.name = dialogName self.url = None self.createDialog() def closeEvent(self, event): """ On close event @param event: @type event: """ pass def setDownload(self, title, txt, url, cancelButton=True): """ Set as download @param title: @type title: @param txt: @type txt: @param url: @type url: """ self.setWindowFlags(Qt.Drawer | Qt.CustomizeWindowHint) self.url = url self.setWindowTitle( title ) self.progressBar.hide() self.imageLabel.setPixmap(QPixmap(':/information.png')) self.loadingLabel.setText( txt ) self.downloadButton.show() if cancelButton: self.cancelButton.show() else: self.cancelButton.hide() self.okButton.hide() self.imageLabel.show() def setTxt (self, title, txt, error=False): """ Set text @param title: @type title: @param txt: @type txt: """ self.setWindowTitle( title ) self.progressBar.hide() self.loadingLabel.setText( txt ) self.imageLabel.show() if error: self.imageLabel.setPixmap(QPixmap(':/warning.png')) else: self.imageLabel.setPixmap(QPixmap(':/information.png')) self.okButton.show() self.downloadButton.hide() self.cancelButton.hide() def setLoading (self, msg='Loading data...' ): """ Set as loading @param msg: @type msg: """ self.setWindowTitle( "%s" % self.name ) self.progressBar.setMaximum(0) self.progressBar.setProperty("value", 0) self.progressBar.show() self.loadingLabel.setText( msg ) self.loadingLabel.show() self.okButton.hide() self.downloadButton.hide() self.cancelButton.hide() self.imageLabel.hide() def setConnection (self ): """ Set text with connection """ self.loadingLabel.setText( "Connection..." ) def setInitialization (self ): """ Set text with initialization """ self.loadingLabel.setText( "Initialization..." ) self.show() def download (self): """ Emit download signal """ self.Download.emit(self.url) self.accept() def onReject(self): """ Called on cancel """ self.DownloadCanceled.emit() self.reject() def updateDataReadProgress(self, bytesRead, totalBytes): """ Update the progress bar @param bytesRead: @type bytesRead: @param totalBytes: @type totalBytes: """ self.progressBar.setMaximum(totalBytes) self.progressBar.setValue(bytesRead) def createDialog(self): """ Create qt dialog """ self.setWindowTitle( "%s" % self.name ) layout = QVBoxLayout() self.loadingLabel = QLabel("Loading...") self.imageLabel = QLabel() layout2 = QHBoxLayout() layout2.addWidget( self.imageLabel ) layout2.addWidget( self.loadingLabel ) self.progressBar = QProgressBar(self) self.progressBar.setMaximum(0) self.progressBar.setProperty("value", 0) self.progressBar.setAlignment(Qt.AlignCenter) self.progressBar.setObjectName("progressBar") buttonLayout = QHBoxLayout() buttonLayout.addStretch() self.okButton = QPushButton("Ok", self) self.downloadButton = QPushButton("Download", self) self.cancelButton = QPushButton("Cancel", self) buttonLayout.addWidget(self.okButton) buttonLayout.addWidget(self.downloadButton) buttonLayout.addWidget(self.cancelButton) self.okButton.clicked.connect(self.accept) self.downloadButton.clicked.connect(self.download) self.cancelButton.clicked.connect(self.onReject) self.okButton.hide() layout.addLayout(layout2) layout.addWidget( self.progressBar ) layout.addLayout(buttonLayout) self.setLayout(layout) flags = Qt.WindowFlags() flags |= Qt.WindowCloseButtonHint flags |= Qt.MSWindowsFixedSizeDialogHint self.setWindowFlags(flags)
if not oLayer: gErrorMsg = u"레이어를 먼저 선택해야 합니다." raise UserWarning # 종료 layerName = oLayer.name() layerType = oLayer.geometryType() crs = oLayer.crs() # ID 리스트 확보 oIDs = oLayer.allFeatureIds() # Progress 생성 progressMessageBar = iface.messageBar().createMessage(u"자료 정보 수집중...") progress = QProgressBar() progress.setMaximum(len(oIDs)) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, iface.messageBar().INFO) # centroid 모으기 centroidList = [] for i, oID in enumerate(oIDs): progress.setValue(i) iFeature = oLayer.getFeatures(QgsFeatureRequest(oID)).next() iGeom = iFeature.geometry().centroid() centroidList.append(iGeom) # Progress 제거 iface.messageBar().clearWidgets()