def read(self, size): content = self.content self.content = "" # content = string while the input parameter size in QByteArray data = QByteArray(content) data.chop(data.size() - size) return str(data)
def writeTile(self, tile, image): if tile.z != self._zoom: self._initZoomLayer(tile.z) data = QByteArray() buff = QBuffer(data) image.save(buff, 'PNG') mmap_name = '/vsimem/' + uuid4().hex gdal.FileFromMemBuffer(mmap_name, data.data()) gdal_dataset = gdal.Open(mmap_name) data = gdal_dataset.ReadRaster(0, 0, self.tile_width, self.tile_height) gdal_dataset = None gdal.Unlink(mmap_name) xoff = (tile.x - self._first_tile.x) * self.tile_width yoff = (tile.y - self._first_tile.y) * self.tile_height self._zoomDs.WriteRaster(xoff, yoff, self.tile_width, self.tile_height, data)
def size(self): data = QByteArray(self.content) return data.size()
def data(self) -> QByteArray: """ Return post/put data a QByteArray """ # Make sure that data is valid return QByteArray(self._data) if self._data else QByteArray()
def xmlDownloaded(self): """ populate the plugins object with the fetched data """ reply = self.sender() reposName = reply.property('reposName') if reply.error() != QNetworkReply.NoError: # fetching failed self.mRepositories[reposName]["state"] = 3 self.mRepositories[reposName]["error"] = reply.errorString() if reply.error() == QNetworkReply.OperationCanceledError: self.mRepositories[reposName][ "error"] += "\n\n" + QCoreApplication.translate( "QgsPluginInstaller", "If you haven't cancelled the download manually, it was most likely caused by a timeout. In this case consider increasing the connection timeout value in QGIS options window." ) else: reposXML = QDomDocument() content = reply.readAll() # Fix lonely ampersands in metadata a = QByteArray() a.append("& ") b = QByteArray() b.append("& ") content = content.replace(a, b) reposXML.setContent(content) pluginNodes = reposXML.elementsByTagName("pyqgis_plugin") if pluginNodes.size(): for i in range(pluginNodes.size()): fileName = pluginNodes.item(i).firstChildElement( "file_name").text().strip() if not fileName: fileName = QFileInfo( pluginNodes.item(i).firstChildElement( "download_url").text().strip().split("?") [0]).fileName() name = fileName.partition(".")[0] experimental = False if pluginNodes.item(i).firstChildElement( "experimental").text().strip().upper() in [ "TRUE", "YES" ]: experimental = True deprecated = False if pluginNodes.item(i).firstChildElement( "deprecated").text().strip().upper() in [ "TRUE", "YES" ]: deprecated = True trusted = False if pluginNodes.item(i).firstChildElement( "trusted").text().strip().upper() in [ "TRUE", "YES" ]: trusted = True icon = pluginNodes.item(i).firstChildElement( "icon").text().strip() if icon and not icon.startswith("http"): icon = "http://%s/%s" % (QUrl( self.mRepositories[reposName]["url"]).host(), icon) if pluginNodes.item(i).toElement().hasAttribute( "plugin_id"): plugin_id = pluginNodes.item(i).toElement().attribute( "plugin_id") else: plugin_id = None plugin = { "id": name, "plugin_id": plugin_id, "name": pluginNodes.item(i).toElement().attribute("name"), "version_available": pluginNodes.item(i).toElement().attribute("version"), "description": pluginNodes.item(i).firstChildElement( "description").text().strip(), "about": pluginNodes.item(i).firstChildElement( "about").text().strip(), "author_name": pluginNodes.item(i).firstChildElement( "author_name").text().strip(), "homepage": pluginNodes.item(i).firstChildElement( "homepage").text().strip(), "download_url": pluginNodes.item(i).firstChildElement( "download_url").text().strip(), "category": pluginNodes.item(i).firstChildElement( "category").text().strip(), "tags": pluginNodes.item(i).firstChildElement( "tags").text().strip(), "changelog": pluginNodes.item(i).firstChildElement( "changelog").text().strip(), "author_email": pluginNodes.item(i).firstChildElement( "author_email").text().strip(), "tracker": pluginNodes.item(i).firstChildElement( "tracker").text().strip(), "code_repository": pluginNodes.item(i).firstChildElement( "repository").text().strip(), "downloads": pluginNodes.item(i).firstChildElement( "downloads").text().strip(), "average_vote": pluginNodes.item(i).firstChildElement( "average_vote").text().strip(), "rating_votes": pluginNodes.item(i).firstChildElement( "rating_votes").text().strip(), "icon": icon, "experimental": experimental, "deprecated": deprecated, "trusted": trusted, "filename": fileName, "installed": False, "available": True, "status": "not installed", "error": "", "error_details": "", "version_installed": "", "zip_repository": reposName, "library": "", "readonly": False } qgisMinimumVersion = pluginNodes.item(i).firstChildElement( "qgis_minimum_version").text().strip() if not qgisMinimumVersion: qgisMinimumVersion = "2" qgisMaximumVersion = pluginNodes.item(i).firstChildElement( "qgis_maximum_version").text().strip() if not qgisMaximumVersion: qgisMaximumVersion = qgisMinimumVersion[0] + ".99" #if compatible, add the plugin to the list if not pluginNodes.item(i).firstChildElement( "disabled").text().strip().upper() in [ "TRUE", "YES" ]: if isCompatible(Qgis.QGIS_VERSION, qgisMinimumVersion, qgisMaximumVersion): #add the plugin to the cache plugins.addFromRepository(plugin) self.mRepositories[reposName]["state"] = 2 else: # no plugin metadata found self.mRepositories[reposName]["state"] = 3 if reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) == 200: self.mRepositories[reposName][ "error"] = QCoreApplication.translate( "QgsPluginInstaller", "Server response is 200 OK, but doesn't contain plugin metatada. This is most likely caused by a proxy or a wrong repository URL. You can configure proxy settings in QGIS options." ) else: self.mRepositories[reposName][ "error"] = QCoreApplication.translate( "QgsPluginInstaller", "Status code:") + " %d %s" % ( reply.attribute( QNetworkRequest.HttpStatusCodeAttribute), reply.attribute( QNetworkRequest.HttpReasonPhraseAttribute)) self.repositoryFetched.emit(reposName) # is the checking done? if not self.fetchingInProgress(): self.checkingDone.emit() reply.deleteLater()
def create_request(self, request_type: str): """Creates a QNetworkRequest() with appropriate headers and URL according to the 'request_type' parameter. :param str request_type: type of request to create. Options: - 'token' - 'search' - 'details' - 'shares' :returns: the QNetworkRequest to send to the Isogeo's API :rtype: QNetworkRequest """ # creating headers (same steps wathever request_type value) header_value = QByteArray() header_name = QByteArray() header_name.append("Authorization") # for token request if request_type == "token": # filling request header with credentials header_value.append("Basic ") header_value.append( base64.b64encode("{}:{}".format(self.app_id, self.app_secret).encode())) # creating the QNetworkRequest from oAuth2 authentication URL request = QNetworkRequest(QUrl(self.api_url_token)) # creating and setting the 'Content-type header' ct_header_value = QByteArray() ct_header_value.append("application/json") request.setHeader(request.ContentTypeHeader, ct_header_value) # for other request_type, setting appropriate url else: if request_type == "shares": url = QUrl("{}/shares".format(self.api_url_base)) elif request_type == "search" or request_type == "details": url = QUrl(self.currentUrl) else: logger.debug( "Unkown request type asked : {}".format(request_type)) raise ValueError return 0 # filling request header with token header_value.append(self.token) request = QNetworkRequest(url) # creating QNetworkRequest from appropriate url request.setRawHeader(header_name, header_value) return request
def __init__(self, alg, model, algName=None, configuration=None): QDialog.__init__(self) self.setModal(True) self._alg = alg # The algorithm to define in this dialog. It is an instance of QgsProcessingAlgorithm self.model = model # The model this algorithm is going to be added to. It is an instance of QgsProcessingModelAlgorithm self.childId = algName # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self.configuration = configuration self.context = createContext() self.widget_labels = {} class ContextGenerator(QgsProcessingContextGenerator): def __init__(self, context): super().__init__() self.processing_context = context def processingContext(self): return self.processing_context self.context_generator = ContextGenerator(self.context) self.setupUi() self.params = None settings = QgsSettings() self.restoreGeometry(settings.value("/Processing/modelParametersDialogGeometry", QByteArray()))
def __init__(self, model=None): super().__init__(None) self.setAttribute(Qt.WA_DeleteOnClose) self.setupUi(self) # LOTS of bug reports when we include the dock creation in the UI file # see e.g. #16428, #19068 # So just roll it all by hand......! self.propertiesDock = QgsDockWidget(self) self.propertiesDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.propertiesDock.setObjectName("propertiesDock") propertiesDockContents = QWidget() self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents) self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0) self.verticalDockLayout_1.setSpacing(0) self.scrollArea_1 = QgsScrollArea(propertiesDockContents) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.scrollArea_1.sizePolicy().hasHeightForWidth()) self.scrollArea_1.setSizePolicy(sizePolicy) self.scrollArea_1.setFocusPolicy(Qt.WheelFocus) self.scrollArea_1.setFrameShape(QFrame.NoFrame) self.scrollArea_1.setFrameShadow(QFrame.Plain) self.scrollArea_1.setWidgetResizable(True) self.scrollAreaWidgetContents_1 = QWidget() self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1) self.gridLayout.setContentsMargins(6, 6, 6, 6) self.gridLayout.setSpacing(4) self.label_1 = QLabel(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1) self.textName = QLineEdit(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.textName, 0, 1, 1, 1) self.label_2 = QLabel(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1) self.label_1.setText(self.tr("Name")) self.textName.setToolTip(self.tr("Enter model name here")) self.label_2.setText(self.tr("Group")) self.textGroup.setToolTip(self.tr("Enter group name here")) self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1) self.verticalDockLayout_1.addWidget(self.scrollArea_1) self.propertiesDock.setWidget(propertiesDockContents) self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock) self.propertiesDock.setWindowTitle(self.tr("Model properties")) self.inputsDock = QgsDockWidget(self) self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.inputsDock.setObjectName("inputsDock") self.inputsDockContents = QWidget() self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents) self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) self.scrollArea_2 = QgsScrollArea(self.inputsDockContents) sizePolicy.setHeightForWidth( self.scrollArea_2.sizePolicy().hasHeightForWidth()) self.scrollArea_2.setSizePolicy(sizePolicy) self.scrollArea_2.setFocusPolicy(Qt.WheelFocus) self.scrollArea_2.setFrameShape(QFrame.NoFrame) self.scrollArea_2.setFrameShadow(QFrame.Plain) self.scrollArea_2.setWidgetResizable(True) self.scrollAreaWidgetContents_2 = QWidget() self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setSpacing(0) self.inputsTree = QTreeWidget(self.scrollAreaWidgetContents_2) self.inputsTree.setAlternatingRowColors(True) self.inputsTree.header().setVisible(False) self.verticalLayout.addWidget(self.inputsTree) self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) self.verticalLayout_3.addWidget(self.scrollArea_2) self.inputsDock.setWidget(self.inputsDockContents) self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock) self.inputsDock.setWindowTitle(self.tr("Inputs")) self.algorithmsDock = QgsDockWidget(self) self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.algorithmsDock.setObjectName("algorithmsDock") self.algorithmsDockContents = QWidget() self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents) self.verticalLayout_4.setContentsMargins(0, 0, 0, 0) self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents) sizePolicy.setHeightForWidth( self.scrollArea_3.sizePolicy().hasHeightForWidth()) self.scrollArea_3.setSizePolicy(sizePolicy) self.scrollArea_3.setFocusPolicy(Qt.WheelFocus) self.scrollArea_3.setFrameShape(QFrame.NoFrame) self.scrollArea_3.setFrameShadow(QFrame.Plain) self.scrollArea_3.setWidgetResizable(True) self.scrollAreaWidgetContents_3 = QWidget() self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3) self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_2.setSpacing(4) self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3) self.verticalLayout_2.addWidget(self.searchBox) self.algorithmTree = QgsProcessingToolboxTreeView( None, QgsApplication.processingRegistry()) self.algorithmTree.setAlternatingRowColors(True) self.algorithmTree.header().setVisible(False) self.verticalLayout_2.addWidget(self.algorithmTree) self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3) self.verticalLayout_4.addWidget(self.scrollArea_3) self.algorithmsDock.setWidget(self.algorithmsDockContents) self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock) self.algorithmsDock.setWindowTitle(self.tr("Algorithms")) self.searchBox.setToolTip( self.tr("Enter algorithm name to filter list")) self.searchBox.setShowSearchIcon(True) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.centralWidget().layout().insertWidget(0, self.bar) try: self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging) except: pass if iface is not None: self.mToolbar.setIconSize(iface.iconSize()) self.setStyleSheet(iface.mainWindow().styleSheet()) self.mActionOpen.setIcon( QgsApplication.getThemeIcon('/mActionFileOpen.svg')) self.mActionSave.setIcon( QgsApplication.getThemeIcon('/mActionFileSave.svg')) self.mActionSaveAs.setIcon( QgsApplication.getThemeIcon('/mActionFileSaveAs.svg')) self.mActionSaveInProject.setIcon( QgsApplication.getThemeIcon('/mAddToProject.svg')) self.mActionZoomActual.setIcon( QgsApplication.getThemeIcon('/mActionZoomActual.svg')) self.mActionZoomIn.setIcon( QgsApplication.getThemeIcon('/mActionZoomIn.svg')) self.mActionZoomOut.setIcon( QgsApplication.getThemeIcon('/mActionZoomOut.svg')) self.mActionExportImage.setIcon( QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg')) self.mActionZoomToItems.setIcon( QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg')) self.mActionExportPdf.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg')) self.mActionExportSvg.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg')) #self.mActionExportPython.setIcon( # QgsApplication.getThemeIcon('/mActionSaveAsPython.svg')) self.mActionEditHelp.setIcon( QgsApplication.getThemeIcon('/mActionEditHelpContent.svg')) self.mActionRun.setIcon( QgsApplication.getThemeIcon('/mActionStart.svg')) self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock) self.tabifyDockWidget(self.inputsDock, self.algorithmsDock) self.inputsDock.raise_() self.zoom = 1 self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) settings = QgsSettings() self.restoreState( settings.value("/Processing/stateModeler", QByteArray())) self.restoreGeometry( settings.value("/Processing/geometryModeler", QByteArray())) self.scene = ModelerScene(self, dialog=self) self.scene.setSceneRect( QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE)) self.view.setScene(self.scene) self.view.setAcceptDrops(True) self.view.ensureVisible(0, 0, 10, 10) def _dragEnterEvent(event): if event.mimeData().hasText() or event.mimeData().hasFormat( 'application/x-vnd.qgis.qgis.algorithmid'): event.acceptProposedAction() else: event.ignore() def _dropEvent(event): if event.mimeData().hasFormat( 'application/x-vnd.qgis.qgis.algorithmid'): data = event.mimeData().data( 'application/x-vnd.qgis.qgis.algorithmid') stream = QDataStream(data, QIODevice.ReadOnly) algorithm_id = stream.readQString() alg = QgsApplication.processingRegistry().createAlgorithmById( algorithm_id) if alg is not None: self._addAlgorithm(alg, event.pos()) else: assert False, algorithm_id elif event.mimeData().hasText(): itemId = event.mimeData().text() if itemId in [ param.id() for param in QgsApplication.instance(). processingRegistry().parameterTypes() ]: self.addInputOfType(itemId, event.pos()) event.accept() else: event.ignore() def _dragMoveEvent(event): if event.mimeData().hasText() or event.mimeData().hasFormat( 'application/x-vnd.qgis.qgis.algorithmid'): event.accept() else: event.ignore() def _wheelEvent(event): self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) settings = QgsSettings() factor = settings.value('/qgis/zoom_favor', 2.0) # "Normal" mouse has an angle delta of 120, precision mouses provide data # faster, in smaller steps factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y()) if (event.modifiers() == Qt.ControlModifier): factor = 1.0 + (factor - 1.0) / 20.0 if event.angleDelta().y() < 0: factor = 1 / factor self.view.scale(factor, factor) def _enterEvent(e): QGraphicsView.enterEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mouseReleaseEvent(e): QGraphicsView.mouseReleaseEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mousePressEvent(e): if e.button() == Qt.MidButton: self.previousMousePos = e.pos() else: QGraphicsView.mousePressEvent(self.view, e) def _mouseMoveEvent(e): if e.buttons() == Qt.MidButton: offset = self.previousMousePos - e.pos() self.previousMousePos = e.pos() self.view.verticalScrollBar().setValue( self.view.verticalScrollBar().value() + offset.y()) self.view.horizontalScrollBar().setValue( self.view.horizontalScrollBar().value() + offset.x()) else: QGraphicsView.mouseMoveEvent(self.view, e) self.view.setDragMode(QGraphicsView.ScrollHandDrag) self.view.dragEnterEvent = _dragEnterEvent self.view.dropEvent = _dropEvent self.view.dragMoveEvent = _dragMoveEvent self.view.wheelEvent = _wheelEvent self.view.enterEvent = _enterEvent self.view.mousePressEvent = _mousePressEvent self.view.mouseMoveEvent = _mouseMoveEvent def _mimeDataInput(items): mimeData = QMimeData() text = items[0].data(0, Qt.UserRole) mimeData.setText(text) return mimeData self.inputsTree.mimeData = _mimeDataInput self.inputsTree.setDragDropMode(QTreeWidget.DragOnly) self.inputsTree.setDropIndicatorShown(True) self.algorithms_model = ModelerToolboxModel( self, QgsApplication.processingRegistry()) self.algorithmTree.setToolboxProxyModel(self.algorithms_model) self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly) self.algorithmTree.setDropIndicatorShown(True) self.algorithmTree.setFilters( QgsProcessingToolboxProxyModel.FilterModeler) if hasattr(self.searchBox, 'setPlaceholderText'): self.searchBox.setPlaceholderText( QCoreApplication.translate('ModelerDialog', 'Search…')) if hasattr(self.textName, 'setPlaceholderText'): self.textName.setPlaceholderText(self.tr('Enter model name here')) if hasattr(self.textGroup, 'setPlaceholderText'): self.textGroup.setPlaceholderText(self.tr('Enter group name here')) # Connect signals and slots self.inputsTree.doubleClicked.connect(self.addInput) self.searchBox.textChanged.connect(self.algorithmTree.setFilterString) self.algorithmTree.doubleClicked.connect(self.addAlgorithm) # Ctrl+= should also trigger a zoom in action ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self) ctrlEquals.activated.connect(self.zoomIn) self.mActionOpen.triggered.connect(self.openModel) self.mActionSave.triggered.connect(self.save) self.mActionSaveAs.triggered.connect(self.saveAs) self.mActionSaveInProject.triggered.connect(self.saveInProject) self.mActionZoomIn.triggered.connect(self.zoomIn) self.mActionZoomOut.triggered.connect(self.zoomOut) self.mActionZoomActual.triggered.connect(self.zoomActual) self.mActionZoomToItems.triggered.connect(self.zoomToItems) self.mActionExportImage.triggered.connect(self.exportAsImage) self.mActionExportPdf.triggered.connect(self.exportAsPdf) self.mActionExportSvg.triggered.connect(self.exportAsSvg) #self.mActionExportPython.triggered.connect(self.exportAsPython) self.mActionEditHelp.triggered.connect(self.editHelp) self.mActionRun.triggered.connect(self.runModel) if model is not None: self.model = model.create() self.model.setSourceFilePath(model.sourceFilePath()) self.textGroup.setText(self.model.group()) self.textName.setText(self.model.displayName()) self.repaintModel() else: self.model = QgsProcessingModelAlgorithm() self.model.setProvider( QgsApplication.processingRegistry().providerById('model')) self.fillInputsTree() self.view.centerOn(0, 0) self.help = None self.hasChanged = False
def __init__(self, alg, model, algName=None, configuration=None): QDialog.__init__(self) self.setModal(True) self._alg = alg # The algorithm to define in this dialog. It is an instance of QgsProcessingAlgorithm self.model = model # The model this algorithm is going to be added to. It is an instance of QgsProcessingModelAlgorithm self.childId = algName # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self.configuration = configuration self.setupUi() self.params = None settings = QgsSettings() self.restoreGeometry(settings.value("/Processing/modelParametersDialogGeometry", QByteArray()))
def __init__(self, alg, model, algName=None): QDialog.__init__(self) self.setModal(True) # The algorithm to define in this dialog. It is an instance of GeoAlgorithm self._alg = alg # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class self.alg = None # The model this algorithm is going to be added to self.model = model # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self.childId = algName self.setupUi() self.params = None settings = QgsSettings() self.restoreGeometry(settings.value("/Processing/modelParametersDialogGeometry", QByteArray()))
def __init__(self, iface, parent=None): super(MainDialog, self).__init__(parent) QDialog.__init__(self) self.setupUi(self) self.iface = iface self.previewUrl = None self.layer_search_combo = None self.exporter_combo = None self.feedback = FeedbackDialog(self) self.feedback.setModal(True) stgs = QSettings() self.restoreGeometry( stgs.value("qgis2web/MainDialogGeometry", QByteArray(), type=QByteArray)) self.verticalLayout_2.addStretch() self.horizontalLayout_6.addStretch() if stgs.value("qgis2web/previewOnStartup", Qt.Checked) == Qt.Checked: self.previewOnStartup.setCheckState(Qt.Checked) else: self.previewOnStartup.setCheckState(Qt.Unchecked) if stgs.value("qgis2web/closeFeedbackOnSuccess", Qt.Checked) == Qt.Checked: self.closeFeedbackOnSuccess.setCheckState(Qt.Checked) else: self.closeFeedbackOnSuccess.setCheckState(Qt.Unchecked) self.previewFeatureLimit.setText( stgs.value("qgis2web/previewFeatureLimit", "1000")) self.appearanceParams.setSelectionMode( QAbstractItemView.SingleSelection) self.preview = None if webkit_available: widget = QWebView() self.preview = widget try: # if os.environ["TRAVIS"]: self.preview.setPage(WebPage()) except Exception: print("Failed to set custom webpage") webview = self.preview.page() webview.setNetworkAccessManager(QgsNetworkAccessManager.instance()) self.preview.settings().setAttribute( QWebSettings.DeveloperExtrasEnabled, True) self.preview.settings().setAttribute( QWebSettings.DnsPrefetchEnabled, True) else: widget = QTextBrowser() widget.setText( self.tr('Preview is not available since QtWebKit ' 'dependency is missing on your system')) self.right_layout.insertWidget(0, widget) self.populateConfigParams(self) self.populate_layers_and_groups(self) self.populateLayerSearch() writer = WRITER_REGISTRY.createWriterFromProject() self.setStateToWriter(writer) self.exporter = EXPORTER_REGISTRY.createFromProject() self.exporter_combo.setCurrentIndex( self.exporter_combo.findText(self.exporter.name())) self.exporter_combo.currentIndexChanged.connect( self.exporterTypeChanged) self.toggleOptions() if webkit_available: if self.previewOnStartup.checkState() == Qt.Checked: self.autoUpdatePreview() self.buttonPreview.clicked.connect(self.previewMap) else: self.buttonPreview.setDisabled(True) QgsProject.instance().cleared.connect(self.reject) self.layersTree.model().dataChanged.connect(self.populateLayerSearch) self.ol3.clicked.connect(self.changeFormat) self.leaflet.clicked.connect(self.changeFormat) self.buttonExport.clicked.connect(self.saveMap) helpText = os.path.join(os.path.dirname(os.path.realpath(__file__)), "helpFile.md") self.helpField.setSource(QUrl.fromLocalFile(helpText)) if webkit_available: self.devConsole = QWebInspector(self.preview) self.devConsole.setFixedHeight(0) self.devConsole.setObjectName("devConsole") self.devConsole.setPage(self.preview.page()) self.devConsole.hide() self.right_layout.insertWidget(1, self.devConsole) self.filter = devToggleFilter() self.filter.devToggle.connect(self.showHideDevConsole) self.installEventFilter(self.filter) self.setModal(False)
def __init__(self, iface, parent=None): QMainWindow.__init__(self, parent) if QApplication.overrideCursor(): QApplication.restoreOverrideCursor() self.setAttribute(Qt.WA_DeleteOnClose) tdir = os.path.dirname(os.path.realpath(__file__)) uif = os.path.join(tdir, "ui", "ui_rivergis.ui") self.ui = uic.loadUi(uif, self) self.conn = None self.curConnName = None self.schema = None self.passwd = None self.rdb = None self.iface = iface # self.mapRegistry = QgsMapLayerRegistry.instance() self.rivergisPath = os.path.dirname(__file__) self.dtms = [] # restore settings self.readSettings() self.menus = self.ui.menubar.findChildren(QMenu) self.toolbars = self.findChildren(QToolBar) # MENU Actions # DB self.ui.actionRefreshConnections.triggered.connect(self.connChanged) self.ui.actionCreateNewSchema.triggered.connect(self.dbCreateSchema) self.ui.actionDeleteSchema.triggered.connect(self.dbDeleteSchema) self.ui.actionRASCreateRdbTables.triggered.connect(self.rasCreateRdbTables) self.ui.actionRASLoadRdbTablesIntoQGIS.triggered.connect(self.rasLoadRdbTablesIntoQGIS) self.ui.actionRASImportLayersIntoRdbTables.triggered.connect(self.rasImportLayersIntoRdbTables) # Settings self.ui.actionOptions.triggered.connect(self.options) self.ui.actionRestoreDefaultOptions.triggered.connect(lambda: self.readSettings(defaults=True)) # RAS Geometry # 1D self.ui.actionRASTopology1D.triggered.connect(lambda: r1d.ras1dStreamCenterlineTopology(self)) self.ui.actionRASLengthsStations.triggered.connect(lambda: r1d.ras1dStreamCenterlineLengthsStations(self)) self.ui.actionCopyStreamCenterlines2Flowpaths.triggered.connect(lambda: r1d.ras1dStreamCenterlines2Flowpaths(self)) self.ui.actionRASStreamCenterlineAll.triggered.connect(lambda: r1d.ras1dStreamCenterlineAll(self)) self.ui.actionRASXSRiverReachNames.triggered.connect(lambda: r1d.ras1dXSRiverReachNames(self)) self.ui.actionRASXSStationing.triggered.connect(lambda: r1d.ras1dXSStationing(self)) self.ui.actionRASXSBankStations.triggered.connect(lambda: r1d.ras1dXSBankStations(self)) self.ui.actionRASXSDownstreamReachLengths.triggered.connect(lambda: r1d.ras1dXSDownstreamLengths(self)) self.ui.actionRASXSElevations.triggered.connect(lambda: r1d.ras1dXSElevations(self)) self.ui.actionRASXSAll.triggered.connect(lambda: r1d.ras1dXSAll(self)) self.ui.actionRASHealLanduseGeometries.triggered.connect(lambda: r1d.ras1dHealLanduseGeoms(self)) self.ui.actionRASManningsNValues.triggered.connect(lambda: r1d.ras1dXSExtractMannings(self)) self.ui.actionRASLevees.triggered.connect(lambda: r1d.ras1dLevees(self)) self.ui.actionRASIneffectiveFlowAreas.triggered.connect(lambda: r1d.ras1dIneffective(self)) self.ui.actionRASBlockedObstructions.triggered.connect(lambda: r1d.ras1dObstructions(self)) self.ui.actionRASXSUpdateInsertMeasuredPoints.triggered.connect(lambda: r1d.ras1dXSUpdateInsertMeasuredPts(self)) self.ui.actionRASBRRiverReachNames.triggered.connect(lambda: r1d.ras1dBRRiverReachNames(self)) self.ui.actionRASBRStationing.triggered.connect(lambda: r1d.ras1dBRStationing(self)) self.ui.actionRASBRElevations.triggered.connect(lambda: r1d.ras1dBRElevations(self)) self.ui.actionRASBRAll.triggered.connect(lambda: r1d.ras1dRASBRAll(self)) self.ui.actionRASInlRiverReachNames.triggered.connect(lambda: r1d.ras1dISRiverReachNames(self)) self.ui.actionRASInlStationing.triggered.connect(lambda: r1d.ras1dISStationing(self)) self.ui.actionRASInlElevations.triggered.connect(lambda: r1d.ras1dISElevations(self)) self.ui.actionRASInlAll.triggered.connect(lambda: r1d.ras1dISAll(self)) self.ui.actionRASLatRiverReachNames.triggered.connect(lambda: r1d.ras1dLatRiverReachNames(self)) self.ui.actionRASLatStationing.triggered.connect(lambda: r1d.ras1dLatStationing(self)) self.ui.actionRASLatElevations.triggered.connect(lambda: r1d.ras1dLatElevations(self)) self.ui.actionRASLatAll.triggered.connect(lambda: r1d.ras1dLatAll(self)) self.ui.actionRASSAElevationVolumeData.triggered.connect(lambda: r1d.ras1dSAVolumeData(self)) self.ui.actionRASSATerrainPointExtraction.triggered.connect(lambda: r1d.ras1dSAElevations(self)) self.ui.actionRASSAAll.triggered.connect(lambda: r1d.ras1dSAAll(self)) self.ui.actionRASSacAssignNearestSA.triggered.connect(lambda: r1d.ras1dSACAssignNearestSA(self)) self.ui.actionRASSacElevations.triggered.connect(lambda: r1d.ras1dSACElevations(self)) self.ui.actionRASSacAll.triggered.connect(lambda: r1d.ras1dSACAll(self)) self.ui.actionRASCreateRASGISImport.triggered.connect(lambda: r1d.ras1dCreateRasGisImportFile(self)) # 2D self.ui.actionRASCreate2dAreaPoints.triggered.connect(lambda: r2d.ras2dCreate2dPoints(self)) self.ui.actionRASPreview2DMesh.triggered.connect(lambda: r2d.ras2dPreviewMesh(self)) self.ui.actionRASSave2DPointsToHECRASGeometry.triggered.connect(lambda: r2d.ras2dSaveMeshPtsToGeometry(self)) # HELP self.ui.actionHelpContents.triggered.connect(self.showRGisHelp) self.ui.actionWebsite.triggered.connect(self.showWebsite) self.ui.actionAbout.triggered.connect(self.about) # combos self.ui.crsWidget.crsChanged.connect(self.updateDefaultCrs) self.ui.connsCbo.activated.connect(self.connChanged) self.ui.schemasCbo.activated.connect(self.schemaChanged) # Welcome message self.ui.textEdit.append('<b>Welcome to RiverGIS!</b><br><br>Start building your model with 3 simple steps:<br>1. <b>Choose a connection</b> to PostGIS database<br>2. choose or create database <b>schema</b> (schema = model container or folder)<br>3. select a <b>projection</b> for the river database objects (projection = Coordinate Reference System, CRS).') self.ui.textEdit.append('<br>If you can\'t see any connection, please, create a new one from menu Layer > Add layer > Add PostGIS layers... <br>') self.ui.textEdit.append('----------------------------------------------------------------------------') # restore the window state s = QSettings() self.restoreGeometry(s.value("/rivergis/mainWindow/geometry", QByteArray(), type=QByteArray)) self.restoreState(s.value("/rivergis/mainWindow/windowState", QByteArray(), type=QByteArray)) # get PostGIS connections details and populate connections' combo self.connChanged() # restore settings self.readSettings() # set QGIS projection CRS as a default for RiverGIS self.ui.crsWidget.setCrs(self.iface.mapCanvas().mapSettings().destinationCrs()) self.updateDefaultCrs() # check if we should connect to previously used RDB if self.open_last_conn: try: self.connChanged(conn_name=self.opts['rdb']['last_conn'], schema_name=self.opts['rdb']['last_schema']) except: pass # disable some actions until a connection to river database is established if not self.rdb: self.disableActions()
def make_buffer(obj): data = QByteArray(make_payload(obj)) buffer = QBuffer() buffer.setData(data) buffer.open(buffer.ReadOnly) return buffer
def download(self): """Downloading the file. :returns: True if success, otherwise returns a tuple with format like this (QNetworkReply.NetworkError, error_message) :raises: IOError - when cannot create output_path """ # Prepare output path self.output_file = QFile(self.output_path) if not self.output_file.open(QFile.WriteOnly): raise IOError(self.output_file.errorString()) # Prepare downloaded buffer self.downloaded_file_buffer = QByteArray() # Request the url request = QNetworkRequest(self.url) self.reply = self.manager.get(request) self.reply.readyRead.connect(self.get_buffer) self.reply.finished.connect(self.write_data) self.manager.requestTimedOut.connect(self.request_timeout) if self.progress_dialog: # progress bar def progress_event(received, total): """Update progress. :param received: Data received so far. :type received: int :param total: Total expected data. :type total: int """ # noinspection PyArgumentList QgsApplication.processEvents() self.progress_dialog.adjustSize() human_received = humanize_file_size(received) human_total = humanize_file_size(total) label_text = tr( "%s : %s of %s" % (self.prefix_text, human_received, human_total)) self.progress_dialog.setLabelText(label_text) self.progress_dialog.setMaximum(total) self.progress_dialog.setValue(received) # cancel def cancel_action(): """Cancel download.""" self.reply.abort() self.reply.deleteLater() self.reply.downloadProgress.connect(progress_event) self.progress_dialog.canceled.connect(cancel_action) # Wait until finished # On Windows 32bit AND QGIS 2.2, self.reply.isFinished() always # returns False even after finished slot is called. So, that's why we # are adding self.finished_flag (see #864) while not self.reply.isFinished() and not self.finished_flag: # noinspection PyArgumentList QgsApplication.processEvents() result = self.reply.error() try: http_code = int( self.reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)) except TypeError: # If the user cancels the request, the HTTP response will be None. http_code = None self.reply.abort() self.reply.deleteLater() if result == QNetworkReply.NoError: return True, None elif result == QNetworkReply.UnknownNetworkError: return False, tr( 'The network is unreachable. Please check your internet ' 'connection.') elif http_code == 408: msg = tr('Sorry, the server aborted your request. ' 'Please try a smaller area.') LOGGER.debug(msg) return False, msg elif http_code == 509: msg = tr( 'Sorry, the server is currently busy with another request. ' 'Please try again in a few minutes.') LOGGER.debug(msg) return False, msg elif result == QNetworkReply.ProtocolUnknownError or \ result == QNetworkReply.HostNotFoundError: # See http://doc.qt.io/qt-5/qurl-obsolete.html#encodedHost encoded_host = self.url.toAce(self.url.host()) LOGGER.exception('Host not found : %s' % encoded_host) return False, tr( 'Sorry, the server is unreachable. Please try again later.') elif result == QNetworkReply.ContentNotFoundError: LOGGER.exception('Path not found : %s' % self.url.path()) return False, tr('Sorry, the layer was not found on the server.') else: return result, self.reply.errorString()
def api_authentification(self): logger.debug("\n------------------ Authentication ------------------") # creating credentials header crd_header_value = QByteArray() crd_header_value.append("Basic ") crd_header_value.append( base64.b64encode("{}:{}".format(self.app_id, self.app_secrets).encode()) ) crd_header_name = QByteArray() crd_header_name.append("Authorization") # creating Content-Type header ct_header_value = QByteArray() ct_header_value.append("application/json") # creating request token_rqst = QNetworkRequest(QUrl(self.token_url)) # setting headers token_rqst.setRawHeader(crd_header_name, crd_header_value) token_rqst.setHeader(token_rqst.ContentTypeHeader, ct_header_value) # creating data data = QByteArray() data.append(urlencode({"grant_type": "client_credentials"})) # requesting and handle reply logger.debug("Asking for token") token_reply = self.naMngr.post(token_rqst, data) token_reply.finished.connect(partial(self.api_handle_token, reply=token_reply))
def responseComplete(self): ''' Send new response ''' self.handler = self.serverIface.requestHandler() params = self.handler.parameterMap( ) # Check if needed params are passed # If not, do not change QGIS Server response if params['SERVICE'].lower() != 'wms': return # Check if getprintatlas request. If not, just send the response if 'REQUEST' not in params or params['REQUEST'].lower() not in ['getprintatlas', 'getcapabilitiesatlas']: return # Get capabilities if params['REQUEST'].lower() == 'getcapabilitiesatlas': body = { 'status': 'success', 'metadata': self.metadata } self.setJsonResponse( '200', body) return # Check if needed params are set if 'TEMPLATE' not in params or 'FORMAT' not in params or 'DPI' not in params or 'MAP' not in params or 'EXP_FILTER' not in params: body = { 'status': 'fail', 'message': 'Missing parameters: TEMPLATE, FORMAT, DPI, MAP, EXP_FILTER are required ' } self.setJsonResponse( '200', body) return self.project_path = self.serverInterface().configFilePath() self.composer_name = params['TEMPLATE'] self.feature_filter = params['EXP_FILTER'] # check expression qExp = QgsExpression(self.feature_filter) if not qExp.hasParserError(): qReq = QgsFeatureRequest(qExp) qReq.setLimit(1) ok = True else: body = { 'status': 'fail', 'message': 'An error occured while parsing the given expression: %s' % qExp.parserErrorString() } syslog.syslog(syslog.LOG_ERR, "ATLAS - ERROR EXPRESSION: %s" % qExp.parserErrorString()) self.setJsonResponse( '200', body) return try: pdf = self.print_atlas( project_path=self.project_path, composer_name=self.composer_name, predefined_scales=self.predefined_scales, feature_filter=self.feature_filter ) except: pdf = None if not pdf: body = { 'status': 'fail', 'message': 'ATLAS - Error while generating the PDF' } QgsMessageLog.logMessage("ATLAS - No PDF generated in %s" % pdf, 'atlasprint', Qgis.Info) self.setJsonResponse( '200', body) return # Send PDF self.handler.clear() self.handler.setResponseHeader('Content-type', 'application/pdf') self.handler.setResponseHeader('Status', '200') try: with open(pdf, 'rb') as f: loads = f.readlines() ba = QByteArray(b''.join(loads)) self.handler.appendBody(ba) except: body = { 'status': 'fail', 'message': 'Error occured while reading PDF file', } self.setJsonResponse( '200', body) finally: os.remove(pdf) return
def __init__(self, alg, paramType=None, param=None): self.alg = alg self.paramType = paramType self.param = param QDialog.__init__(self) self.setModal(True) self.setupUi() settings = QgsSettings() self.restoreGeometry(settings.value("/Processing/modelParametersDefinitionDialogGeometry", QByteArray()))
def run(plugin): """Import intermediate certs and return True on success""" if QgsApplication.authManager().isDisabled(): plugin.log(QgsApplication.authManager().disabledMessage()) return False ca_pems = dict() with wincertstore.CertSystemStore("CA") as store: for cert in store.itercerts(usage=None): # plugin.log(cert.get_name()) # plugin.log(cert.enhanced_keyusage_names()) ca_pems[cert.get_name()] = cert.get_pem() plugin.log( plugin.tr("Number of possible CAs found: {0}").format(len(ca_pems))) if not ca_pems: return False ca_certs = [] trusted_cas = QgsApplication.authManager().trustedCaCertsCache() for ca_cn, ca_pem in ca_pems.items(): try: ca_bytes = ca_pem.encode('ASCII') except UnicodeEncodeError: continue pem_ba = QByteArray(ca_bytes) cas = QSslCertificate.fromData(pem_ba) # plugin.log("Converted PEM to QSslCertificate {0}: ".format(ca_cn)) if not cas: plugin.log( plugin.tr("Could not convert PEM to QSslCertificate: {0}"). format(ca_cn)) continue ca = cas[0] # noinspection PyArgumentList if not QgsAuthCertUtils.certIsViable(cert=ca): plugin.log(plugin.tr(" cert not viable: {0}").format(ca_cn)) continue # noinspection PyArgumentList if not QgsAuthCertUtils.certificateIsAuthority(cert=ca): plugin.log(plugin.tr(" cert not a CA: {0}").format(ca_cn)) continue if ca in trusted_cas: plugin.log( plugin.tr(" cert already in trusted CA cache: {0}").format( ca_cn)) continue plugin.log(plugin.tr(" found CA to add: {0}").format(ca_cn)) ca_certs.append(ca) if ca_certs: plugin.log(plugin.tr("Storing CAs in auth system db")) if not QgsApplication.authManager().storeCertAuthorities(ca_certs): plugin.log(plugin.tr(" FAILED")) return False plugin.log(plugin.tr(" SUCCESS")) plugin.log(plugin.tr("Reinitializing auth system SSL caches")) QgsApplication.authManager().initSslCaches() return True else: plugin.log(plugin.tr("No CAs found to store in auth system db")) return True
def __init__(self, alg=None): super(ModelerDialog, self).__init__(None) self.setupUi(self) self.zoom = 1 self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) settings = QSettings() self.splitter.restoreState( settings.value("/Processing/splitterModeler", QByteArray())) self.restoreGeometry( settings.value("/Processing/geometryModeler", QByteArray())) self.tabWidget.setCurrentIndex(0) self.scene = ModelerScene(self) self.scene.setSceneRect( QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE)) self.view.setScene(self.scene) self.view.setAcceptDrops(True) self.view.ensureVisible(0, 0, 10, 10) def _dragEnterEvent(event): if event.mimeData().hasText(): event.acceptProposedAction() else: event.ignore() def _dropEvent(event): if event.mimeData().hasText(): text = event.mimeData().text() if text in ModelerParameterDefinitionDialog.paramTypes: self.addInputOfType(text, event.pos()) else: alg = ModelerUtils.getAlgorithm(text) if alg is not None: self._addAlgorithm(alg.getCopy(), event.pos()) event.accept() else: event.ignore() def _dragMoveEvent(event): if event.mimeData().hasText(): event.accept() else: event.ignore() def _wheelEvent(event): self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) factor = 1.05 if event.delta() > 0: factor = 1 / factor self.view.scale(factor, factor) self.repaintModel() def _enterEvent(e): QGraphicsView.enterEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mousePressEvent(e): QGraphicsView.mousePressEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mouseReleaseEvent(e): QGraphicsView.mouseReleaseEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) self.view.setDragMode(QGraphicsView.ScrollHandDrag) self.view.dragEnterEvent = _dragEnterEvent self.view.dropEvent = _dropEvent self.view.dragMoveEvent = _dragMoveEvent self.view.wheelEvent = _wheelEvent self.view.enterEvent = _enterEvent self.view.mousePressEvent = _mousePressEvent self.view.mouseReleaseEvent = _mouseReleaseEvent def _mimeDataInput(items): mimeData = QMimeData() text = items[0].text(0) mimeData.setText(text) return mimeData self.inputsTree.mimeData = _mimeDataInput self.inputsTree.setDragDropMode(QTreeWidget.DragOnly) self.inputsTree.setDropIndicatorShown(True) def _mimeDataAlgorithm(items): item = items[0] if isinstance(item, TreeAlgorithmItem): mimeData = QMimeData() mimeData.setText(item.alg.commandLineName()) return mimeData self.algorithmTree.mimeData = _mimeDataAlgorithm self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly) self.algorithmTree.setDropIndicatorShown(True) # Set icons self.btnOpen.setIcon( QgsApplication.getThemeIcon('/mActionFileOpen.svg')) self.btnSave.setIcon( QgsApplication.getThemeIcon('/mActionFileSave.svg')) self.btnSaveAs.setIcon( QgsApplication.getThemeIcon('/mActionFileSaveAs.svg')) self.btnExportImage.setIcon( QgsApplication.getThemeIcon('/mActionSaveMapAsImage.png')) self.btnExportPython.setIcon( QgsApplication.getThemeIcon('/console/iconSaveAsConsole.png')) self.btnEditHelp.setIcon( QIcon(os.path.join(pluginPath, 'images', 'edithelp.png'))) self.btnRun.setIcon( QIcon(os.path.join(pluginPath, 'images', 'runalgorithm.png'))) if hasattr(self.searchBox, 'setPlaceholderText'): self.searchBox.setPlaceholderText(self.tr('Search...')) if hasattr(self.textName, 'setPlaceholderText'): self.textName.setPlaceholderText( self.tr('[Enter model name here]')) if hasattr(self.textGroup, 'setPlaceholderText'): self.textGroup.setPlaceholderText( self.tr('[Enter group name here]')) # Connect signals and slots self.inputsTree.doubleClicked.connect(self.addInput) self.searchBox.textChanged.connect(self.fillAlgorithmTree) self.algorithmTree.doubleClicked.connect(self.addAlgorithm) self.btnOpen.clicked.connect(self.openModel) self.btnSave.clicked.connect(self.save) self.btnSaveAs.clicked.connect(self.saveAs) self.btnExportImage.clicked.connect(self.exportAsImage) self.btnExportPython.clicked.connect(self.exportAsPython) self.btnEditHelp.clicked.connect(self.editHelp) self.btnRun.clicked.connect(self.runModel) if alg is not None: self.alg = alg self.textGroup.setText(alg.group) self.textName.setText(alg.name) self.repaintModel() else: self.alg = ModelerAlgorithm() self.alg.modelerdialog = self self.fillInputsTree() self.fillAlgorithmTree() self.view.centerOn(0, 0) self.alg.setModelerView(self) self.help = None # Indicates whether to update or not the toolbox after # closing this dialog self.update = False self.hasChanged = False
def __init__(self, options, selectedoptions=None, datatype=None): super(MultipleInputDialog, self).__init__(None) self.setupUi(self) self.datatype = datatype self.model = None self.options = [] for i, option in enumerate(options): if option is None or isinstance(option, str): self.options.append((i, option)) else: self.options.append((option[0], option[1])) self.selectedoptions = selectedoptions or [] # Additional buttons self.btnSelectAll = QPushButton(self.tr('Select all')) self.buttonBox.addButton(self.btnSelectAll, QDialogButtonBox.ActionRole) self.btnClearSelection = QPushButton(self.tr('Clear selection')) self.buttonBox.addButton(self.btnClearSelection, QDialogButtonBox.ActionRole) self.btnToggleSelection = QPushButton(self.tr('Toggle selection')) self.buttonBox.addButton(self.btnToggleSelection, QDialogButtonBox.ActionRole) if self.datatype is not None: btnAddFile = QPushButton(QCoreApplication.translate("MultipleInputDialog", 'Add file(s)…')) btnAddFile.clicked.connect(self.addFiles) self.buttonBox.addButton(btnAddFile, QDialogButtonBox.ActionRole) self.btnSelectAll.clicked.connect(lambda: self.selectAll(True)) self.btnClearSelection.clicked.connect(lambda: self.selectAll(False)) self.btnToggleSelection.clicked.connect(self.toggleSelection) self.settings = QgsSettings() self.restoreGeometry(self.settings.value("/Processing/multipleInputDialogGeometry", QByteArray())) self.lstLayers.setSelectionMode(QAbstractItemView.ExtendedSelection) self.lstLayers.setDragDropMode(QAbstractItemView.InternalMove) self.populateList() self.finished.connect(self.saveWindowGeometry)
def __init__(self, model=None): super(ModelerDialog, self).__init__(None) self.setupUi(self) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.centralWidget().layout().insertWidget(0, self.bar) try: self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging) except: pass self.mToolbar.setIconSize(iface.iconSize()) self.mActionOpen.setIcon( QgsApplication.getThemeIcon('/mActionFileOpen.svg')) self.mActionSave.setIcon( QgsApplication.getThemeIcon('/mActionFileSave.svg')) self.mActionSaveAs.setIcon( QgsApplication.getThemeIcon('/mActionFileSaveAs.svg')) self.mActionZoomActual.setIcon( QgsApplication.getThemeIcon('/mActionZoomActual.svg')) self.mActionZoomIn.setIcon( QgsApplication.getThemeIcon('/mActionZoomIn.svg')) self.mActionZoomOut.setIcon( QgsApplication.getThemeIcon('/mActionZoomOut.svg')) self.mActionExportImage.setIcon( QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg')) self.mActionZoomToItems.setIcon( QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg')) self.mActionExportPdf.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg')) self.mActionExportSvg.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg')) self.mActionExportPython.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsPython.svg')) self.mActionEditHelp.setIcon( QgsApplication.getThemeIcon('/mActionEditHelpContent.svg')) self.mActionRun.setIcon( QgsApplication.getThemeIcon('/mActionStart.svg')) self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock) self.tabifyDockWidget(self.inputsDock, self.algorithmsDock) self.inputsDock.raise_() self.zoom = 1 self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) settings = QgsSettings() self.restoreState( settings.value("/Processing/stateModeler", QByteArray())) self.restoreGeometry( settings.value("/Processing/geometryModeler", QByteArray())) self.scene = ModelerScene(self, dialog=self) self.scene.setSceneRect( QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE)) self.view.setScene(self.scene) self.view.setAcceptDrops(True) self.view.ensureVisible(0, 0, 10, 10) def _dragEnterEvent(event): if event.mimeData().hasText(): event.acceptProposedAction() else: event.ignore() def _dropEvent(event): if event.mimeData().hasText(): text = event.mimeData().text() if text in ModelerParameterDefinitionDialog.paramTypes: self.addInputOfType(text, event.pos()) else: alg = QgsApplication.processingRegistry( ).createAlgorithmById(text) if alg is not None: self._addAlgorithm(alg, event.pos()) event.accept() else: event.ignore() def _dragMoveEvent(event): if event.mimeData().hasText(): event.accept() else: event.ignore() def _wheelEvent(event): self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) settings = QgsSettings() factor = settings.value('/qgis/zoom_favor', 2.0) # "Normal" mouse has an angle delta of 120, precision mouses provide data # faster, in smaller steps factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y()) if (event.modifiers() == Qt.ControlModifier): factor = 1.0 + (factor - 1.0) / 20.0 if event.angleDelta().y() < 0: factor = 1 / factor self.view.scale(factor, factor) def _enterEvent(e): QGraphicsView.enterEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mouseReleaseEvent(e): QGraphicsView.mouseReleaseEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mousePressEvent(e): if e.button() == Qt.MidButton: self.previousMousePos = e.pos() else: QGraphicsView.mousePressEvent(self.view, e) def _mouseMoveEvent(e): if e.buttons() == Qt.MidButton: offset = self.previousMousePos - e.pos() self.previousMousePos = e.pos() self.view.verticalScrollBar().setValue( self.view.verticalScrollBar().value() + offset.y()) self.view.horizontalScrollBar().setValue( self.view.horizontalScrollBar().value() + offset.x()) else: QGraphicsView.mouseMoveEvent(self.view, e) self.view.setDragMode(QGraphicsView.ScrollHandDrag) self.view.dragEnterEvent = _dragEnterEvent self.view.dropEvent = _dropEvent self.view.dragMoveEvent = _dragMoveEvent self.view.wheelEvent = _wheelEvent self.view.enterEvent = _enterEvent self.view.mousePressEvent = _mousePressEvent self.view.mouseMoveEvent = _mouseMoveEvent def _mimeDataInput(items): mimeData = QMimeData() text = items[0].text(0) mimeData.setText(text) return mimeData self.inputsTree.mimeData = _mimeDataInput self.inputsTree.setDragDropMode(QTreeWidget.DragOnly) self.inputsTree.setDropIndicatorShown(True) def _mimeDataAlgorithm(items): item = items[0] if isinstance(item, TreeAlgorithmItem): mimeData = QMimeData() mimeData.setText(item.alg.id()) return mimeData self.algorithmTree.mimeData = _mimeDataAlgorithm self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly) self.algorithmTree.setDropIndicatorShown(True) if hasattr(self.searchBox, 'setPlaceholderText'): self.searchBox.setPlaceholderText(self.tr('Search...')) if hasattr(self.textName, 'setPlaceholderText'): self.textName.setPlaceholderText(self.tr('Enter model name here')) if hasattr(self.textGroup, 'setPlaceholderText'): self.textGroup.setPlaceholderText(self.tr('Enter group name here')) # Connect signals and slots self.inputsTree.doubleClicked.connect(self.addInput) self.searchBox.textChanged.connect(self.fillAlgorithmTree) self.algorithmTree.doubleClicked.connect(self.addAlgorithm) # Ctrl+= should also trigger a zoom in action ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self) ctrlEquals.activated.connect(self.zoomIn) self.mActionOpen.triggered.connect(self.openModel) self.mActionSave.triggered.connect(self.save) self.mActionSaveAs.triggered.connect(self.saveAs) self.mActionZoomIn.triggered.connect(self.zoomIn) self.mActionZoomOut.triggered.connect(self.zoomOut) self.mActionZoomActual.triggered.connect(self.zoomActual) self.mActionZoomToItems.triggered.connect(self.zoomToItems) self.mActionExportImage.triggered.connect(self.exportAsImage) self.mActionExportPdf.triggered.connect(self.exportAsPdf) self.mActionExportSvg.triggered.connect(self.exportAsSvg) self.mActionExportPython.triggered.connect(self.exportAsPython) self.mActionEditHelp.triggered.connect(self.editHelp) self.mActionRun.triggered.connect(self.runModel) if model is not None: self.model = model.create() self.model.setSourceFilePath(model.sourceFilePath()) self.textGroup.setText(self.model.group()) self.textName.setText(self.model.displayName()) self.repaintModel() else: self.model = QgsProcessingModelAlgorithm() self.model.setProvider( QgsApplication.processingRegistry().providerById('model')) self.fillInputsTree() self.fillAlgorithmTree() self.view.centerOn(0, 0) self.help = None self.hasChanged = False
def __init__(self, alg=None): super(ModelerDialog, self).__init__(None) self.setupUi(self) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.centralWidget().layout().insertWidget(0, self.bar) try: self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging) except: pass self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock) self.tabifyDockWidget(self.inputsDock, self.algorithmsDock) self.inputsDock.raise_() self.zoom = 1 self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) settings = QSettings() self.restoreState( settings.value("/Processing/stateModeler", QByteArray())) self.restoreGeometry( settings.value("/Processing/geometryModeler", QByteArray())) self.scene = ModelerScene(self) self.scene.setSceneRect( QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE)) self.view.setScene(self.scene) self.view.setAcceptDrops(True) self.view.ensureVisible(0, 0, 10, 10) def _dragEnterEvent(event): if event.mimeData().hasText(): event.acceptProposedAction() else: event.ignore() def _dropEvent(event): if event.mimeData().hasText(): text = event.mimeData().text() if text in ModelerParameterDefinitionDialog.paramTypes: self.addInputOfType(text, event.pos()) else: alg = algList.getAlgorithm(text) if alg is not None: self._addAlgorithm(alg.getCopy(), event.pos()) event.accept() else: event.ignore() def _dragMoveEvent(event): if event.mimeData().hasText(): event.accept() else: event.ignore() def _wheelEvent(event): self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) settings = QSettings() factor = settings.value('/qgis/zoom_favor', 2.0) if (event.modifiers() == Qt.ControlModifier): factor = 1.0 + (factor - 1.0) / 20.0 if event.angleDelta().y() < 0: factor = 1 / factor self.view.scale(factor, factor) self.repaintModel() def _enterEvent(e): QGraphicsView.enterEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mousePressEvent(e): QGraphicsView.mousePressEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mouseReleaseEvent(e): QGraphicsView.mouseReleaseEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mousePressEvent(e): if e.button() == Qt.MidButton: self.previousMousePos = e.pos() else: QGraphicsView.mousePressEvent(self.view, e) def _mouseMoveEvent(e): if e.buttons() == Qt.MidButton: offset = self.previousMousePos - e.pos() self.previousMousePos = e.pos() self.view.verticalScrollBar().setValue( self.view.verticalScrollBar().value() + offset.y()) self.view.horizontalScrollBar().setValue( self.view.horizontalScrollBar().value() + offset.x()) else: QGraphicsView.mouseMoveEvent(self.view, e) self.view.setDragMode(QGraphicsView.ScrollHandDrag) self.view.dragEnterEvent = _dragEnterEvent self.view.dropEvent = _dropEvent self.view.dragMoveEvent = _dragMoveEvent self.view.wheelEvent = _wheelEvent self.view.enterEvent = _enterEvent self.view.mousePressEvent = _mousePressEvent self.view.mousePressEvent = _mousePressEvent self.view.mouseMoveEvent = _mouseMoveEvent def _mimeDataInput(items): mimeData = QMimeData() text = items[0].text(0) mimeData.setText(text) return mimeData self.inputsTree.mimeData = _mimeDataInput self.inputsTree.setDragDropMode(QTreeWidget.DragOnly) self.inputsTree.setDropIndicatorShown(True) def _mimeDataAlgorithm(items): item = items[0] if isinstance(item, TreeAlgorithmItem): mimeData = QMimeData() mimeData.setText(item.alg.commandLineName()) return mimeData self.algorithmTree.mimeData = _mimeDataAlgorithm self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly) self.algorithmTree.setDropIndicatorShown(True) if hasattr(self.searchBox, 'setPlaceholderText'): self.searchBox.setPlaceholderText(self.tr('Search...')) if hasattr(self.textName, 'setPlaceholderText'): self.textName.setPlaceholderText(self.tr('Enter model name here')) if hasattr(self.textGroup, 'setPlaceholderText'): self.textGroup.setPlaceholderText(self.tr('Enter group name here')) # Connect signals and slots self.inputsTree.doubleClicked.connect(self.addInput) self.searchBox.textChanged.connect(self.fillAlgorithmTree) self.algorithmTree.doubleClicked.connect(self.addAlgorithm) iconSize = settings.value("iconsize", 24) self.mToolbar.setIconSize(QSize(iconSize, iconSize)) self.mActionOpen.triggered.connect(self.openModel) self.mActionSave.triggered.connect(self.save) self.mActionSaveAs.triggered.connect(self.saveAs) self.mActionExportImage.triggered.connect(self.exportAsImage) self.mActionExportPython.triggered.connect(self.exportAsPython) self.mActionEditHelp.triggered.connect(self.editHelp) self.mActionRun.triggered.connect(self.runModel) if alg is not None: self.alg = alg self.textGroup.setText(alg.group) self.textName.setText(alg.name) self.repaintModel() else: self.alg = ModelerAlgorithm() self.alg.modelerdialog = self self.fillInputsTree() self.fillAlgorithmTree() self.view.centerOn(0, 0) self.alg.setModelerView(self) self.help = None self.hasChanged = False
def testCopyPaste(self): p = QgsProject() l = QgsLayout(p) # clear clipboard mime_data = QMimeData() mime_data.setData("text/xml", QByteArray()) clipboard = QApplication.clipboard() clipboard.setMimeData(mime_data) # add an item item1 = QgsLayoutItemLabel(l) item1.setText('label 1') l.addLayoutItem(item1) item1.setSelected(True) item2 = QgsLayoutItemLabel(l) item2.setText('label 2') l.addLayoutItem(item2) item2.setSelected(True) # multiframes multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1a') multiframe1.addFrame(frame1) frame1b = QgsLayoutFrame(l, multiframe1) frame1b.setId('frame1b') multiframe1.addFrame(frame1b) # not selected frame1c = QgsLayoutFrame(l, multiframe1) frame1c.setId('frame1b') multiframe1.addFrame(frame1c) # not selected multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') multiframe2.addFrame(frame2) frame1.setSelected(True) frame2.setSelected(True) view = QgsLayoutView() view.setCurrentLayout(l) self.assertFalse(view.hasItemsInClipboard()) view.copySelectedItems(QgsLayoutView.ClipboardCopy) self.assertTrue(view.hasItemsInClipboard()) pasted = view.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 4) new_multiframes = [m for m in l.multiFrames() if m not in [multiframe1, multiframe2]] self.assertEqual(len(new_multiframes), 2) self.assertIn(pasted[0], l.items()) self.assertIn(pasted[1], l.items()) labels = [p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutLabel] self.assertIn(sip.cast(labels[0], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) self.assertIn(sip.cast(labels[1], QgsLayoutItemLabel).text(), ('label 1', 'label 2')) frames = [p for p in pasted if p.type() == QgsLayoutItemRegistry.LayoutFrame] pasted_frame1 = sip.cast(frames[0], QgsLayoutFrame) pasted_frame2 = sip.cast(frames[1], QgsLayoutFrame) self.assertIn(pasted_frame1.multiFrame(), new_multiframes) self.assertIn(new_multiframes[0].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertIn(pasted_frame2.multiFrame(), new_multiframes) self.assertIn(new_multiframes[1].frames()[0].uuid(), (pasted_frame1.uuid(), pasted_frame2.uuid())) self.assertEqual(frame1.multiFrame(), multiframe1) self.assertCountEqual(multiframe1.frames(), [frame1, frame1b, frame1c]) self.assertEqual(frame1b.multiFrame(), multiframe1) self.assertEqual(frame1c.multiFrame(), multiframe1) self.assertEqual(frame2.multiFrame(), multiframe2) self.assertCountEqual(multiframe2.frames(), [frame2]) # copy specific item view.copyItems([item2], QgsLayoutView.ClipboardCopy) l2 = QgsLayout(p) view2 = QgsLayoutView() view2.setCurrentLayout(l2) pasted = view2.pasteItems(QgsLayoutView.PasteModeCursor) self.assertEqual(len(pasted), 1) self.assertIn(pasted[0], l2.items()) self.assertEqual(sip.cast(pasted[0], QgsLayoutItemLabel).text(), 'label 2')
def restoreSettingsConsole(self): storedTabScripts = self.settings.value("pythonConsole/tabScripts", []) self.tabListScript = storedTabScripts self.splitter.restoreState(self.settings.value("pythonConsole/splitterConsole", QByteArray())) self.splitterEditor.restoreState(self.settings.value("pythonConsole/splitterEditor", QByteArray())) self.splitterObj.restoreState(self.settings.value("pythonConsole/splitterObj", QByteArray()))
def __init__(self, alg): super(AlgorithmDialogBase, self).__init__(iface.mainWindow()) self.setupUi(self) self.feedback = AlgorithmDialogFeedback(self) self.settings = QSettings() self.restoreGeometry( self.settings.value("/Processing/dialogBase", QByteArray())) self.executed = False self.mainWidget = None self.alg = alg # Rename OK button to Run self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok) self.btnRun.setText(self.tr('Run')) self.btnClose = self.buttonBox.button(QDialogButtonBox.Close) self.setWindowTitle(self.alg.displayName()) #~ desktop = QDesktopWidget() #~ if desktop.physicalDpiX() > 96: #~ self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96) algHelp = self.alg.shortHelp() if algHelp is None: self.textShortHelp.setVisible(False) else: self.textShortHelp.document().setDefaultStyleSheet( '''.summary { margin-left: 10px; margin-right: 10px; } h2 { color: #555555; padding-bottom: 15px; } a { text-decoration: none; color: #3498db; font-weight: bold; } p { color: #666666; } b { color: #333333; } dl dd { margin-bottom: 5px; }''' ) self.textShortHelp.setHtml(algHelp) self.textShortHelp.setOpenLinks(False) def linkClicked(url): webbrowser.open(url.toString()) self.textShortHelp.anchorClicked.connect(linkClicked) isText, algHelp = self.alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr( '<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) rq = QNetworkRequest(algHelp) self.reply = QgsNetworkAccessManager.instance().get(rq) self.reply.finished.connect(self.requestFinished) except Exception as e: self.tabWidget.removeTab(2) else: self.tabWidget.removeTab(2) self.showDebug = ProcessingConfig.getSetting( ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
def __init__(self, alg): super(AlgorithmDialogBase, self).__init__(iface.mainWindow()) self.setupUi(self) # don't collapse parameters panel self.splitter.setCollapsible(0, False) # add collapse button to splitter splitterHandle = self.splitter.handle(1) handleLayout = QVBoxLayout() handleLayout.setContentsMargins(0, 0, 0, 0) self.btnCollapse = QToolButton(splitterHandle) self.btnCollapse.setAutoRaise(True) self.btnCollapse.setFixedSize(12, 12) self.btnCollapse.setCursor(Qt.ArrowCursor) handleLayout.addWidget(self.btnCollapse) handleLayout.addStretch() splitterHandle.setLayout(handleLayout) self.settings = QgsSettings() self.splitter.restoreState( self.settings.value("/Processing/dialogBaseSplitter", QByteArray())) self.restoreGeometry( self.settings.value("/Processing/dialogBase", QByteArray())) self.splitterState = self.splitter.saveState() self.splitterChanged(0, 0) self.executed = False self.mainWidget = None self.alg = alg self.setWindowTitle(self.alg.displayName()) self.buttonBox.rejected.connect(self.reject) self.buttonBox.accepted.connect(self.accept) # Rename OK button to Run self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok) self.btnRun.setText(self.tr('Run')) self.buttonCancel.setEnabled(False) self.btnClose = self.buttonBox.button(QDialogButtonBox.Close) self.buttonBox.helpRequested.connect(self.openHelp) self.btnCollapse.clicked.connect(self.toggleCollapsed) self.splitter.splitterMoved.connect(self.splitterChanged) # desktop = QDesktopWidget() # if desktop.physicalDpiX() > 96: # self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96) algHelp = self.formatHelp(self.alg) if algHelp is None: self.textShortHelp.hide() else: self.textShortHelp.document().setDefaultStyleSheet( '''.summary { margin-left: 10px; margin-right: 10px; } h2 { color: #555555; padding-bottom: 15px; } a { text-decoration: none; color: #3498db; font-weight: bold; } p { color: #666666; } b { color: #333333; } dl dd { margin-bottom: 5px; }''' ) self.textShortHelp.setHtml(algHelp) def linkClicked(url): webbrowser.open(url.toString()) self.textShortHelp.anchorClicked.connect(linkClicked) self.showDebug = ProcessingConfig.getSetting( ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
def __init__(self, algType, alg): super(ScriptEditorDialog, self).__init__(None) self.setupUi(self) self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) settings = QgsSettings() self.restoreState( settings.value("/Processing/stateScriptEditor", QByteArray())) self.restoreGeometry( settings.value("/Processing/geometryScriptEditor", QByteArray())) iconSize = int(settings.value("iconsize", 24)) self.toolBar.setIconSize(QSize(iconSize, iconSize)) self.actionOpenScript.setIcon( QgsApplication.getThemeIcon('/mActionFileOpen.svg')) self.actionSaveScript.setIcon( QgsApplication.getThemeIcon('/mActionFileSave.svg')) self.actionSaveScriptAs.setIcon( QgsApplication.getThemeIcon('/mActionFileSaveAs.svg')) self.actionEditScriptHelp.setIcon( QgsApplication.getThemeIcon('/mActionEditHelpContent.svg')) self.actionRunScript.setIcon( QgsApplication.getThemeIcon('/mActionStart.svg')) self.actionCut.setIcon( QgsApplication.getThemeIcon('/mActionEditCut.svg')) self.actionCopy.setIcon( QgsApplication.getThemeIcon('/mActionEditCopy.svg')) self.actionPaste.setIcon( QgsApplication.getThemeIcon('/mActionEditPaste.svg')) self.actionUndo.setIcon( QgsApplication.getThemeIcon('/mActionUndo.svg')) self.actionRedo.setIcon( QgsApplication.getThemeIcon('/mActionRedo.svg')) self.actionIncreaseFontSize.setIcon( QgsApplication.getThemeIcon('/mActionIncreaseFont.svg')) self.actionDecreaseFontSize.setIcon( QgsApplication.getThemeIcon('/mActionDecreaseFont.svg')) # Connect signals and slots self.actionOpenScript.triggered.connect(self.openScript) self.actionSaveScript.triggered.connect(self.save) self.actionSaveScriptAs.triggered.connect(self.saveAs) self.actionEditScriptHelp.triggered.connect(self.editHelp) self.actionRunScript.triggered.connect(self.runAlgorithm) self.actionCut.triggered.connect(self.editor.cut) self.actionCopy.triggered.connect(self.editor.copy) self.actionPaste.triggered.connect(self.editor.paste) self.actionUndo.triggered.connect(self.editor.undo) self.actionRedo.triggered.connect(self.editor.redo) self.actionIncreaseFontSize.triggered.connect(self.editor.zoomIn) self.actionDecreaseFontSize.triggered.connect(self.editor.zoomOut) self.editor.textChanged.connect(lambda: self.setHasChanged(True)) self.alg = alg self.algType = algType self.snippets = {} if self.algType == self.SCRIPT_PYTHON: path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "script", "snippets.py") with codecs.open(path, 'r', encoding='utf-8') as f: lines = f.readlines() snippetlines = [] name = None for line in lines: if line.startswith("##"): if snippetlines: self.snippets[name] = "".join(snippetlines) name = line[2:] snippetlines = [] else: snippetlines.append(line) if snippetlines: self.snippets[name] = "".join(snippetlines) #if self.snippets: # self.btnSnippets.setVisible(False) if self.alg is not None: self.filename = self.alg.descriptionFile self.editor.setText(self.alg.script) else: self.filename = None self.update = False self.help = None self.setHasChanged(False) self.editor.setLexerType(self.algType)
def testWriteWithBinaryField(self): """ Test writing with a binary field :return: """ basetestpath = tempfile.mkdtemp() tmpfile = os.path.join(basetestpath, 'binaryfield.sqlite') ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid']) lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('binfield', ogr.OFTBinary)) lyr.CreateField(ogr.FieldDefn('binfield2', ogr.OFTBinary)) f = None ds = None vl = QgsVectorLayer(tmpfile) self.assertTrue(vl.isValid()) # check that 1 of its fields is a bool fields = vl.fields() self.assertEqual( fields.at(fields.indexFromName('binfield')).type(), QVariant.ByteArray) dp = vl.dataProvider() f = QgsFeature(fields) bin_1 = b'xxx' bin_2 = b'yyy' bin_val1 = QByteArray(bin_1) bin_val2 = QByteArray(bin_2) f.setAttributes([1, 'str', 100, bin_val1, bin_val2]) self.assertTrue(dp.addFeature(f)) # write a gpkg package with a binary field filename = os.path.join(str(QDir.tempPath()), 'with_bin_field') rc, errmsg = QgsVectorFileWriter.writeAsVectorFormat( vl, filename, 'utf-8', vl.crs(), 'GPKG') self.assertEqual(rc, QgsVectorFileWriter.NoError) # open the resulting geopackage vl = QgsVectorLayer(filename + '.gpkg', '', 'ogr') self.assertTrue(vl.isValid()) fields = vl.fields() # test type of converted field idx = fields.indexFromName('binfield') self.assertEqual(fields.at(idx).type(), QVariant.ByteArray) idx2 = fields.indexFromName('binfield2') self.assertEqual(fields.at(idx2).type(), QVariant.ByteArray) # test values self.assertEqual(vl.getFeature(1).attributes()[idx], bin_val1) self.assertEqual(vl.getFeature(1).attributes()[idx2], bin_val2) del vl os.unlink(filename + '.gpkg')
def download(self): """Downloading the file. :returns: True if success, otherwise returns a tuple with format like this (QNetworkReply.NetworkError, error_message) :raises: IOError - when cannot create output_path """ # Prepare output path self.output_file = QFile(self.output_path) if not self.output_file.open(QFile.WriteOnly): raise IOError(self.output_file.errorString()) # Prepare downloaded buffer self.downloaded_file_buffer = QByteArray() # Request the url request = QNetworkRequest(self.url) self.reply = self.manager.get(request) self.reply.readyRead.connect(self.get_buffer) self.reply.finished.connect(self.write_data) self.manager.requestTimedOut.connect(self.request_timeout) if self.progress_dialog: # progress bar def progress_event(received, total): """Update progress. :param received: Data received so far. :type received: int :param total: Total expected data. :type total: int """ # noinspection PyArgumentList QgsApplication.processEvents() self.progress_dialog.adjustSize() human_received = humanize_file_size(received) human_total = humanize_file_size(total) label_text = tr("%s : %s of %s" % ( self.prefix_text, human_received, human_total)) self.progress_dialog.setLabelText(label_text) self.progress_dialog.setMaximum(total) self.progress_dialog.setValue(received) # cancel def cancel_action(): """Cancel download.""" self.reply.abort() self.reply.deleteLater() self.reply.downloadProgress.connect(progress_event) self.progress_dialog.canceled.connect(cancel_action) # Wait until finished # On Windows 32bit AND QGIS 2.2, self.reply.isFinished() always # returns False even after finished slot is called. So, that's why we # are adding self.finished_flag (see #864) while not self.reply.isFinished() and not self.finished_flag: # noinspection PyArgumentList QgsApplication.processEvents() result = self.reply.error() try: http_code = int(self.reply.attribute( QNetworkRequest.HttpStatusCodeAttribute)) except TypeError: # If the user cancels the request, the HTTP response will be None. http_code = None self.reply.abort() self.reply.deleteLater() if result == QNetworkReply.NoError: return True, None elif result == QNetworkReply.UnknownNetworkError: return False, tr( 'The network is unreachable. Please check your internet ' 'connection.') elif http_code == 408: msg = tr( 'Sorry, the server aborted your request. ' 'Please try a smaller area.') LOGGER.debug(msg) return False, msg elif http_code == 509: msg = tr( 'Sorry, the server is currently busy with another request. ' 'Please try again in a few minutes.') LOGGER.debug(msg) return False, msg elif result == QNetworkReply.ProtocolUnknownError or \ result == QNetworkReply.HostNotFoundError: # See http://doc.qt.io/qt-5/qurl-obsolete.html#encodedHost encoded_host = self.url.toAce(self.url.host()) LOGGER.exception('Host not found : %s' % encoded_host) return False, tr( 'Sorry, the server is unreachable. Please try again later.') elif result == QNetworkReply.ContentNotFoundError: LOGGER.exception('Path not found : %s' % self.url.path()) return False, tr('Sorry, the layer was not found on the server.') else: return result, self.reply.errorString()
def add_stations(self, content: QByteArray): """ Adds stations from reply content """ lines = content.data().decode().split('\n') self._add_stations(lines[1:])
def __init__(self, options): super(MultipleFileInputDialog, self).__init__(None) self.setupUi(self) self.lstLayers.setSelectionMode(QAbstractItemView.ExtendedSelection) self.selectedoptions = options # Additional buttons self.btnAdd = QPushButton(self.tr('Add file')) self.buttonBox.addButton(self.btnAdd, QDialogButtonBox.ActionRole) self.btnRemove = QPushButton(self.tr('Remove file(s)')) self.buttonBox.addButton(self.btnRemove, QDialogButtonBox.ActionRole) self.btnRemoveAll = QPushButton(self.tr('Remove all')) self.buttonBox.addButton(self.btnRemoveAll, QDialogButtonBox.ActionRole) self.btnAdd.clicked.connect(self.addFile) self.btnRemove.clicked.connect(lambda: self.removeRows()) self.btnRemoveAll.clicked.connect(lambda: self.removeRows(True)) self.settings = QgsSettings() self.restoreGeometry(self.settings.value("/Processing/multipleFileInputDialogGeometry", QByteArray())) self.populateList() self.finished.connect(self.saveWindowGeometry)
def upload_files(self, layer, field_index, features): """ Upload given features' source files to remote server and return a dict formatted as changeAttributeValues expects to update 'datos' attribute to a remote location. """ if not QSettings().value('Asistente-LADM_COL/sources/document_repository'): self.message_with_duration_emitted.emit(QCoreApplication.translate("SourceHandler", "Source files were not uploaded to the document repository because you have that option unchecked. You can still upload the source files later using the 'Upload Pending Source Files' menu."), Qgis.Info, 10) return dict() # Test if we have Internet connection and a valid service} dlg = self.qgis_utils.get_settings_dialog() res, msg = dlg.is_source_service_valid() if not res: msg['text'] = QCoreApplication.translate("SourceHandler", "No file could be uploaded to the server. You can do it later from the 'Upload Pending Source Files' menu. Reason: {}").format(msg['text']) self.message_with_duration_emitted.emit(msg['text'], msg['level'], 20) return dict() file_features = [feature for feature in features if os.path.isfile(feature[field_index])] total = len(features) not_found = total - len(file_features) upload_dialog = UploadProgressDialog(len(file_features), not_found) upload_dialog.show() count = 0 upload_errors = 0 new_values = dict() for feature in file_features: data_url = feature[field_index] file_name = os.path.basename(data_url) nam = QNetworkAccessManager() #reply.downloadProgress.connect(upload_dialog.update_current_progress) multiPart = QHttpMultiPart(QHttpMultiPart.FormDataType) textPart = QHttpPart() textPart.setHeader(QNetworkRequest.ContentDispositionHeader, QVariant("form-data; name=\"driver\"")) textPart.setBody(QByteArray().append('Local')) filePart = QHttpPart() filePart.setHeader(QNetworkRequest.ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"{}\"".format(file_name))) file = QFile(data_url) file.open(QIODevice.ReadOnly) filePart.setBodyDevice(file) file.setParent(multiPart) # we cannot delete the file now, so delete it with the multiPart multiPart.append(filePart) multiPart.append(textPart) service_url = '/'.join([ QSettings().value('Asistente-LADM_COL/source/service_endpoint', DEFAULT_ENDPOINT_SOURCE_SERVICE), SOURCE_SERVICE_UPLOAD_SUFFIX]) request = QNetworkRequest(QUrl(service_url)) reply = nam.post(request, multiPart) #reply.uploadProgress.connect(upload_dialog.update_current_progress) reply.error.connect(self.error_returned) multiPart.setParent(reply) # We'll block execution until we get response from the server loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec_() response = reply.readAll() data = QTextStream(response, QIODevice.ReadOnly) content = data.readAll() if content is None: self.log.logMessage("There was an error uploading file '{}'".format(data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue try: response = json.loads(content) except json.decoder.JSONDecodeError: self.log.logMessage("Couldn't parse JSON response from server for file '{}'!!!".format(data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue if 'error' in response: self.log.logMessage("STATUS: {}. ERROR: {} MESSAGE: {} FILE: {}".format( response['status'], response['error'], response['message'], data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue reply.deleteLater() if 'url' not in response: self.log.logMessage("'url' attribute not found in JSON response for file '{}'!".format(data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue url = self.get_file_url(response['url']) new_values[feature.id()] = {field_index : url} count += 1 upload_dialog.update_total_progress(count) if not_found > 0: self.message_with_duration_emitted.emit( QCoreApplication.translate("SourceHandler", "{} out of {} records {} ignored because {} file path couldn't be found in the local disk!").format( not_found, total, QCoreApplication.translate("SourceHandler", "was") if not_found == 1 else QCoreApplication.translate("SourceHandler", "were"), QCoreApplication.translate("SourceHandler", "its") if not_found == 1 else QCoreApplication.translate("SourceHandler", "their") ), Qgis.Warning, 0) if len(new_values): self.message_with_duration_emitted.emit( QCoreApplication.translate("SourceHandler", "{} out of {} files {} uploaded to the server and {} remote location stored in the database!").format( len(new_values), total, QCoreApplication.translate("SourceHandler", "was") if len(new_values) == 1 else QCoreApplication.translate("SourceHandler", "were"), QCoreApplication.translate("SourceHandler", "its") if len(new_values) == 1 else QCoreApplication.translate("SourceHandler", "their") ), Qgis.Info, 0) if upload_errors: self.message_with_duration_emitted.emit( QCoreApplication.translate("SourceHandler", "{} out of {} files could not be uploaded to the server because of upload errors! See log for details.").format( upload_errors, total ), Qgis.Warning, 0) return new_values
def xmlDownloaded(self): """ populate the plugins object with the fetched data """ reply = self.sender() reposName = reply.property('reposName') if reply.error() != QNetworkReply.NoError: # fetching failed self.mRepositories[reposName]["state"] = 3 self.mRepositories[reposName]["error"] = reply.errorString() if reply.error() == QNetworkReply.OperationCanceledError: self.mRepositories[reposName]["error"] += "\n\n" + QCoreApplication.translate("QgsPluginInstaller", "If you haven't canceled the download manually, it was most likely caused by a timeout. In this case consider increasing the connection timeout value in QGIS options window.") elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 301: redirectionUrl = reply.attribute(QNetworkRequest.RedirectionTargetAttribute) if redirectionUrl.isRelative(): redirectionUrl = reply.url().resolved(redirectionUrl) redirectionCounter = reply.property('redirectionCounter') + 1 if redirectionCounter > 4: self.mRepositories[reposName]["state"] = 3 self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Too many redirections") else: # Fire a new request and exit immediately in order to quietly destroy the old one self.requestFetching(reposName, redirectionUrl, redirectionCounter) reply.deleteLater() return else: reposXML = QDomDocument() content = reply.readAll() # Fix lonely ampersands in metadata a = QByteArray() a.append("& ") b = QByteArray() b.append("& ") content = content.replace(a, b) reposXML.setContent(content) pluginNodes = reposXML.elementsByTagName("pyqgis_plugin") if pluginNodes.size(): for i in range(pluginNodes.size()): fileName = pluginNodes.item(i).firstChildElement("file_name").text().strip() if not fileName: fileName = QFileInfo(pluginNodes.item(i).firstChildElement("download_url").text().strip().split("?")[0]).fileName() name = fileName.partition(".")[0] experimental = False if pluginNodes.item(i).firstChildElement("experimental").text().strip().upper() in ["TRUE", "YES"]: experimental = True deprecated = False if pluginNodes.item(i).firstChildElement("deprecated").text().strip().upper() in ["TRUE", "YES"]: deprecated = True trusted = False if pluginNodes.item(i).firstChildElement("trusted").text().strip().upper() in ["TRUE", "YES"]: trusted = True icon = pluginNodes.item(i).firstChildElement("icon").text().strip() if icon and not icon.startswith("http"): icon = "http://{}/{}".format(QUrl(self.mRepositories[reposName]["url"]).host(), icon) if pluginNodes.item(i).toElement().hasAttribute("plugin_id"): plugin_id = pluginNodes.item(i).toElement().attribute("plugin_id") else: plugin_id = None plugin = { "id": name, "plugin_id": plugin_id, "name": pluginNodes.item(i).toElement().attribute("name"), "version_available": pluginNodes.item(i).toElement().attribute("version"), "description": pluginNodes.item(i).firstChildElement("description").text().strip(), "about": pluginNodes.item(i).firstChildElement("about").text().strip(), "author_name": pluginNodes.item(i).firstChildElement("author_name").text().strip(), "homepage": pluginNodes.item(i).firstChildElement("homepage").text().strip(), "download_url": pluginNodes.item(i).firstChildElement("download_url").text().strip(), "category": pluginNodes.item(i).firstChildElement("category").text().strip(), "tags": pluginNodes.item(i).firstChildElement("tags").text().strip(), "changelog": pluginNodes.item(i).firstChildElement("changelog").text().strip(), "author_email": pluginNodes.item(i).firstChildElement("author_email").text().strip(), "tracker": pluginNodes.item(i).firstChildElement("tracker").text().strip(), "code_repository": pluginNodes.item(i).firstChildElement("repository").text().strip(), "downloads": pluginNodes.item(i).firstChildElement("downloads").text().strip(), "average_vote": pluginNodes.item(i).firstChildElement("average_vote").text().strip(), "rating_votes": pluginNodes.item(i).firstChildElement("rating_votes").text().strip(), "icon": icon, "experimental": experimental, "deprecated": deprecated, "trusted": trusted, "filename": fileName, "installed": False, "available": True, "status": "not installed", "error": "", "error_details": "", "version_installed": "", "zip_repository": reposName, "library": "", "readonly": False } qgisMinimumVersion = pluginNodes.item(i).firstChildElement("qgis_minimum_version").text().strip() if not qgisMinimumVersion: qgisMinimumVersion = "2" qgisMaximumVersion = pluginNodes.item(i).firstChildElement("qgis_maximum_version").text().strip() if not qgisMaximumVersion: qgisMaximumVersion = qgisMinimumVersion[0] + ".99" # if compatible, add the plugin to the list if not pluginNodes.item(i).firstChildElement("disabled").text().strip().upper() in ["TRUE", "YES"]: if isCompatible(pyQgisVersion(), qgisMinimumVersion, qgisMaximumVersion): # add the plugin to the cache plugins.addFromRepository(plugin) self.mRepositories[reposName]["state"] = 2 else: # no plugin metadata found self.mRepositories[reposName]["state"] = 3 if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Server response is 200 OK, but doesn't contain plugin metatada. This is most likely caused by a proxy or a wrong repository URL. You can configure proxy settings in QGIS options.") else: self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Status code:") + " {} {}".format( reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute) ) self.repositoryFetched.emit(reposName) # is the checking done? if not self.fetchingInProgress(): self.checkingDone.emit() reply.deleteLater()
def get_certificate(cls): # Set a value in case of use s = "" qba = QByteArray(s) return qba