Ejemplo n.º 1
0
    def saveToPostGIS(self):
        dlg = PostgisTableSelector(self, self.parameter.name().lower())
        dlg.exec_()
        if dlg.connection:
            self.use_temporary = False
            settings = QgsSettings()
            mySettings = '/PostgreSQL/connections/' + dlg.connection
            dbname = settings.value(mySettings + '/database')
            user = settings.value(mySettings + '/username')
            host = settings.value(mySettings + '/host')
            port = settings.value(mySettings + '/port')
            password = settings.value(mySettings + '/password')
            uri = QgsDataSourceUri()
            uri.setConnection(host, str(port), dbname, user, password)
            uri.setDataSource(dlg.schema, dlg.table,
                              "the_geom" if isinstance(self.parameter, QgsProcessingParameterFeatureSink) and self.parameter.hasGeometry() else None)

            connInfo = uri.connectionInfo()
            (success, user, passwd) = QgsCredentials.instance().get(connInfo, None, None)
            if success:
                QgsCredentials.instance().put(connInfo, user, passwd)
            self.leText.setText("postgis:" + uri.uri())

            self.skipOutputChanged.emit(False)
            self.destinationChanged.emit()
Ejemplo n.º 2
0
    def connect(self, parent=None):
        conn_name = self.connectionName()
        settings = QgsSettings()
        settings.beginGroup(u"/%s/%s" % (self.connectionSettingsKey(), conn_name))

        if not settings.contains("database"):  # non-existent entry?
            raise InvalidDataException(self.tr('There is no defined database connection "{0}".').format(conn_name))

        from qgis.core import QgsDataSourceUri

        uri = QgsDataSourceUri()

        settingsList = ["service", "host", "port", "database", "username", "password", "authcfg"]
        service, host, port, database, username, password, authcfg = [settings.value(x, "", type=str) for x in settingsList]

        useEstimatedMetadata = settings.value("estimatedMetadata", False, type=bool)
        sslmode = settings.value("sslmode", QgsDataSourceUri.SslPrefer, type=int)

        settings.endGroup()

        if hasattr(authcfg, 'isNull') and authcfg.isNull():
            authcfg = ''

        if service:
            uri.setConnection(service, database, username, password, sslmode, authcfg)
        else:
            uri.setConnection(host, port, database, username, password, sslmode, authcfg)

        uri.setUseEstimatedMetadata(useEstimatedMetadata)

        try:
            return self.connectToUri(uri)
        except ConnectionError:
            return False
Ejemplo n.º 3
0
    def load(self):
        """ populate the mRepositories dict"""
        self.mRepositories = {}
        settings = QgsSettings()
        settings.beginGroup(reposGroup)
        # first, update repositories in QgsSettings if needed
        officialRepoPresent = False
        for key in settings.childGroups():
            url = settings.value(key + "/url", "", type=str)
            if url == officialRepo[1]:
                officialRepoPresent = True
        if not officialRepoPresent:
            settings.setValue(officialRepo[0] + "/url", officialRepo[1])

        for key in settings.childGroups():
            self.mRepositories[key] = {}
            self.mRepositories[key]["url"] = settings.value(key + "/url", "", type=str)
            self.mRepositories[key]["authcfg"] = settings.value(key + "/authcfg", "", type=str)
            self.mRepositories[key]["enabled"] = settings.value(key + "/enabled", True, type=bool)
            self.mRepositories[key]["valid"] = settings.value(key + "/valid", True, type=bool)
            self.mRepositories[key]["Relay"] = Relay(key)
            self.mRepositories[key]["xmlData"] = None
            self.mRepositories[key]["state"] = 0
            self.mRepositories[key]["error"] = ""
        settings.endGroup()
Ejemplo n.º 4
0
def uri_from_name(conn_name):
    settings = QgsSettings()
    settings.beginGroup(u"/PostgreSQL/connections/%s" % conn_name)

    if not settings.contains("database"):  # non-existent entry?
        raise QgsProcessingException(QCoreApplication.translate("PostGIS", 'There is no defined database connection "{0}".').format(conn_name))

    uri = QgsDataSourceUri()

    settingsList = ["service", "host", "port", "database", "username", "password", "authcfg"]
    service, host, port, database, username, password, authcfg = [settings.value(x, "", type=str) for x in settingsList]

    useEstimatedMetadata = settings.value("estimatedMetadata", False, type=bool)
    try:
        sslmode = settings.value("sslmode", QgsDataSourceUri.SslPrefer, type=int)
    except TypeError:
        sslmode = QgsDataSourceUri.SslPrefer

    settings.endGroup()

    if hasattr(authcfg, 'isNull') and authcfg.isNull():
        authcfg = ''

    if service:
        uri.setConnection(service, database, username, password, sslmode, authcfg)
    else:
        uri.setConnection(host, port, database, username, password, sslmode, authcfg)

    uri.setUseEstimatedMetadata(useEstimatedMetadata)

    return uri
Ejemplo n.º 5
0
    def selectFile(self):
        output = self.alg.parameterDefinition('OUTPUT')
        fileFilter = getFileFilter(output)

        settings = QgsSettings()
        if settings.contains('/Processing/LastOutputPath'):
            path = settings.value('/Processing/LastOutputPath')
        else:
            path = ProcessingConfig.getSetting(ProcessingConfig.OUTPUT_FOLDER)
        lastEncoding = settings.value('/Processing/encoding', 'System')
        fileDialog = QgsEncodingFileDialog(self,
                                           self.tr('Save file'),
                                           path,
                                           fileFilter,
                                           lastEncoding)
        fileDialog.setFileMode(QFileDialog.AnyFile)
        fileDialog.setAcceptMode(QFileDialog.AcceptSave)
        fileDialog.setOption(QFileDialog.DontConfirmOverwrite, False)
        if fileDialog.exec_() == QDialog.Accepted:
            files = fileDialog.selectedFiles()
            encoding = str(fileDialog.encoding())
            output.encoding = encoding
            filename = str(files[0])
            selectedFileFilter = str(fileDialog.selectedNameFilter())
            if not filename.lower().endswith(
                    tuple(re.findall("\\*(\\.[a-z]{1,10})", fileFilter))):
                ext = re.search("\\*(\\.[a-z]{1,10})", selectedFileFilter)
                if ext:
                    filename = filename + ext.group(1)
            self.leOutputFile.setText(filename)
            settings.setValue('/Processing/LastOutputPath',
                              os.path.dirname(filename))
            settings.setValue('/Processing/encoding', encoding)
Ejemplo n.º 6
0
    def initLexer(self):
        if self.lexerType == self.LEXER_PYTHON:
            self.lexer = QsciLexerPython()

            colorDefault = QColor('#2e3436')
            colorComment = QColor('#c00')
            colorCommentBlock = QColor('#3465a4')
            colorNumber = QColor('#4e9a06')
            colorType = QColor('#4e9a06')
            colorKeyword = QColor('#204a87')
            colorString = QColor('#ce5c00')

            self.lexer.setDefaultFont(self.defaultFont)
            self.lexer.setDefaultColor(colorDefault)

            self.lexer.setColor(colorComment, 1)
            self.lexer.setColor(colorNumber, 2)
            self.lexer.setColor(colorString, 3)
            self.lexer.setColor(colorString, 4)
            self.lexer.setColor(colorKeyword, 5)
            self.lexer.setColor(colorString, 6)
            self.lexer.setColor(colorString, 7)
            self.lexer.setColor(colorType, 8)
            self.lexer.setColor(colorCommentBlock, 12)
            self.lexer.setColor(colorString, 15)

            self.lexer.setFont(self.italicFont, 1)
            self.lexer.setFont(self.boldFont, 5)
            self.lexer.setFont(self.boldFont, 8)
            self.lexer.setFont(self.italicFont, 12)

            self.api = QsciAPIs(self.lexer)

            settings = QgsSettings()
            useDefaultAPI = bool(settings.value('pythonConsole/preloadAPI',
                                                True))
            if useDefaultAPI:
                # Load QGIS API shipped with Python console
                self.api.loadPrepared(
                    os.path.join(QgsApplication.pkgDataPath(),
                                 'python', 'qsci_apis', 'pyqgis.pap'))
            else:
                # Load user-defined API files
                apiPaths = settings.value('pythonConsole/userAPI', [])
                for path in apiPaths:
                    self.api.load(path)
                self.api.prepare()
                self.lexer.setAPIs(self.api)
        elif self.lexerType == self.LEXER_R:
            # R lexer
            self.lexer = LexerR()

        self.setLexer(self.lexer)
Ejemplo n.º 7
0
    def __init__(self, iface, parent=None):
        QMainWindow.__init__(self, parent)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setupUi()
        self.iface = iface

        # restore the window state
        settings = QgsSettings()
        self.restoreGeometry(settings.value("/DB_Manager/mainWindow/geometry", QByteArray(), type=QByteArray))
        self.restoreState(settings.value("/DB_Manager/mainWindow/windowState", QByteArray(), type=QByteArray))

        self.tabs.currentChanged.connect(self.tabChanged)
        self.tree.selectedItemChanged.connect(self.itemChanged)
        self.itemChanged(None)
Ejemplo n.º 8
0
    def __init__(self, parent=None):
        super(LayerPreview, self).__init__(parent)
        self.parent = parent
        self.setCanvasColor(QColor(255, 255, 255))

        self.item = None
        self.dirty = False
        self.currentLayerId = None

        # reuse settings from QGIS
        settings = QgsSettings()
        self.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type=bool))
        zoomFactor = settings.value("/qgis/zoom_factor", 2, type=float)
        self.setWheelFactor(zoomFactor)
Ejemplo n.º 9
0
    def execute(self):
        settings = QgsSettings()
        lastDir = settings.value('Processing/lastModelsDir', '')
        filename, selected_filter = QFileDialog.getOpenFileName(self.toolbox,
                                                                self.tr('Open model', 'AddModelFromFileAction'), lastDir,
                                                                self.tr('Processing model files (*.model *.MODEL)', 'AddModelFromFileAction'))
        if filename:
            try:
                settings.setValue('Processing/lastModelsDir',
                                  QFileInfo(filename).absoluteDir().absolutePath())

                ModelerAlgorithm.fromFile(filename)
            except WrongModelException:
                QMessageBox.warning(
                    self.toolbox,
                    self.tr('Error reading model', 'AddModelFromFileAction'),
                    self.tr('The selected file does not contain a valid model', 'AddModelFromFileAction'))
                return
            except:
                QMessageBox.warning(self.toolbox,
                                    self.tr('Error reading model', 'AddModelFromFileAction'),
                                    self.tr('Cannot read file', 'AddModelFromFileAction'))
                return
            destFilename = os.path.join(ModelerUtils.modelsFolders()[0], os.path.basename(filename))
            shutil.copyfile(filename, destFilename)
            QgsApplication.processingRegistry().providerById('model').refreshAlgorithms()
def main():
    datestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    if QT5:
        ini_out_dir = QStandardPaths.writableLocation(QStandardPaths.DesktopLocation)
    else:
        ini_out_dir = QDesktopServices.storageLocation(QDesktopServices.DesktopLocation)
    ini_name = 'org.qgis.{0}-settings_{1}.ini'.format(QGIS_APP_NAME, datestamp)
    ini_out = QDir(ini_out_dir).absoluteFilePath(ini_name)

    if not os.path.exists(ini_out_dir):
        print('INI output directory does not exist: {0}'.format(ini_out_dir))
        return

    if not os.access(ini_out_dir, os.W_OK | os.X_OK):
        print('INI output directory is not writeable: {0}'.format(ini_out_dir))
        return

    # QGIS settings
    if HAS_QGSSETTINGS:
        qgis_settings = QgsSettings()
    else:
        qgis_settings = QSettings()

    # Output INI settings
    ini_settings = QSettings(ini_out, QSettings.IniFormat)

    qgis_keys = qgis_settings.allKeys()
    for k in qgis_keys:
        ini_settings.setValue(k, qgis_settings.value(k))

    ini_settings.sync()

    print("Settings output to: {0}".format(QDir.toNativeSeparators(ini_out)))
Ejemplo n.º 11
0
    def chooseOutputFile(self):
        # get last used dir
        settings = QgsSettings()
        lastUsedDir = settings.value(self.lastUsedVectorDirSettingsKey, ".")

        # get selected filter
        selectedFilter = self.cboFileFormat.currentData()

        # ask for a filename
        filename, filter = QFileDialog.getSaveFileName(self, self.tr("Choose where to save the file"), lastUsedDir,
                                                       selectedFilter)
        if filename == "":
            return

        filterString = QgsVectorFileWriter.filterForDriver(selectedFilter)
        ext = filterString[filterString.find('.'):]
        ext = ext[:ext.find(' ')]

        if not filename.lower().endswith(ext):
            filename += ext

        # store the last used dir
        settings.setValue(self.lastUsedVectorDirSettingsKey, QFileInfo(filename).filePath())

        self.editOutputFile.setText(filename)
Ejemplo n.º 12
0
def addBoundlessRepository():
    """Add Boundless plugin repository to list of the available
       plugin repositories if it is not presented here
    """
    repoUrl = pluginSetting('repoUrl')

    if repoUrl == '':
        repoUrl = setRepositoryUrl()

    if isRepositoryInDirectory():
        return

    settings = QSettings()
    settings.beginGroup(reposGroup)
    hasBoundlessRepository = False
    for repo in settings.childGroups():
        url = settings.value(repo + '/url', '')
        if url == repoUrl:
            hasBoundlessRepository = True

    # Boundless repository not found, so we add it to the list
    if not hasBoundlessRepository:
        settings.setValue(boundlessRepoName + '/url', repoUrl)
        settings.setValue(boundlessRepoName + '/authcfg', '')
    settings.endGroup()
Ejemplo n.º 13
0
 def markNews(self):
     settings = QSettings()
     seenPlugins = settings.value(seenPluginGroup, list(self.plugins.keys()), str)
     if len(seenPlugins) > 0:
         for i in list(self.plugins.keys()):
             if seenPlugins.count(i) == 0 and self.plugins[i]['status'] == 'not installed':
                 self.plugins[i]['status'] = 'new'
Ejemplo n.º 14
0
 def browse(self):
     """ open save layer dialog """
     settings = QgsSettings()
     dirName = settings.value("/UI/lastShapefileDir")
     encode = settings.value("/UI/encoding")
     fileDialog = QgsEncodingFileDialog(self, "Output shape file", dirName,
                                        "Shape file (*.shp)", encode)
     fileDialog.setDefaultSuffix("shp")
     fileDialog.setFileMode(QtWidgets.QFileDialog.AnyFile)
     fileDialog.setAcceptMode(QtWidgets.QFileDialog.AcceptSave)
     #fileDialog.setConfirmOverwrite(True)
     if not fileDialog.exec_() == QtWidgets.QDialog.Accepted:
         return
     files = fileDialog.selectedFiles()
     self.pointEdit.setText(files[0])
     self.encoding = fileDialog.encoding()
Ejemplo n.º 15
0
    def chooseInputFile(self):
        vectorFormats = QgsProviderRegistry.instance().fileVectorFilters()
        # get last used dir and format
        settings = QgsSettings()
        lastDir = settings.value("/db_manager/lastUsedDir", "")
        lastVectorFormat = settings.value("/UI/lastVectorFileFilter", "")
        # ask for a filename
        filename, lastVectorFormat = QFileDialog.getOpenFileName(self, self.tr("Choose the file to import"),
                                                                 lastDir, vectorFormats, lastVectorFormat)
        if filename == "":
            return
        # store the last used dir and format
        settings.setValue("/db_manager/lastUsedDir", QFileInfo(filename).filePath())
        settings.setValue("/UI/lastVectorFileFilter", lastVectorFormat)

        self.cboInputLayer.setEditText(filename)
Ejemplo n.º 16
0
 def updateSeenPluginsList(self):
     settings = QSettings()
     seenPlugins = settings.value(seenPluginGroup, list(self.plugins.keys()), str)
     for i in list(self.plugins.keys()):
         if seenPlugins.count(i) == 0:
             seenPlugins += [i]
     settings.setValue(seenPluginGroup, seenPlugins)
Ejemplo n.º 17
0
def createContext(feedback=None):
    """
    Creates a default processing context

    :param feedback: Optional existing QgsProcessingFeedback object, or None to use a default feedback object
    :type feedback: Optional[QgsProcessingFeedback]

    :returns: New QgsProcessingContext object
    :rtype: QgsProcessingContext
    """
    context = QgsProcessingContext()
    context.setProject(QgsProject.instance())
    context.setFeedback(feedback)

    invalid_features_method = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
    if invalid_features_method is None:
        invalid_features_method = QgsFeatureRequest.GeometryAbortOnInvalid
    context.setInvalidGeometryCheck(invalid_features_method)

    settings = QgsSettings()
    context.setDefaultEncoding(settings.value("/Processing/encoding", "System"))

    context.setExpressionContext(createExpressionContext())

    return context
Ejemplo n.º 18
0
 def execute(self):
     settings = QgsSettings()
     lastDir = settings.value('Processing/lastScriptsDir', '')
     filenames, selected_filter = QFileDialog.getOpenFileNames(self.toolbox,
                                                               self.tr('Script files', 'AddScriptFromFileAction'), lastDir,
                                                               self.tr('Script files (*.py *.PY)', 'AddScriptFromFileAction'))
     if filenames:
         validAlgs = 0
         wrongAlgs = []
         for filename in filenames:
             try:
                 settings.setValue('Processing/lastScriptsDir',
                                   QFileInfo(filename).absoluteDir().absolutePath())
                 script = ScriptAlgorithm(filename)
                 destFilename = os.path.join(ScriptUtils.scriptsFolders()[0], os.path.basename(filename))
                 with open(destFilename, 'w') as f:
                     f.write(script.script)
                 validAlgs += 1
             except WrongScriptException:
                 wrongAlgs.append(os.path.basename(filename))
         if validAlgs:
             QgsApplication.processingRegistry().providerById('script').refreshAlgorithms()
         if wrongAlgs:
             QMessageBox.warning(self.toolbox,
                                 self.tr('Error reading scripts', 'AddScriptFromFileAction'),
                                 self.tr('The following files do not contain a valid script:\n-', 'AddScriptFromFileAction') +
                                 "\n-".join(wrongAlgs))
Ejemplo n.º 19
0
    def getVectorWriter(self, fields, geomType, crs, context):
        """Returns a suitable writer to which features can be added as
        a result of the algorithm. Use this to transparently handle
        output values instead of creating your own method.

        Executing this method might modify the object, adding additional
        information to it, so the writer can be later accessed and
        processed within QGIS. It should be called just once, since a
        new call might result in previous data being replaced, thus
        rendering a previously obtained writer useless.

        @param fields   a list  of QgsField
        @param geomType a suitable geometry type, as it would be passed
                        to a QgsVectorFileWriter constructor
        @param crs      the crs of the layer to create

        @return writer  instance of the vector writer class
        :param context:
        """

        if self.encoding is None:
            settings = QgsSettings()
            self.encoding = settings.value('/Processing/encoding', 'System', str)

        w, w_dest = QgsProcessingUtils.createFeatureSink(self.value, context, fields, geomType, crs, {'fileEncoding': self.encoding})
        self.value = w_dest
        return w
Ejemplo n.º 20
0
    def showSelectionDialog(self):
        # Find the file dialog's working directory
        settings = QgsSettings()
        text = self.leText.text()
        if os.path.isdir(text):
            path = text
        elif os.path.isdir(os.path.dirname(text)):
            path = os.path.dirname(text)
        elif settings.contains('/Processing/LastInputPath'):
            path = settings.value('/Processing/LastInputPath')
        else:
            path = ''

        if self.isFolder:
            folder = QFileDialog.getExistingDirectory(self,
                                                      self.tr('Select Folder'), path)
            if folder:
                self.leText.setText(folder)
                settings.setValue('/Processing/LastInputPath',
                                  os.path.dirname(folder))
        else:
            filenames, selected_filter = QFileDialog.getOpenFileNames(self,
                                                                      self.tr('Select File'), path, self.tr('{} files').format(self.ext.upper()) + ' (*.' + self.ext + self.tr(');;All files (*.*)'))
            if filenames:
                self.leText.setText(u';'.join(filenames))
                settings.setValue('/Processing/LastInputPath',
                                  os.path.dirname(filenames[0]))
Ejemplo n.º 21
0
    def saveToGeopackage(self):
        file_filter = self.tr('GeoPackage files (*.gpkg);;All files (*.*)', 'OutputFile')

        settings = QgsSettings()
        if settings.contains('/Processing/LastOutputPath'):
            path = settings.value('/Processing/LastOutputPath')
        else:
            path = ProcessingConfig.getSetting(ProcessingConfig.OUTPUT_FOLDER)

        filename, filter = QFileDialog.getSaveFileName(self, self.tr("Save to GeoPackage"), path,
                                                       file_filter, options=QFileDialog.DontConfirmOverwrite)

        if not filename:
            return

        layer_name, ok = QInputDialog.getText(self, self.tr('Save to GeoPackage'), self.tr('Layer name'), text=self.parameter.name().lower())
        if ok:
            self.use_temporary = False
            if not filename.lower().endswith('.gpkg'):
                filename += '.gpkg'
            settings.setValue('/Processing/LastOutputPath',
                              os.path.dirname(filename))

            uri = QgsDataSourceUri()
            uri.setDatabase(filename)
            uri.setDataSource('', layer_name,
                              'geom' if isinstance(self.parameter, QgsProcessingParameterFeatureSink) and self.parameter.hasGeometry() else None)
            self.leText.setText("ogr:" + uri.uri())

            self.skipOutputChanged.emit(False)
            self.destinationChanged.emit()
Ejemplo n.º 22
0
    def saveToSpatialite(self):
        fileFilter = self.tr('SpatiaLite files (*.sqlite)', 'OutputFile')

        settings = QgsSettings()
        if settings.contains('/Processing/LastOutputPath'):
            path = settings.value('/Processing/LastOutputPath')
        else:
            path = ProcessingConfig.getSetting(ProcessingConfig.OUTPUT_FOLDER)

        fileDialog = QgsEncodingFileDialog(
            self, self.tr('Save SpatiaLite'), path, fileFilter, self.encoding)
        fileDialog.setFileMode(QFileDialog.AnyFile)
        fileDialog.setAcceptMode(QFileDialog.AcceptSave)
        fileDialog.setOption(QFileDialog.DontConfirmOverwrite, True)

        if fileDialog.exec_() == QDialog.Accepted:
            self.use_temporary = False
            files = fileDialog.selectedFiles()
            self.encoding = str(fileDialog.encoding())
            fileName = str(files[0])
            selectedFileFilter = str(fileDialog.selectedNameFilter())
            if not fileName.lower().endswith(
                    tuple(re.findall("\\*(\\.[a-z]{1,10})", fileFilter))):
                ext = re.search("\\*(\\.[a-z]{1,10})", selectedFileFilter)
                if ext:
                    fileName += ext.group(1)
            settings.setValue('/Processing/LastOutputPath',
                              os.path.dirname(fileName))
            settings.setValue('/Processing/encoding', self.encoding)

            uri = QgsDataSourceUri()
            uri.setDatabase(fileName)
            uri.setDataSource('', self.parameter.name().lower(),
                              'the_geom' if isinstance(self.parameter, QgsProcessingParameterFeatureSink) and self.parameter.hasGeometry() else None)
            self.leText.setText("spatialite:" + uri.uri())
Ejemplo n.º 23
0
    def showFileSelectionDialog(self):
        settings = QgsSettings()
        text = str(self.text.text())
        if os.path.isdir(text):
            path = text
        elif os.path.isdir(os.path.dirname(text)):
            path = os.path.dirname(text)
        elif settings.contains('/Processing/LastInputPath'):
            path = str(settings.value('/Processing/LastInputPath'))
        else:
            path = ''

        ret, selected_filter = QFileDialog.getOpenFileNames(self, self.tr('Select Files'), path,
                                                            getFileFilter(self.param))
        if ret:
            files = list(ret)
            settings.setValue('/Processing/LastInputPath',
                              os.path.dirname(str(files[0])))
            for i, filename in enumerate(files):
                files[i] = dataobjects.getRasterSublayer(filename, self.param)
            if len(files) == 1:
                self.text.setText(files[0])
                self.textEditingFinished()
            else:
                if isinstance(self.param, QgsProcessingParameterMultipleLayers):
                    self.text.setText(';'.join(str(f) for f in files))
                else:
                    rowdif = len(files) - (self._table().rowCount() - self.row)
                    for i in range(rowdif):
                        self._panel().addRow()
                    for i, f in enumerate(files):
                        self._table().cellWidget(i + self.row,
                                                 self.col).setValue(f)
Ejemplo n.º 24
0
def createContext():
    """
    Creates a default processing context
    """
    context = QgsProcessingContext()
    context.setProject(QgsProject.instance())

    invalid_features_method = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
    if invalid_features_method is None:
        invalid_features_method = QgsFeatureRequest.GeometryAbortOnInvalid
    context.setInvalidGeometryCheck(invalid_features_method)

    def raise_error(f):
        raise GeoAlgorithmExecutionException(QCoreApplication.translate("FeatureIterator",
                                                                        'Features with invalid geometries found. Please fix these geometries or specify the "Ignore invalid input features" flag'))

    context.setInvalidGeometryCallback(raise_error)

    def raise_transform_error(f):
        raise GeoAlgorithmExecutionException(QCoreApplication.translate("FeatureIterator",
                                                                        'Encountered a transform error when reprojecting feature with id {}.'.format(f.id())))
    context.setTransformErrorCallback(raise_transform_error)

    settings = QgsSettings()
    context.setDefaultEncoding(settings.value("/Processing/encoding", "System"))

    return context
Ejemplo n.º 25
0
    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()))
Ejemplo n.º 26
0
    def showFileDialog(self, seldir):
        settings = QgsSettings()
        text = str(self.text.text())
        if os.path.isdir(text):
            path = text
        elif not seldir and os.path.isdir(os.path.dirname(text)):
            path = os.path.dirname(text)
        elif settings.contains('/Processing/LastInputPath'):
            path = str(settings.value('/Processing/LastInputPath'))
        else:
            path = ''

        if not seldir:
            ret, selected_filter = QFileDialog.getOpenFileNames(
                self, self.tr('Select Files'), path, getFileFilter(self.param)
            )
        else:
            ret = QFileDialog.getExistingDirectory(self, self.tr('Select Directory'), path)

        if ret:
            if seldir:
                settings.setValue('/Processing/LastInputPath', ret)

                files = []
                for pp in Path(ret).rglob("*"):
                    if not pp.is_file():
                        continue

                    p = pp.as_posix()

                    if ((isinstance(self.param, QgsProcessingParameterRasterLayer)
                         or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType() == QgsProcessing.TypeRaster)) and
                            not QgsRasterLayer.isValidRasterFileName(p)):
                        continue

                    files.append(p)

                if not files:
                    return

            else:
                files = list(ret)
                settings.setValue('/Processing/LastInputPath', os.path.dirname(str(files[0])))

            for i, filename in enumerate(files):
                files[i] = dataobjects.getRasterSublayer(filename, self.param)
            if len(files) == 1:
                self.text.setText(files[0])
                self.textEditingFinished()
            else:
                if isinstance(self.param, QgsProcessingParameterMultipleLayers):
                    self.text.setText(';'.join(str(f) for f in files))
                else:
                    rowdif = len(files) - (self._table().rowCount() - self.row)
                    for i in range(rowdif):
                        self._panel().addRow()
                    for i, f in enumerate(files):
                        self._table().cellWidget(i + self.row,
                                                 self.col).setValue(f)
Ejemplo n.º 27
0
    def installFromZipFile(self, filePath):
        if not os.path.isfile(filePath):
            return

        settings = QgsSettings()
        settings.setValue(settingsGroup + '/lastZipDirectory',
                          QFileInfo(filePath).absoluteDir().absolutePath())

        error = False
        infoString = None

        with zipfile.ZipFile(filePath, 'r') as zf:
            pluginName = os.path.split(zf.namelist()[0])[0]

        pluginFileName = os.path.splitext(os.path.basename(filePath))[0]

        pluginsDirectory = qgis.utils.home_plugin_path
        if not QDir(pluginsDirectory).exists():
            QDir().mkpath(pluginsDirectory)

        # If the target directory already exists as a link,
        # remove the link without resolving
        QFile(os.path.join(pluginsDirectory, pluginFileName)).remove()

        try:
            # Test extraction. If fails, then exception will be raised
            # and no removing occurs
            unzip(str(filePath), str(pluginsDirectory))
            # Removing old plugin files if exist
            removeDir(QDir.cleanPath(os.path.join(pluginsDirectory, pluginFileName)))
            # Extract new files
            unzip(str(filePath), str(pluginsDirectory))
        except:
            error = True
            infoString = (self.tr("Plugin installation failed"),
                          self.tr("Failed to unzip the plugin package\n{}.\nProbably it is broken".format(filePath)))

        if infoString is None:
            updateAvailablePlugins()
            loadPlugin(pluginName)
            plugins.getAllInstalled(testLoad=True)
            plugins.rebuild()

            if settings.contains('/PythonPlugins/' + pluginName):
                if settings.value('/PythonPlugins/' + pluginName, False, bool):
                    startPlugin(pluginName)
                    reloadPlugin(pluginName)
                else:
                    unloadPlugin(pluginName)
                    loadPlugin(pluginName)
            else:
                if startPlugin(pluginName):
                    settings.setValue('/PythonPlugins/' + pluginName, True)
            infoString = (self.tr("Plugin installed successfully"), "")

        if infoString[0]:
            level = error and QgsMessageBar.CRITICAL or QgsMessageBar.INFO
            msg = "<b>%s:</b>%s" % (infoString[0], infoString[1])
            iface.pluginManagerInterface().pushMessage(msg, level)
Ejemplo n.º 28
0
 def markNews(self):
     """ mark all new plugins as new """
     settings = QgsSettings()
     seenPlugins = settings.value(settingsGroup + '/seen_plugins', list(self.mPlugins.keys()), type=str)
     if len(seenPlugins) > 0:
         for i in list(self.mPlugins.keys()):
             if seenPlugins.count(i) == 0 and self.mPlugins[i]["status"] == "not installed":
                 self.mPlugins[i]["status"] = "new"
Ejemplo n.º 29
0
 def loadAPIFile(self):
     settings = QgsSettings()
     lastDirPath = settings.value("pythonConsole/lastDirAPIPath", "", type=str)
     fileAPI, selected_filter = QFileDialog.getOpenFileName(
         self, "Open API File", lastDirPath, "API file (*.api)")
     if fileAPI:
         self.addAPI(fileAPI)
         settings.setValue("pythonConsole/lastDirAPIPath", fileAPI)
Ejemplo n.º 30
0
 def updateSeenPluginsList(self):
     """ update the list of all seen plugins """
     settings = QgsSettings()
     seenPlugins = settings.value(settingsGroup + '/seen_plugins', list(self.mPlugins.keys()), type=str)
     for i in list(self.mPlugins.keys()):
         if seenPlugins.count(i) == 0:
             seenPlugins += [i]
     settings.setValue(settingsGroup + '/seen_plugins', seenPlugins)
Ejemplo n.º 31
0
class ShellOutputScintilla(QsciScintilla):

    def __init__(self, parent=None):
        super(ShellOutputScintilla, self).__init__(parent)
        self.parent = parent
        self.shell = self.parent.shell

        self.settings = QgsSettings()

        # Creates layout for message bar
        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # messageBar instance
        self.infoBar = QgsMessageBar()
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        # Enable non-ascii chars for editor
        self.setUtf8(True)

        sys.stdout = writeOut(self, sys.stdout)
        sys.stderr = writeOut(self, sys.stderr, "_traceback")

        self.insertInitText()
        self.refreshSettingsOutput()
        self.setReadOnly(True)

        # Set the default font
        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        self.setFont(font)
        self.setMarginsFont(font)
        # Margin 0 is used for line numbers
        self.setMarginWidth(0, 0)
        self.setMarginWidth(1, 0)
        self.setMarginWidth(2, 0)
        #fm = QFontMetrics(font)
        self.setMarginsFont(font)
        self.setMarginWidth(1, "00000")
        self.setMarginLineNumbers(1, True)
        self.setMarginsForegroundColor(QColor("#3E3EE3"))
        self.setMarginsBackgroundColor(QColor("#f9f9f9"))
        self.setCaretLineVisible(True)
        self.setCaretWidth(0)

        self.setMinimumHeight(120)

        self.setWrapMode(QsciScintilla.WrapCharacter)
        self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)

        self.runScut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_E), self)
        self.runScut.setContext(Qt.WidgetShortcut)
        self.runScut.activated.connect(self.enteredSelected)
        # Reimplemented copy action to prevent paste prompt (>>>,...) in command view
        self.copyShortcut = QShortcut(QKeySequence.Copy, self)
        self.copyShortcut.activated.connect(self.copy)
        self.selectAllShortcut = QShortcut(QKeySequence.SelectAll, self)
        self.selectAllShortcut.activated.connect(self.selectAll)

    def insertInitText(self):
        txtInit = QCoreApplication.translate("PythonConsole",
                                             "Python Console \n"
                                             "Use iface to access QGIS API interface or Type help(iface) for more info")

        # some translation string for the console header ends without '\n'
        # and the first command in console will be appended at the header text.
        # The following code add a '\n' at the end of the string if not present.
        if txtInit.endswith('\n'):
            self.setText(txtInit)
        else:
            self.setText(txtInit + '\n')

    def refreshSettingsOutput(self):
        # Set Python lexer
        self.setLexers()
        caretLineColor = self.settings.value("pythonConsole/caretLineColor", QColor("#fcf3ed"))
        cursorColor = self.settings.value("pythonConsole/cursorColor", QColor(Qt.black))
        self.setCaretLineBackgroundColor(caretLineColor)
        self.setCaretForegroundColor(cursorColor)

    def setLexers(self):
        self.lexer = QsciLexerPython()

        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)

        loadFont = self.settings.value("pythonConsole/fontfamilytext")
        if loadFont:
            font.setFamily(loadFont)
        fontSize = self.settings.value("pythonConsole/fontsize", type=int)
        if fontSize:
            font.setPointSize(fontSize)

        self.lexer.setDefaultFont(font)
        self.lexer.setDefaultColor(QColor(self.settings.value("pythonConsole/defaultFontColor", QColor(Qt.black))))
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/commentFontColor", QColor(Qt.gray))), 1)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/keywordFontColor", QColor(Qt.darkGreen))), 5)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/classFontColor", QColor(Qt.blue))), 8)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/methodFontColor", QColor(Qt.darkGray))), 9)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/decorFontColor", QColor(Qt.darkBlue))), 15)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/commentBlockFontColor", QColor(Qt.gray))), 12)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/singleQuoteFontColor", QColor(Qt.blue))), 4)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/doubleQuoteFontColor", QColor(Qt.blue))), 3)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/tripleSingleQuoteFontColor", QColor(Qt.blue))), 6)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/tripleDoubleQuoteFontColor", QColor(Qt.blue))), 7)
        self.lexer.setColor(QColor(Qt.red), 14)
        self.lexer.setFont(font, 1)
        self.lexer.setFont(font, 2)
        self.lexer.setFont(font, 3)
        self.lexer.setFont(font, 4)

        for style in range(0, 33):
            paperColor = QColor(self.settings.value("pythonConsole/paperBackgroundColor", QColor(Qt.white)))
            self.lexer.setPaper(paperColor, style)

        self.setLexer(self.lexer)

    def clearConsole(self):
        self.setText('')
        self.insertInitText()
        self.shell.setFocus()

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        iconRun = QgsApplication.getThemeIcon("console/iconRunConsole.png")
        iconClear = QgsApplication.getThemeIcon("console/iconClearConsole.png")
        iconHideTool = QgsApplication.getThemeIcon("console/iconHideToolConsole.png")
        iconSettings = QgsApplication.getThemeIcon("console/iconSettingsConsole.png")
        menu.addAction(iconHideTool,
                       QCoreApplication.translate("PythonConsole", "Hide/Show Toolbar"),
                       self.hideToolBar)
        menu.addSeparator()
        showEditorAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Show Editor"),
            self.showEditor)
        menu.addSeparator()
        runAction = menu.addAction(iconRun,
                                   QCoreApplication.translate("PythonConsole", "Enter Selected"),
                                   self.enteredSelected,
                                   QKeySequence(Qt.CTRL + Qt.Key_E))
        clearAction = menu.addAction(iconClear,
                                     QCoreApplication.translate("PythonConsole", "Clear Console"),
                                     self.clearConsole)
        menu.addSeparator()
        copyAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Copy"),
            self.copy, QKeySequence.Copy)
        selectAllAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Select All"),
            self.selectAll, QKeySequence.SelectAll)
        menu.addSeparator()
        menu.addAction(iconSettings,
                       QCoreApplication.translate("PythonConsole", "Options..."),
                       self.parent.openSettings)
        runAction.setEnabled(False)
        clearAction.setEnabled(False)
        copyAction.setEnabled(False)
        selectAllAction.setEnabled(False)
        showEditorAction.setEnabled(True)
        if self.hasSelectedText():
            runAction.setEnabled(True)
            copyAction.setEnabled(True)
        if not self.text(3) == '':
            selectAllAction.setEnabled(True)
            clearAction.setEnabled(True)
        if self.parent.tabEditorWidget.isVisible():
            showEditorAction.setEnabled(False)
        menu.exec_(self.mapToGlobal(e.pos()))

    def hideToolBar(self):
        tB = self.parent.toolBar
        tB.hide() if tB.isVisible() else tB.show()
        self.shell.setFocus()

    def showEditor(self):
        Ed = self.parent.splitterObj
        if not Ed.isVisible():
            Ed.show()
            self.parent.showEditorButton.setChecked(True)
        self.shell.setFocus()

    def copy(self):
        """Copy text to clipboard... or keyboard interrupt"""
        if self.hasSelectedText():
            text = self.selectedText()
            text = text.replace('>>> ', '').replace('... ', '').strip()  # removing prompts
            QApplication.clipboard().setText(text)
        else:
            raise KeyboardInterrupt

    def enteredSelected(self):
        cmd = self.selectedText()
        self.shell.insertFromDropPaste(cmd)
        self.shell.entered()

    def keyPressEvent(self, e):
        # empty text indicates possible shortcut key sequence so stay in output
        txt = e.text()
        if len(txt) and txt >= " ":
            self.shell.append(txt)
            self.shell.move_cursor_to_end()
            self.shell.setFocus()
            e.ignore()
        else:
            # possible shortcut key sequence, accept it
            e.accept()

    def widgetMessageBar(self, iface, text):
        timeout = iface.messageTimeout()
        self.infoBar.pushMessage(text, QgsMessageBar.INFO, timeout)
Ejemplo n.º 32
0
    def initLexer(self):
        settings = QgsSettings()
        self.lexer = QsciLexerPython()

        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)

        loadFont = settings.value("pythonConsole/fontfamilytextEditor")
        if loadFont:
            font.setFamily(loadFont)
        fontSize = settings.value("pythonConsole/fontsizeEditor", type=int)
        if fontSize:
            font.setPointSize(fontSize)

        self.lexer.setDefaultFont(font)
        self.lexer.setDefaultColor(
            QColor(
                settings.value("pythonConsole/defaultFontColorEditor",
                               QColor(self.DEFAULT_COLOR))))
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/commentFontColorEditor",
                               QColor(self.COMMENT_COLOR))), 1)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/numberFontColorEditor",
                               QColor(self.NUMBER_COLOR))), 2)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/keywordFontColorEditor",
                               QColor(self.KEYWORD_COLOR))), 5)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/classFontColorEditor",
                               QColor(self.CLASS_COLOR))), 8)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/methodFontColorEditor",
                               QColor(self.METHOD_COLOR))), 9)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/decorFontColorEditor",
                               QColor(self.DECORATION_COLOR))), 15)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/commentBlockFontColorEditor",
                               QColor(self.COMMENT_BLOCK_COLOR))), 12)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/singleQuoteFontColorEditor",
                               QColor(self.SINGLE_QUOTE_COLOR))), 4)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/doubleQuoteFontColorEditor",
                               QColor(self.DOUBLE_QUOTE_COLOR))), 3)
        self.lexer.setColor(
            QColor(
                settings.value(
                    "pythonConsole/tripleSingleQuoteFontColorEditor",
                    QColor(self.TRIPLE_SINGLE_QUOTE_COLOR))), 6)
        self.lexer.setColor(
            QColor(
                settings.value(
                    "pythonConsole/tripleDoubleQuoteFontColorEditor",
                    QColor(self.TRIPLE_DOUBLE_QUOTE_COLOR))), 7)
        self.lexer.setColor(
            QColor(
                settings.value("pythonConsole/defaultFontColorEditor",
                               QColor(self.DEFAULT_COLOR))), 13)
        self.lexer.setFont(font, 1)
        self.lexer.setFont(font, 3)
        self.lexer.setFont(font, 4)
        self.lexer.setFont(font, QsciLexerPython.UnclosedString)

        for style in range(0, 33):
            paperColor = QColor(
                settings.value("pythonConsole/paperBackgroundColorEditor",
                               QColor(self.BACKGROUND_COLOR)))
            self.lexer.setPaper(paperColor, style)

        self.api = QsciAPIs(self.lexer)

        useDefaultAPI = bool(settings.value('pythonConsole/preloadAPI', True))
        if useDefaultAPI:
            # Load QGIS API shipped with Python console
            self.api.loadPrepared(
                os.path.join(QgsApplication.pkgDataPath(), 'python',
                             'qsci_apis', 'pyqgis.pap'))
        else:
            # Load user-defined API files
            apiPaths = settings.value('pythonConsole/userAPI', [])
            for path in apiPaths:
                self.api.load(path)
            self.api.prepare()
            self.lexer.setAPIs(self.api)

        self.setLexer(self.lexer)
Ejemplo n.º 33
0
class AlgorithmDialogBase(BASE, WIDGET):

    def __init__(self, alg):
        super(AlgorithmDialogBase, self).__init__(iface.mainWindow())
        self.setupUi(self)

        self.feedback = AlgorithmDialogFeedback(self)
        self.feedback.progressChanged.connect(self.setPercentage)

        self.settings = QgsSettings()
        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:
                self.tabWidget.removeTab(2)
        else:
            self.tabWidget.removeTab(2)

        self.showDebug = ProcessingConfig.getSetting(
            ProcessingConfig.SHOW_DEBUG_IN_DIALOG)

    def requestFinished(self):
        """Change the webview HTML content"""
        reply = self.sender()
        if reply.error() != QNetworkReply.NoError:
            html = self.tr('<h2>No help available for this algorithm</h2><p>{}</p>'.format(reply.errorString()))
        else:
            html = str(reply.readAll())
        reply.deleteLater()
        self.txtHelp.setHtml(html)

    def closeEvent(self, evt):
        self.settings.setValue("/Processing/dialogBase", self.saveGeometry())
        super(AlgorithmDialogBase, self).closeEvent(evt)

    def setMainWidget(self, widget):
        if self.mainWidget is not None:
            QgsProject.instance().layerWasAdded.disconnect(self.mainWidget.layerRegistryChanged)
            QgsProject.instance().layersWillBeRemoved.disconnect(self.mainWidget.layerRegistryChanged)
        self.mainWidget = widget
        self.tabWidget.widget(0).layout().addWidget(self.mainWidget)
        QgsProject.instance().layerWasAdded.connect(self.mainWidget.layerRegistryChanged)
        QgsProject.instance().layersWillBeRemoved.connect(self.mainWidget.layerRegistryChanged)

    def error(self, msg):
        QApplication.restoreOverrideCursor()
        self.setInfo(msg, True)
        self.resetGUI()
        self.tabWidget.setCurrentIndex(1)

    def resetGUI(self):
        QApplication.restoreOverrideCursor()
        self.lblProgress.setText('')
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)
        self.btnRun.setEnabled(True)
        self.btnClose.setEnabled(True)

    def setInfo(self, msg, error=False):
        if error:
            self.txtLog.append('<span style="color:red"><br>%s<br></span>' % msg)
        else:
            self.txtLog.append(msg)
        QCoreApplication.processEvents()

    def setCommand(self, cmd):
        if self.showDebug:
            self.setInfo('<code>%s<code>' % cmd)
        QCoreApplication.processEvents()

    def setDebugInfo(self, msg):
        if self.showDebug:
            self.setInfo('<span style="color:blue">%s</span>' % msg)
        QCoreApplication.processEvents()

    def setConsoleInfo(self, msg):
        if self.showDebug:
            self.setCommand('<span style="color:darkgray">%s</span>' % msg)
        QCoreApplication.processEvents()

    def setPercentage(self, value):
        if self.progressBar.maximum() == 0:
            self.progressBar.setMaximum(100)
        self.progressBar.setValue(value)
        QCoreApplication.processEvents()

    def setText(self, text):
        self.lblProgress.setText(text)
        self.setInfo(text, False)
        QCoreApplication.processEvents()

    def setParamValues(self):
        pass

    def setParamValue(self, param, widget, alg=None):
        pass

    def accept(self):
        pass

    def finish(self, context):
        pass

    class InvalidParameterValue(Exception):

        def __init__(self, param, widget):
            (self.parameter, self.widget) = (param, widget)
Ejemplo n.º 34
0
 def rebuild(self):
     """ build or rebuild the mPlugins from the caches """
     self.mPlugins = {}
     for i in list(self.localCache.keys()):
         self.mPlugins[i] = self.localCache[i].copy()
     settings = QgsSettings()
     allowExperimental = settings.value(settingsGroup +
                                        "/allowExperimental",
                                        False,
                                        type=bool)
     allowDeprecated = settings.value(settingsGroup + "/allowDeprecated",
                                      False,
                                      type=bool)
     for i in list(self.repoCache.values()):
         for j in i:
             plugin = j.copy()  # do not update repoCache elements!
             key = plugin["id"]
             # check if the plugin is allowed and if there isn't any better one added already.
             if (allowExperimental or not plugin["experimental"]) \
                and (allowDeprecated or not plugin["deprecated"]) \
                and not (key in self.mPlugins and self.mPlugins[key]["version_available"] and compareVersions(self.mPlugins[key]["version_available"], plugin["version_available"]) < 2):
                 # The mPlugins dict contains now locally installed plugins.
                 # Now, add the available one if not present yet or update it if present already.
                 if key not in self.mPlugins:
                     self.mPlugins[key] = plugin  # just add a new plugin
                 else:
                     # update local plugin with remote metadata
                     # description, about, icon: only use remote data if local one not available. Prefer local version because of i18n.
                     # NOTE: don't prefer local name to not desynchronize names if repository doesn't support i18n.
                     # Also prefer local icon to avoid downloading.
                     for attrib in translatableAttributes + ["icon"]:
                         if attrib != "name":
                             if not self.mPlugins[key][attrib] and plugin[
                                     attrib]:
                                 self.mPlugins[key][attrib] = plugin[attrib]
                     # other remote metadata is preferred:
                     for attrib in [
                             "name", "plugin_id", "description", "about",
                             "category", "tags", "changelog", "author_name",
                             "author_email", "homepage", "tracker",
                             "code_repository", "experimental",
                             "deprecated", "version_available",
                             "zip_repository", "download_url", "filename",
                             "downloads", "average_vote", "rating_votes",
                             "trusted"
                     ]:
                         if attrib not in translatableAttributes or attrib == "name":  # include name!
                             if plugin[attrib]:
                                 self.mPlugins[key][attrib] = plugin[attrib]
                 # set status
                 #
                 # installed   available   status
                 # ---------------------------------------
                 # none        any         "not installed" (will be later checked if is "new")
                 # any         none        "orphan"
                 # same        same        "installed"
                 # less        greater     "upgradeable"
                 # greater     less        "newer"
                 if not self.mPlugins[key]["version_available"]:
                     self.mPlugins[key]["status"] = "orphan"
                 elif not self.mPlugins[key]["version_installed"]:
                     self.mPlugins[key]["status"] = "not installed"
                 elif self.mPlugins[key]["version_installed"] in [
                         "?", "-1"
                 ]:
                     self.mPlugins[key]["status"] = "installed"
                 elif compareVersions(
                         self.mPlugins[key]["version_available"],
                         self.mPlugins[key]["version_installed"]) == 0:
                     self.mPlugins[key]["status"] = "installed"
                 elif compareVersions(
                         self.mPlugins[key]["version_available"],
                         self.mPlugins[key]["version_installed"]) == 1:
                     self.mPlugins[key]["status"] = "upgradeable"
                 else:
                     self.mPlugins[key]["status"] = "newer"
                 # debug: test if the status match the "installed" tag:
                 if self.mPlugins[key]["status"] in [
                         "not installed"
                 ] and self.mPlugins[key]["installed"]:
                     raise Exception(
                         "Error: plugin status is ambiguous (1)")
                 if self.mPlugins[key]["status"] in [
                         "installed", "orphan", "upgradeable", "newer"
                 ] and not self.mPlugins[key]["installed"]:
                     raise Exception(
                         "Error: plugin status is ambiguous (2)")
     self.markNews()
Ejemplo n.º 35
0
    def save(self):
        toSave = []
        context = dataobjects.createContext()
        for row in range(self.batchRowCount()):
            algParams = {}
            algOutputs = {}
            col = 0
            alg = self.alg
            for param in alg.parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue
                if param.isDestination():
                    continue
                wrapper = self.wrappers[row][col]

                # For compatibility with 3.x API, we need to check whether the wrapper is
                # the deprecated WidgetWrapper class. If not, it's the newer
                # QgsAbstractProcessingParameterWidgetWrapper class
                # TODO QGIS 4.0 - remove
                if issubclass(wrapper.__class__, WidgetWrapper):
                    widget = wrapper.widget
                else:
                    widget = wrapper.wrappedWidget()

                value = wrapper.parameterValue()

                if not param.checkValueIsAcceptable(value, context):
                    self.parent.messageBar().pushMessage(
                        "",
                        self.tr(
                            'Wrong or missing parameter value: {0} (row {1})').
                        format(param.description(), row + 1),
                        level=Qgis.Warning,
                        duration=5)
                    return
                algParams[param.name()] = param.valueAsPythonString(
                    value, context)
                col += 1
            for out in alg.destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue
                widget = self.tblParameters.cellWidget(row + 1, col)
                text = widget.getValue()
                if text.strip() != '':
                    algOutputs[out.name()] = text.strip()
                    col += 1
                else:
                    self.parent.messageBar().pushMessage(
                        "",
                        self.tr('Wrong or missing output value: {0} (row {1})'
                                ).format(out.description(), row + 1),
                        level=Qgis.Warning,
                        duration=5)
                    return
            toSave.append({
                self.PARAMETERS: algParams,
                self.OUTPUTS: algOutputs
            })

        settings = QgsSettings()
        last_path = settings.value("/Processing/LastBatchPath",
                                   QDir.homePath())
        filename, __ = QFileDialog.getSaveFileName(
            self, self.tr('Save Batch'), last_path,
            self.tr('JSON files (*.json)'))
        if filename:
            if not filename.endswith('.json'):
                filename += '.json'
            last_path = QFileInfo(filename).path()
            settings.setValue('/Processing/LastBatchPath', last_path)
            with open(filename, 'w') as f:
                json.dump(toSave, f)
Ejemplo n.º 36
0
class MultipleInputDialog(BASE, WIDGET):

    def __init__(self, options, selectedoptions=None):
        super(MultipleInputDialog, self).__init__(None)
        self.setupUi(self)

        self.lstLayers.setSelectionMode(QAbstractItemView.NoSelection)

        self.options = []
        for i, option in enumerate(options):
            if option is None or isinstance(option, basestring):
                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)

        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.populateList()
        self.finished.connect(self.saveWindowGeometry)

    def saveWindowGeometry(self):
        self.settings.setValue("/Processing/multipleInputDialogGeometry", self.saveGeometry())

    def populateList(self):
        model = QStandardItemModel()
        for value, text in self.options:
            item = QStandardItem(text)
            item.setData(value, Qt.UserRole)
            item.setCheckState(Qt.Checked if value in self.selectedoptions else Qt.Unchecked)
            item.setCheckable(True)
            model.appendRow(item)

        self.lstLayers.setModel(model)

    def accept(self):
        self.selectedoptions = []
        model = self.lstLayers.model()
        for i in range(model.rowCount()):
            item = model.item(i)
            if item.checkState() == Qt.Checked:
                self.selectedoptions.append(item.data(Qt.UserRole))
        QDialog.accept(self)

    def reject(self):
        self.selectedoptions = None
        QDialog.reject(self)

    def selectAll(self, value):
        model = self.lstLayers.model()
        for i in range(model.rowCount()):
            item = model.item(i)
            item.setCheckState(Qt.Checked if value else Qt.Unchecked)

    def toggleSelection(self):
        model = self.lstLayers.model()
        for i in range(model.rowCount()):
            item = model.item(i)
            checked = item.checkState() == Qt.Checked
            item.setCheckState(Qt.Unchecked if checked else Qt.Checked)
Ejemplo n.º 37
0
 def checkingOnStart(self):
     """ return true if checking for news and updates is enabled """
     settings = QgsSettings()
     return settings.value(settingsGroup + "/checkOnStart",
                           False,
                           type=bool)
Ejemplo n.º 38
0
    def runGdal(commands, feedback=None):
        if feedback is None:
            feedback = QgsProcessingFeedback()
        envval = os.getenv('PATH')
        # We need to give some extra hints to get things picked up on OS X
        isDarwin = False
        try:
            isDarwin = platform.system() == 'Darwin'
        except IOError:  # https://travis-ci.org/m-kuhn/QGIS#L1493-L1526
            pass
        if isDarwin and os.path.isfile(
                os.path.join(QgsApplication.prefixPath(), "bin", "gdalinfo")):
            # Looks like there's a bundled gdal. Let's use it.
            os.environ['PATH'] = "{}{}{}".format(
                os.path.join(QgsApplication.prefixPath(), "bin"), os.pathsep,
                envval)
            os.environ['DYLD_LIBRARY_PATH'] = os.path.join(
                QgsApplication.prefixPath(), "lib")
        else:
            # Other platforms should use default gdal finder codepath
            settings = QgsSettings()
            path = settings.value('/GdalTools/gdalPath', '')
            if not path.lower() in envval.lower().split(os.pathsep):
                envval += '{}{}'.format(os.pathsep, path)
                os.putenv('PATH', envval)

        fused_command = ' '.join([str(c) for c in commands])
        QgsMessageLog.logMessage(fused_command, 'Processing', Qgis.Info)
        feedback.pushInfo('GDAL command:')
        feedback.pushCommandInfo(fused_command)
        feedback.pushInfo('GDAL command output:')
        success = False
        retry_count = 0
        while not success:
            loglines = []
            loglines.append('GDAL execution console output')
            try:
                with subprocess.Popen(
                        fused_command,
                        shell=True,
                        stdout=subprocess.PIPE,
                        stdin=subprocess.DEVNULL,
                        stderr=subprocess.STDOUT,
                        universal_newlines=True,
                ) as proc:
                    for line in proc.stdout:
                        feedback.pushConsoleInfo(line)
                        loglines.append(line)
                    success = True
            except IOError as e:
                if retry_count < 5:
                    retry_count += 1
                else:
                    raise IOError(
                        str(e) +
                        u'\nTried 5 times without success. Last iteration stopped after reading {} line(s).\nLast line(s):\n{}'
                        .format(len(loglines), u'\n'.join(loglines[-10:])))

            QgsMessageLog.logMessage('\n'.join(loglines), 'Processing',
                                     Qgis.Info)
            GdalUtils.consoleOutput = loglines
Ejemplo n.º 39
0
    def setCommonOptions(self):
        # Enable non-ASCII characters
        self.setUtf8(True)

        # Default font
        font = QFont()
        font.setFamily('Courier')
        font.setFixedPitch(True)
        font.setPointSize(10)
        self.setFont(font)
        self.setMarginsFont(font)

        self.setBraceMatching(QsciScintilla.SloppyBraceMatch)

        self.setWrapMode(QsciScintilla.WrapWord)
        self.setWrapVisualFlags(QsciScintilla.WrapFlagByText,
                                QsciScintilla.WrapFlagNone, 4)

        self.setSelectionForegroundColor(QColor('#2e3436'))
        self.setSelectionBackgroundColor(QColor('#babdb6'))

        # Show line numbers
        self.setMarginWidth(1, '000')
        self.setMarginLineNumbers(1, True)
        self.setMarginsForegroundColor(QColor('#2e3436'))
        self.setMarginsBackgroundColor(QColor('#babdb6'))

        # Highlight current line
        self.setCaretLineVisible(True)
        self.setCaretLineBackgroundColor(QColor('#d3d7cf'))

        # Folding
        self.setFolding(QsciScintilla.BoxedTreeFoldStyle)
        self.setFoldMarginColors(QColor('#d3d7cf'), QColor('#d3d7cf'))

        # Mark column 80 with vertical line
        self.setEdgeMode(QsciScintilla.EdgeLine)
        self.setEdgeColumn(80)
        self.setEdgeColor(QColor('#eeeeec'))

        # Indentation
        self.setAutoIndent(True)
        self.setIndentationsUseTabs(False)
        self.setIndentationWidth(4)
        self.setTabIndents(True)
        self.setBackspaceUnindents(True)
        self.setTabWidth(4)

        # Autocomletion
        self.setAutoCompletionThreshold(2)
        self.setAutoCompletionSource(QsciScintilla.AcsAPIs)
        self.setAutoCompletionCaseSensitivity(False)

        # Load font from Python console settings
        settings = QgsSettings()
        fontName = settings.value('pythonConsole/fontfamilytext', 'Monospace')
        fontSize = int(settings.value('pythonConsole/fontsize', 10))

        self.defaultFont = QFont(fontName)
        self.defaultFont.setFixedPitch(True)
        self.defaultFont.setPointSize(fontSize)
        self.defaultFont.setStyleHint(QFont.TypeWriter)
        self.defaultFont.setStretch(QFont.SemiCondensed)
        self.defaultFont.setLetterSpacing(QFont.PercentageSpacing, 87.0)
        self.defaultFont.setBold(False)

        self.boldFont = QFont(self.defaultFont)
        self.boldFont.setBold(True)

        self.italicFont = QFont(self.defaultFont)
        self.italicFont.setItalic(True)

        self.setFont(self.defaultFont)
        self.setMarginsFont(self.defaultFont)

        self.initLexer()
Ejemplo n.º 40
0
def old_version_import() -> Service:
    settings = QgsSettings()
    if settings.contains('plugins/geomapfsih_locator_plugin/geomapfish_url'):
        definition = dict()
        definition['name'] = settings.value(
            'plugins/geomapfsih_locator_plugin/filter_name',
            'geomapfish',
            type=str)
        definition['url'] = settings.value(
            'plugins/geomapfsih_locator_plugin/geomapfish_url', '', type=str)
        definition['crs'] = settings.value(
            'plugins/geomapfsih_locator_plugin/geomapfish_crs', '', type=str)

        definition['remove_leading_digits'] = settings.value(
            'plugins/geomapfsih_locator_plugin/remove_leading_digits',
            True,
            type=bool)
        definition['replace_underscore'] = settings.value(
            'plugins/geomapfsih_locator_plugin/replace_underscore',
            True,
            type=bool)
        definition['break_camelcase'] = settings.value(
            'plugins/geomapfsih_locator_plugin/break_camelcase',
            True,
            type=bool)

        definition['category_limit'] = settings.value(
            'plugins/geomapfsih_locator_plugin/category_limit', 8, type=int)
        definition['total_limit'] = settings.value(
            'plugins/geomapfsih_locator_plugin/total_limit', 50, type=int)

        user = settings.value(
            'plugins/geomapfsih_locator_plugin/geomapfish_user', '', type=str)
        pwd = settings.value(
            'plugins/geomapfsih_locator_plugin/geomapfish_pass', '', type=str)

        info("importing old service: {}".format(definition))

        if user:
            reply = QMessageBox.question(
                None, "Geomapfish Locator",
                QCoreApplication.translate(
                    "Geomapfish Locator",
                    "User and password were saved in clear text in former Geomapfish plugin. "
                    "Would you like to use QGIS authentication to store these credentials? "
                    "If not, they will be removed."))
            if reply == QMessageBox.Yes:
                config = QgsAuthMethodConfig('Basic')
                config.setName('geomapfish_{}'.format(definition['name']))
                config.setConfig('username', user)
                config.setConfig('password', pwd)
                QgsApplication.authManager().storeAuthenticationConfig(config)
                definition['authid'] = config.id()
                dbg_info("created new auth id: {}".format(config.id()))
            else:
                drop_keys()
                return None

        drop_keys()
        return Service(definition)

    else:
        return None
Ejemplo n.º 41
0
    def setCommonOptions(self):
        # Enable non-ASCII characters
        self.setUtf8(True)

        settings = QgsSettings()

        # Default font
        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        self.setFont(font)
        self.setMarginsFont(font)

        self.setBraceMatching(QsciScintilla.SloppyBraceMatch)
        self.setMatchedBraceBackgroundColor(
            QColor(
                settings.value(
                    "pythonConsole/matchedBraceBackgroundColorEditor",
                    QColor(self.MATCHED_BRACE_BACKGROUND_COLOR))))
        self.setMatchedBraceForegroundColor(
            QColor(
                settings.value(
                    "pythonConsole/matchedBraceForegroundColorEditor",
                    QColor(self.MATCHED_BRACE_FOREGROUND_COLOR))))

        #self.setWrapMode(QsciScintilla.WrapWord)
        #self.setWrapVisualFlags(QsciScintilla.WrapFlagByText,
        #                        QsciScintilla.WrapFlagNone, 4)

        self.setSelectionForegroundColor(
            QColor(
                settings.value("pythonConsole/selectionForegroundColorEditor",
                               QColor(self.SELECTION_FOREGROUND_COLOR))))
        self.setSelectionBackgroundColor(
            QColor(
                settings.value("pythonConsole/selectionBackgroundColorEditor",
                               QColor(self.SELECTION_BACKGROUND_COLOR))))

        # Show line numbers
        fontmetrics = QFontMetrics(font)
        self.setMarginWidth(1, fontmetrics.width("0000") + 5)
        self.setMarginLineNumbers(1, True)
        self.setMarginsForegroundColor(
            QColor(
                settings.value("pythonConsole/marginForegroundColorEditor",
                               QColor(self.MARGIN_FOREGROUND_COLOR))))
        self.setMarginsBackgroundColor(
            QColor(
                settings.value("pythonConsole/marginBackgroundColorEditor",
                               QColor(self.MARGIN_BACKGROUND_COLOR))))
        self.setIndentationGuidesForegroundColor(
            QColor(
                settings.value("pythonConsole/marginForegroundColorEditor",
                               QColor(self.MARGIN_FOREGROUND_COLOR))))
        self.setIndentationGuidesBackgroundColor(
            QColor(
                settings.value("pythonConsole/marginBackgroundColorEditor",
                               QColor(self.MARGIN_BACKGROUND_COLOR))))

        # Highlight current line
        caretLineColorEditor = settings.value(
            "pythonConsole/caretLineColorEditor",
            QColor(self.CARET_LINE_COLOR))
        cursorColorEditor = settings.value("pythonConsole/cursorColorEditor",
                                           QColor(self.CURSOR_COLOR))
        self.setCaretLineVisible(True)
        self.setCaretWidth(2)
        self.setCaretLineBackgroundColor(caretLineColorEditor)
        self.setCaretForegroundColor(cursorColorEditor)

        # Folding
        self.setFolding(QsciScintilla.PlainFoldStyle)
        foldColor = QColor(
            settings.value("pythonConsole/foldColorEditor",
                           QColor(self.FOLD_COLOR)))
        self.setFoldMarginColors(foldColor, foldColor)

        # Mark column 80 with vertical line
        self.setEdgeMode(QsciScintilla.EdgeLine)
        self.setEdgeColumn(80)
        self.setEdgeColor(
            QColor(
                settings.value("pythonConsole/edgeColorEditor",
                               QColor(self.EDGE_COLOR))))

        # Indentation
        self.setAutoIndent(True)
        self.setIndentationsUseTabs(False)
        self.setIndentationWidth(4)
        self.setTabIndents(True)
        self.setBackspaceUnindents(True)
        self.setTabWidth(4)
        self.setIndentationGuides(True)

        # Autocompletion
        self.setAutoCompletionThreshold(2)
        self.setAutoCompletionSource(QsciScintilla.AcsAPIs)

        self.setFonts(10)
        self.initLexer()
Ejemplo n.º 42
0
    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
Ejemplo n.º 43
0
class ManageConnectionsDialog(QDialog, BASE_CLASS):
    """manage connections"""
    def __init__(self, mode):
        """init dialog"""

        QDialog.__init__(self)
        self.setupUi(self)
        self.settings = QgsSettings()
        self.filename = None
        self.mode = mode  # 0 - save, 1 - load
        self.btnBrowse.clicked.connect(self.select_file)
        self.manage_gui()

    def manage_gui(self):
        """manage interface"""

        if self.mode == 1:
            self.label.setText(self.tr('Load from file'))
            self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr('Load'))
        else:
            self.label.setText(self.tr('Save to file'))
            self.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr('Save'))
            self.populate()

        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)

    def select_file(self):
        """select file ops"""

        label = self.tr('eXtensible Markup Language (*.xml *.XML)')

        if self.mode == 0:
            slabel = self.tr('Save connections')
            self.filename, filter = QFileDialog.getSaveFileName(
                self, slabel, '.', label)
        else:
            slabel = self.tr('Load connections')
            self.filename, selected_filter = QFileDialog.getOpenFileName(
                self, slabel, '.', label)

        if not self.filename:
            return

        # ensure the user never omitted the extension from the file name
        if not self.filename.lower().endswith('.xml'):
            self.filename = '%s.xml' % self.filename

        self.leFileName.setText(self.filename)

        if self.mode == 1:
            self.populate()

        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)

    def populate(self):
        """populate connections list from settings"""

        if self.mode == 0:
            self.settings.beginGroup('/MetaSearch/')
            keys = self.settings.childGroups()
            for key in keys:
                item = QListWidgetItem(self.listConnections)
                item.setText(key)
            self.settings.endGroup()

        else:  # populate connections list from file
            doc = get_connections_from_file(self, self.filename)
            if doc is None:
                self.filename = None
                self.leFileName.clear()
                self.listConnections.clear()
                return

            for csw in doc.findall('csw'):
                item = QListWidgetItem(self.listConnections)
                item.setText(csw.attrib.get('name'))

    def save(self, connections):
        """save connections ops"""

        doc = etree.Element('qgsCSWConnections')
        doc.attrib['version'] = '1.0'

        for conn in connections:
            url = self.settings.value('/MetaSearch/%s/url' % conn)
            if url is not None:
                connection = etree.SubElement(doc, 'csw')
                connection.attrib['name'] = conn
                connection.attrib['url'] = url

        # write to disk
        with open(self.filename, 'w') as fileobj:
            fileobj.write(prettify_xml(etree.tostring(doc)))
        QMessageBox.information(self, self.tr('Save Connections'),
                                self.tr('Saved to {0}').format(self.filename))
        self.reject()

    def load(self, items):
        """load connections"""

        self.settings.beginGroup('/MetaSearch/')
        keys = self.settings.childGroups()
        self.settings.endGroup()

        exml = etree.parse(self.filename).getroot()

        for csw in exml.findall('csw'):
            conn_name = csw.attrib.get('name')

            # process only selected connections
            if conn_name not in items:
                continue

            # check for duplicates
            if conn_name in keys:
                label = self.tr('File {0} exists. Overwrite?').format(
                    conn_name)
                res = QMessageBox.warning(self, self.tr('Loading Connections'),
                                          label,
                                          QMessageBox.Yes | QMessageBox.No)
                if res != QMessageBox.Yes:
                    continue

            # no dups detected or overwrite is allowed
            url = '/MetaSearch/%s/url' % conn_name
            self.settings.setValue(url, csw.attrib.get('url'))

    def accept(self):
        """accept connections"""

        selection = self.listConnections.selectedItems()
        if len(selection) == 0:
            return

        items = []
        for sel in selection:
            items.append(sel.text())

        if self.mode == 0:  # save
            self.save(items)
        else:  # load
            self.load(items)

        self.filename = None
        self.leFileName.clear()
        self.listConnections.clear()
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)

    def reject(self):
        """back out of manage connections dialogue"""

        QDialog.reject(self)
    def showSelectionDialog(self):
        if isinstance(self.output, QgsProcessingParameterFolderDestination):
            self.selectDirectory()
            return

        filefilter = getFileFilter(self.output)
        settings = QgsSettings()
        if settings.contains('/Processing/LastBatchOutputPath'):
            path = str(settings.value('/Processing/LastBatchOutputPath'))
        else:
            path = ''
        filename, selectedFileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save file'), path, filefilter)
        if filename:
            if not filename.lower().endswith(
                    tuple(re.findall("\\*(\\.[a-z]{1,10})", filefilter))):
                ext = re.search("\\*(\\.[a-z]{1,10})", selectedFileFilter)
                if ext:
                    filename += ext.group(1)
            settings.setValue('/Processing/LastBatchOutputPath',
                              os.path.dirname(filename))
            dlg = AutofillDialog(self.alg)
            dlg.exec_()
            if dlg.mode is not None:
                try:
                    if dlg.mode == AutofillDialog.DO_NOT_AUTOFILL:
                        self.table.cellWidget(self.row,
                                              self.col).setValue(filename)
                    elif dlg.mode == AutofillDialog.FILL_WITH_NUMBERS:
                        n = self.table.rowCount() - self.row
                        for i in range(n):
                            name = filename[:filename.rfind('.')] \
                                + str(i + 1) + filename[filename.rfind('.'):]
                            self.table.cellWidget(i + self.row,
                                                  self.col).setValue(name)
                    elif dlg.mode == AutofillDialog.FILL_WITH_PARAMETER:
                        n = self.table.rowCount() - self.row
                        for i in range(n):
                            widget = self.table.cellWidget(
                                i + self.row, dlg.param_index)
                            param = self.alg.parameterDefinitions()[
                                dlg.param_index]
                            if isinstance(
                                    param,
                                (QgsProcessingParameterRasterLayer,
                                 QgsProcessingParameterFeatureSource,
                                 QgsProcessingParameterVectorLayer,
                                 QgsProcessingParameterMultipleLayers)):
                                v = widget.value()
                                if isinstance(v, QgsMapLayer):
                                    s = v.name()
                                else:
                                    s = os.path.basename(v)
                                    s = os.path.splitext(s)[0]
                            elif isinstance(param,
                                            QgsProcessingParameterBoolean):
                                s = str(widget.currentIndex() == 0)
                            elif isinstance(param, QgsProcessingParameterEnum):
                                s = str(widget.currentText())
                            elif isinstance(param,
                                            QgsProcessingParameterMatrix):
                                s = str(widget.table)
                            else:
                                s = str(widget.text())
                            name = filename[:filename.rfind('.')] + s \
                                + filename[filename.rfind('.'):]
                            self.table.cellWidget(i + self.row,
                                                  self.col).setValue(name)
                except:
                    pass
Ejemplo n.º 45
0
class MetaSearchDialog(QDialog, BASE_CLASS):
    """main dialogue"""
    def __init__(self, iface):
        """init window"""

        QDialog.__init__(self)
        self.setupUi(self)

        self.iface = iface
        self.map = iface.mapCanvas()
        self.settings = QgsSettings()
        self.catalog = None
        self.catalog_url = None
        self.catalog_username = None
        self.catalog_password = None
        self.context = StaticContext()

        version = self.context.metadata.get('general', 'version')
        self.setWindowTitle(self.tr('MetaSearch {0}').format(version))

        self.rubber_band = QgsRubberBand(self.map, True)  # True = a polygon
        self.rubber_band.setColor(QColor(255, 0, 0, 75))
        self.rubber_band.setWidth(5)

        # form inputs
        self.startfrom = 0
        self.maxrecords = 10
        self.timeout = 10
        self.constraints = []

        # Servers tab
        self.cmbConnectionsServices.activated.connect(self.save_connection)
        self.cmbConnectionsSearch.activated.connect(self.save_connection)
        self.btnServerInfo.clicked.connect(self.connection_info)
        self.btnAddDefault.clicked.connect(self.add_default_connections)
        self.btnCapabilities.clicked.connect(self.show_xml)
        self.tabWidget.currentChanged.connect(self.populate_connection_list)

        # server management buttons
        self.btnNew.clicked.connect(self.add_connection)
        self.btnEdit.clicked.connect(self.edit_connection)
        self.btnDelete.clicked.connect(self.delete_connection)
        self.btnLoad.clicked.connect(self.load_connections)
        self.btnSave.clicked.connect(save_connections)

        # Search tab
        self.treeRecords.itemSelectionChanged.connect(self.record_clicked)
        self.treeRecords.itemDoubleClicked.connect(self.show_metadata)
        self.btnSearch.clicked.connect(self.search)
        self.leKeywords.returnPressed.connect(self.search)
        # prevent dialog from closing upon pressing enter
        self.buttonBox.button(QDialogButtonBox.Close).setAutoDefault(False)
        # launch help from button
        self.buttonBox.helpRequested.connect(self.help)
        self.btnCanvasBbox.setAutoDefault(False)
        self.btnCanvasBbox.clicked.connect(self.set_bbox_from_map)
        self.btnGlobalBbox.clicked.connect(self.set_bbox_global)

        # navigation buttons
        self.btnFirst.clicked.connect(self.navigate)
        self.btnPrev.clicked.connect(self.navigate)
        self.btnNext.clicked.connect(self.navigate)
        self.btnLast.clicked.connect(self.navigate)

        self.mActionAddWms.triggered.connect(self.add_to_ows)
        self.mActionAddWfs.triggered.connect(self.add_to_ows)
        self.mActionAddWcs.triggered.connect(self.add_to_ows)
        self.btnShowXml.clicked.connect(self.show_xml)

        # settings
        self.radioTitleAsk.clicked.connect(self.set_ows_save_title_ask)
        self.radioTitleNoAsk.clicked.connect(self.set_ows_save_title_no_ask)
        self.radioTempName.clicked.connect(self.set_ows_save_temp_name)

        self.manageGui()

    def manageGui(self):
        """open window"""

        self.tabWidget.setCurrentIndex(0)
        self.populate_connection_list()
        self.btnCapabilities.setEnabled(False)
        self.spnRecords.setValue(
            int(self.settings.value('/MetaSearch/returnRecords', 10)))

        key = '/MetaSearch/%s' % self.cmbConnectionsSearch.currentText()
        self.catalog_url = self.settings.value('%s/url' % key)
        self.catalog_username = self.settings.value('%s/username' % key)
        self.catalog_password = self.settings.value('%s/password' % key)

        self.set_bbox_global()

        self.reset_buttons()

        # get preferred connection save strategy from settings and set it
        save_strategy = self.settings.value('/MetaSearch/ows_save_strategy',
                                            'title_ask')
        if save_strategy == 'temp_name':
            self.radioTempName.setChecked(True)
        elif save_strategy == 'title_no_ask':
            self.radioTitleNoAsk.setChecked(True)
        else:
            self.radioTitleAsk.setChecked(True)

        # install proxy handler if specified in QGIS settings
        self.install_proxy()

    # Servers tab

    def populate_connection_list(self):
        """populate select box with connections"""

        self.settings.beginGroup('/MetaSearch/')
        self.cmbConnectionsServices.clear()
        self.cmbConnectionsServices.addItems(self.settings.childGroups())
        self.cmbConnectionsSearch.clear()
        self.cmbConnectionsSearch.addItems(self.settings.childGroups())
        self.settings.endGroup()

        self.set_connection_list_position()

        if self.cmbConnectionsServices.count() == 0:
            # no connections - disable various buttons
            state_disabled = False
            self.btnSave.setEnabled(state_disabled)
            # and start with connection tab open
            self.tabWidget.setCurrentIndex(1)
            # tell the user to add services
            msg = self.tr('No services/connections defined. To get '
                          'started with MetaSearch, create a new '
                          'connection by clicking \'New\' or click '
                          '\'Add default services\'.')
            self.textMetadata.setHtml('<p><h3>%s</h3></p>' % msg)
        else:
            # connections - enable various buttons
            state_disabled = True

        self.btnServerInfo.setEnabled(state_disabled)
        self.btnEdit.setEnabled(state_disabled)
        self.btnDelete.setEnabled(state_disabled)

    def set_connection_list_position(self):
        """set the current index to the selected connection"""
        to_select = self.settings.value('/MetaSearch/selected')
        conn_count = self.cmbConnectionsServices.count()

        if conn_count == 0:
            self.btnDelete.setEnabled(False)
            self.btnServerInfo.setEnabled(False)
            self.btnEdit.setEnabled(False)

        # does to_select exist in cmbConnectionsServices?
        exists = False
        for i in range(conn_count):
            if self.cmbConnectionsServices.itemText(i) == to_select:
                self.cmbConnectionsServices.setCurrentIndex(i)
                self.cmbConnectionsSearch.setCurrentIndex(i)
                exists = True
                break

        # If we couldn't find the stored item, but there are some, default
        # to the last item (this makes some sense when deleting items as it
        # allows the user to repeatidly click on delete to remove a whole
        # lot of items)
        if not exists and conn_count > 0:
            # If to_select is null, then the selected connection wasn't found
            # by QgsSettings, which probably means that this is the first time
            # the user has used CSWClient, so default to the first in the list
            # of connetions. Otherwise default to the last.
            if not to_select:
                current_index = 0
            else:
                current_index = conn_count - 1

            self.cmbConnectionsServices.setCurrentIndex(current_index)
            self.cmbConnectionsSearch.setCurrentIndex(current_index)

    def save_connection(self):
        """save connection"""

        caller = self.sender().objectName()

        if caller == 'cmbConnectionsServices':  # servers tab
            current_text = self.cmbConnectionsServices.currentText()
        elif caller == 'cmbConnectionsSearch':  # search tab
            current_text = self.cmbConnectionsSearch.currentText()

        self.settings.setValue('/MetaSearch/selected', current_text)
        key = '/MetaSearch/%s' % current_text

        if caller == 'cmbConnectionsSearch':  # bind to service in search tab
            self.catalog_url = self.settings.value('%s/url' % key)
            self.catalog_username = self.settings.value('%s/username' % key)
            self.catalog_password = self.settings.value('%s/password' % key)

        if caller == 'cmbConnectionsServices':  # clear server metadata
            self.textMetadata.clear()

        self.btnCapabilities.setEnabled(False)

    def connection_info(self):
        """show connection info"""

        current_text = self.cmbConnectionsServices.currentText()
        key = '/MetaSearch/%s' % current_text
        self.catalog_url = self.settings.value('%s/url' % key)
        self.catalog_username = self.settings.value('%s/username' % key)
        self.catalog_password = self.settings.value('%s/password' % key)

        # connect to the server
        if not self._get_csw():
            return

        QApplication.restoreOverrideCursor()

        if self.catalog:  # display service metadata
            self.btnCapabilities.setEnabled(True)
            metadata = render_template('en', self.context, self.catalog,
                                       'service_metadata.html')
            style = QgsApplication.reportStyleSheet()
            self.textMetadata.clear()
            self.textMetadata.document().setDefaultStyleSheet(style)
            self.textMetadata.setHtml(metadata)

    def add_connection(self):
        """add new service"""

        conn_new = NewConnectionDialog()
        conn_new.setWindowTitle(self.tr('New Catalogue service'))
        if conn_new.exec_() == QDialog.Accepted:  # add to service list
            self.populate_connection_list()
        self.textMetadata.clear()

    def edit_connection(self):
        """modify existing connection"""

        current_text = self.cmbConnectionsServices.currentText()

        url = self.settings.value('/MetaSearch/%s/url' % current_text)

        conn_edit = NewConnectionDialog(current_text)
        conn_edit.setWindowTitle(self.tr('Edit Catalogue service'))
        conn_edit.leName.setText(current_text)
        conn_edit.leURL.setText(url)
        conn_edit.leUsername.setText(
            self.settings.value('/MetaSearch/%s/username' % current_text))
        conn_edit.lePassword.setText(
            self.settings.value('/MetaSearch/%s/password' % current_text))

        if conn_edit.exec_() == QDialog.Accepted:  # update service list
            self.populate_connection_list()

    def delete_connection(self):
        """delete connection"""

        current_text = self.cmbConnectionsServices.currentText()

        key = '/MetaSearch/%s' % current_text

        msg = self.tr('Remove service {0}?').format(current_text)

        result = QMessageBox.information(self, self.tr('Confirm delete'), msg,
                                         QMessageBox.Ok | QMessageBox.Cancel)
        if result == QMessageBox.Ok:  # remove service from list
            self.settings.remove(key)
            index_to_delete = self.cmbConnectionsServices.currentIndex()
            self.cmbConnectionsServices.removeItem(index_to_delete)
            self.cmbConnectionsSearch.removeItem(index_to_delete)
            self.set_connection_list_position()

    def load_connections(self):
        """load services from list"""

        ManageConnectionsDialog(1).exec_()
        self.populate_connection_list()

    def add_default_connections(self):
        """add default connections"""

        filename = os.path.join(self.context.ppath, 'resources',
                                'connections-default.xml')
        doc = get_connections_from_file(self, filename)
        if doc is None:
            return

        self.settings.beginGroup('/MetaSearch/')
        keys = self.settings.childGroups()
        self.settings.endGroup()

        for server in doc.findall('csw'):
            name = server.attrib.get('name')
            # check for duplicates
            if name in keys:
                msg = self.tr('{0} exists.  Overwrite?').format(name)
                res = QMessageBox.warning(self, self.tr('Loading connections'),
                                          msg,
                                          QMessageBox.Yes | QMessageBox.No)
                if res != QMessageBox.Yes:
                    continue

            # no dups detected or overwrite is allowed
            key = '/MetaSearch/%s' % name
            self.settings.setValue('%s/url' % key, server.attrib.get('url'))

        self.populate_connection_list()

    # Settings tab

    def set_ows_save_title_ask(self):
        """save ows save strategy as save ows title, ask if duplicate"""

        self.settings.setValue('/MetaSearch/ows_save_strategy', 'title_ask')

    def set_ows_save_title_no_ask(self):
        """save ows save strategy as save ows title, do NOT ask if duplicate"""

        self.settings.setValue('/MetaSearch/ows_save_strategy', 'title_no_ask')

    def set_ows_save_temp_name(self):
        """save ows save strategy as save with a temporary name"""

        self.settings.setValue('/MetaSearch/ows_save_strategy', 'temp_name')

    # Search tab

    def set_bbox_from_map(self):
        """set bounding box from map extent"""

        crs = self.map.mapSettings().destinationCrs()
        try:
            crsid = int(crs.authid().split(':')[1])
        except IndexError:  # no projection
            crsid = 4326

        extent = self.map.extent()

        if crsid != 4326:  # reproject to EPSG:4326
            src = QgsCoordinateReferenceSystem(crsid)
            dest = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform(src, dest)
            minxy = xform.transform(
                QgsPoint(extent.xMinimum(), extent.yMinimum()))
            maxxy = xform.transform(
                QgsPoint(extent.xMaximum(), extent.yMaximum()))
            minx, miny = minxy
            maxx, maxy = maxxy
        else:  # 4326
            minx = extent.xMinimum()
            miny = extent.yMinimum()
            maxx = extent.xMaximum()
            maxy = extent.yMaximum()

        self.leNorth.setText(str(maxy)[0:9])
        self.leSouth.setText(str(miny)[0:9])
        self.leWest.setText(str(minx)[0:9])
        self.leEast.setText(str(maxx)[0:9])

    def set_bbox_global(self):
        """set global bounding box"""
        self.leNorth.setText('90')
        self.leSouth.setText('-90')
        self.leWest.setText('-180')
        self.leEast.setText('180')

    def search(self):
        """execute search"""

        self.catalog = None
        self.constraints = []

        # clear all fields and disable buttons
        self.lblResults.clear()
        self.treeRecords.clear()

        self.reset_buttons()

        # save some settings
        self.settings.setValue('/MetaSearch/returnRecords',
                               self.spnRecords.cleanText())

        # set current catalogue
        current_text = self.cmbConnectionsSearch.currentText()
        key = '/MetaSearch/%s' % current_text
        self.catalog_url = self.settings.value('%s/url' % key)
        self.catalog_username = self.settings.value('%s/username' % key)
        self.catalog_password = self.settings.value('%s/password' % key)

        # start position and number of records to return
        self.startfrom = 0
        self.maxrecords = self.spnRecords.value()

        # set timeout
        self.timeout = self.spnTimeout.value()

        # bbox
        minx = self.leWest.text()
        miny = self.leSouth.text()
        maxx = self.leEast.text()
        maxy = self.leNorth.text()
        bbox = [minx, miny, maxx, maxy]

        # only apply spatial filter if bbox is not global
        # even for a global bbox, if a spatial filter is applied, then
        # the CSW server will skip records without a bbox
        if bbox != ['-180', '-90', '180', '90']:
            self.constraints.append(BBox(bbox))

        # keywords
        if self.leKeywords.text():
            # TODO: handle multiple word searches
            keywords = self.leKeywords.text()
            self.constraints.append(PropertyIsLike('csw:AnyText', keywords))

        if len(self.constraints) > 1:  # exclusive search (a && b)
            self.constraints = [self.constraints]

        # build request
        if not self._get_csw():
            return

        # TODO: allow users to select resources types
        # to find ('service', 'dataset', etc.)
        try:
            self.catalog.getrecords2(constraints=self.constraints,
                                     maxrecords=self.maxrecords,
                                     esn='full')
        except ExceptionReport as err:
            QApplication.restoreOverrideCursor()
            QMessageBox.warning(self, self.tr('Search error'),
                                self.tr('Search error: {0}').format(err))
            return
        except Exception as err:
            QApplication.restoreOverrideCursor()
            QMessageBox.warning(self, self.tr('Connection error'),
                                self.tr('Connection error: {0}').format(err))
            return

        if self.catalog.results['matches'] == 0:
            QApplication.restoreOverrideCursor()
            self.lblResults.setText(self.tr('0 results'))
            return

        QApplication.restoreOverrideCursor()
        self.display_results()

    def display_results(self):
        """display search results"""

        self.treeRecords.clear()

        position = self.catalog.results['returned'] + self.startfrom

        msg = self.tr('Showing {0} - {1} of %n result(s)', 'number of results',
                      self.catalog.results['matches']).format(
                          self.startfrom + 1, position)

        self.lblResults.setText(msg)

        for rec in self.catalog.records:
            item = QTreeWidgetItem(self.treeRecords)
            if self.catalog.records[rec].type:
                item.setText(0, normalize_text(self.catalog.records[rec].type))
            else:
                item.setText(0, 'unknown')
            if self.catalog.records[rec].title:
                item.setText(1,
                             normalize_text(self.catalog.records[rec].title))
            if self.catalog.records[rec].identifier:
                set_item_data(item, 'identifier',
                              self.catalog.records[rec].identifier)

        self.btnShowXml.setEnabled(True)

        if self.catalog.results["matches"] < self.maxrecords:
            disabled = False
        else:
            disabled = True

        self.btnFirst.setEnabled(disabled)
        self.btnPrev.setEnabled(disabled)
        self.btnNext.setEnabled(disabled)
        self.btnLast.setEnabled(disabled)

    def record_clicked(self):
        """record clicked signal"""

        # disable only service buttons
        self.reset_buttons(True, False, False)

        if not self.treeRecords.selectedItems():
            return

        item = self.treeRecords.currentItem()
        if not item:
            return

        identifier = get_item_data(item, 'identifier')
        try:
            record = self.catalog.records[identifier]
        except KeyError as err:
            QMessageBox.warning(self, self.tr('Record parsing error'),
                                'Unable to locate record identifier')
            return

        # if the record has a bbox, show a footprint on the map
        if record.bbox is not None:
            points = bbox_to_polygon(record.bbox)
            if points is not None:
                src = QgsCoordinateReferenceSystem(4326)
                dst = self.map.mapSettings().destinationCrs()
                geom = QgsGeometry.fromWkt(points)
                if src.postgisSrid() != dst.postgisSrid():
                    ctr = QgsCoordinateTransform(src, dst)
                    try:
                        geom.transform(ctr)
                    except Exception as err:
                        QMessageBox.warning(
                            self, self.tr('Coordinate Transformation Error'),
                            str(err))
                self.rubber_band.setToGeometry(geom, None)

        # figure out if the data is interactive and can be operated on
        self.find_services(record, item)

    def find_services(self, record, item):
        """scan record for WMS/WMTS|WFS|WCS endpoints"""

        links = record.uris + record.references

        services = {}
        for link in links:

            if 'scheme' in link:
                link_type = link['scheme']
            elif 'protocol' in link:
                link_type = link['protocol']
            else:
                link_type = None

            if link_type is not None:
                link_type = link_type.upper()

            wmswmst_link_types = list(
                map(str.upper, link_types.WMSWMST_LINK_TYPES))
            wfs_link_types = list(map(str.upper, link_types.WFS_LINK_TYPES))
            wcs_link_types = list(map(str.upper, link_types.WCS_LINK_TYPES))

            # if the link type exists, and it is one of the acceptable
            # interactive link types, then set
            if all([
                    link_type is not None, link_type
                    in wmswmst_link_types + wfs_link_types + wcs_link_types
            ]):
                if link_type in wmswmst_link_types:
                    services['wms'] = link['url']
                    self.mActionAddWms.setEnabled(True)
                if link_type in wfs_link_types:
                    services['wfs'] = link['url']
                    self.mActionAddWfs.setEnabled(True)
                if link_type in wcs_link_types:
                    services['wcs'] = link['url']
                    self.mActionAddWcs.setEnabled(True)
                self.tbAddData.setEnabled(True)

            set_item_data(item, 'link', json.dumps(services))

    def navigate(self):
        """manage navigation / paging"""

        caller = self.sender().objectName()

        if caller == 'btnFirst':
            self.startfrom = 0
        elif caller == 'btnLast':
            self.startfrom = self.catalog.results['matches'] - self.maxrecords
        elif caller == 'btnNext':
            self.startfrom += self.maxrecords
            if self.startfrom >= self.catalog.results["matches"]:
                msg = self.tr('End of results. Go to start?')
                res = QMessageBox.information(
                    self, self.tr('Navigation'), msg,
                    (QMessageBox.Ok | QMessageBox.Cancel))
                if res == QMessageBox.Ok:
                    self.startfrom = 0
                else:
                    return
        elif caller == "btnPrev":
            self.startfrom -= self.maxrecords
            if self.startfrom <= 0:
                msg = self.tr('Start of results. Go to end?')
                res = QMessageBox.information(
                    self, self.tr('Navigation'), msg,
                    (QMessageBox.Ok | QMessageBox.Cancel))
                if res == QMessageBox.Ok:
                    self.startfrom = (self.catalog.results['matches'] -
                                      self.maxrecords)
                else:
                    return

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        try:
            self.catalog.getrecords2(constraints=self.constraints,
                                     maxrecords=self.maxrecords,
                                     startposition=self.startfrom,
                                     esn='full')
        except ExceptionReport as err:
            QApplication.restoreOverrideCursor()
            QMessageBox.warning(self, self.tr('Search error'),
                                self.tr('Search error: {0}').format(err))
            return
        except Exception as err:
            QApplication.restoreOverrideCursor()
            QMessageBox.warning(self, self.tr('Connection error'),
                                self.tr('Connection error: {0}').format(err))
            return

        QApplication.restoreOverrideCursor()

        self.display_results()

    def add_to_ows(self):
        """add to OWS provider connection list"""

        conn_name_matches = []

        item = self.treeRecords.currentItem()

        if not item:
            return

        item_data = json.loads(get_item_data(item, 'link'))

        caller = self.sender().objectName()

        # stype = human name,/Qgis/connections-%s,providername
        if caller == 'mActionAddWms':
            stype = ['OGC:WMS/OGC:WMTS', 'wms', 'wms']
            data_url = item_data['wms']
        elif caller == 'mActionAddWfs':
            stype = ['OGC:WFS', 'wfs', 'WFS']
            data_url = item_data['wfs']
        elif caller == 'mActionAddWcs':
            stype = ['OGC:WCS', 'wcs', 'wcs']
            data_url = item_data['wcs']

        QApplication.restoreOverrideCursor()

        sname = '%s from MetaSearch' % stype[1]

        # store connection
        # check if there is a connection with same name
        self.settings.beginGroup('/Qgis/connections-%s' % stype[1])
        keys = self.settings.childGroups()
        self.settings.endGroup()

        for key in keys:
            if key.startswith(sname):
                conn_name_matches.append(key)
        if conn_name_matches:
            sname = conn_name_matches[-1]

        # check for duplicates
        if sname in keys:  # duplicate found
            if self.radioTitleAsk.isChecked():  # ask to overwrite
                msg = self.tr('Connection {0} exists. Overwrite?').format(
                    sname)
                res = QMessageBox.warning(self, self.tr('Saving server'), msg,
                                          QMessageBox.Yes | QMessageBox.No)
                if res != QMessageBox.Yes:  # assign new name with serial
                    sname = serialize_string(sname)
            elif self.radioTitleNoAsk.isChecked():  # don't ask to overwrite
                pass
            elif self.radioTempName.isChecked():  # use temp name
                sname = serialize_string(sname)

        # no dups detected or overwrite is allowed
        self.settings.beginGroup('/Qgis/connections-%s' % stype[1])
        self.settings.setValue('/%s/url' % sname, clean_ows_url(data_url))
        self.settings.endGroup()

        # open provider window
        ows_provider = QgsProviderRegistry.instance().selectWidget(
            stype[2], self)

        service_type = stype[0]

        # connect dialog signals to iface slots
        if service_type == 'OGC:WMS/OGC:WMTS':
            ows_provider.addRasterLayer.connect(self.iface.addRasterLayer)
            conn_cmb = ows_provider.findChild(QWidget, 'cmbConnections')
            connect = 'on_btnConnect_clicked'
        elif service_type == 'OGC:WFS':
            ows_provider.addWfsLayer.connect(
                self.iface.mainWindow().addWfsLayer)
            conn_cmb = ows_provider.findChild(QWidget, 'cmbConnections')
            connect = 'connectToServer'
        elif service_type == 'OGC:WCS':
            ows_provider.addRasterLayer.connect(self.iface.addRasterLayer)
            conn_cmb = ows_provider.findChild(QWidget, 'mConnectionsComboBox')
            connect = 'on_mConnectButton_clicked'
        ows_provider.setModal(False)
        ows_provider.show()

        # open provider dialogue against added OWS
        index = conn_cmb.findText(sname)
        if index > -1:
            conn_cmb.setCurrentIndex(index)
            # only for wfs
            if service_type == 'OGC:WFS':
                ows_provider.on_cmbConnections_activated(index)
        getattr(ows_provider, connect)()

    def show_metadata(self):
        """show record metadata"""

        if not self.treeRecords.selectedItems():
            return

        item = self.treeRecords.currentItem()
        if not item:
            return

        identifier = get_item_data(item, 'identifier')

        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            cat = CatalogueServiceWeb(self.catalog_url,
                                      timeout=self.timeout,
                                      username=self.catalog_username,
                                      password=self.catalog_password)
            cat.getrecordbyid([self.catalog.records[identifier].identifier])
        except ExceptionReport as err:
            QApplication.restoreOverrideCursor()
            QMessageBox.warning(
                self, self.tr('GetRecords error'),
                self.tr('Error getting response: {0}').format(err))
            return
        except KeyError as err:
            QMessageBox.warning(self, self.tr('Record parsing error'),
                                self.tr('Unable to locate record identifier'))
            QApplication.restoreOverrideCursor()
            return

        QApplication.restoreOverrideCursor()

        record = cat.records[identifier]
        record.xml_url = cat.request

        crd = RecordDialog()
        metadata = render_template('en', self.context, record,
                                   'record_metadata_dc.html')

        style = QgsApplication.reportStyleSheet()
        crd.textMetadata.document().setDefaultStyleSheet(style)
        crd.textMetadata.setHtml(metadata)
        crd.exec_()

    def show_xml(self):
        """show XML request / response"""

        crd = XMLDialog()
        request_html = highlight_xml(self.context, self.catalog.request)
        response_html = highlight_xml(self.context, self.catalog.response)
        style = QgsApplication.reportStyleSheet()
        crd.txtbrXMLRequest.clear()
        crd.txtbrXMLResponse.clear()
        crd.txtbrXMLRequest.document().setDefaultStyleSheet(style)
        crd.txtbrXMLResponse.document().setDefaultStyleSheet(style)
        crd.txtbrXMLRequest.setHtml(request_html)
        crd.txtbrXMLResponse.setHtml(response_html)
        crd.exec_()

    def reset_buttons(self, services=True, xml=True, navigation=True):
        """Convenience function to disable WMS/WMTS|WFS|WCS buttons"""

        if services:
            self.tbAddData.setEnabled(False)
            self.mActionAddWms.setEnabled(False)
            self.mActionAddWfs.setEnabled(False)
            self.mActionAddWcs.setEnabled(False)

        if xml:
            self.btnShowXml.setEnabled(False)

        if navigation:
            self.btnFirst.setEnabled(False)
            self.btnPrev.setEnabled(False)
            self.btnNext.setEnabled(False)
            self.btnLast.setEnabled(False)

    def help(self):
        """launch help"""

        open_url(get_help_url())

    def reject(self):
        """back out of dialogue"""

        QDialog.reject(self)
        self.rubber_band.reset()

    def _get_csw(self):
        """convenience function to init owslib.csw.CatalogueServiceWeb"""

        # connect to the server
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            self.catalog = CatalogueServiceWeb(self.catalog_url,
                                               timeout=self.timeout,
                                               username=self.catalog_username,
                                               password=self.catalog_password)
            return True
        except ExceptionReport as err:
            msg = self.tr('Error connecting to service: {0}').format(err)
        except ValueError as err:
            msg = self.tr('Value Error: {0}').format(err)
        except Exception as err:
            msg = self.tr('Unknown Error: {0}').format(err)

        QApplication.restoreOverrideCursor()
        QMessageBox.warning(self, self.tr('CSW Connection error'), msg)
        return False

    def install_proxy(self):
        """set proxy if one is set in QGIS network settings"""

        # initially support HTTP for now
        if self.settings.value('/proxy/proxyEnabled') == 'true':
            if self.settings.value('/proxy/proxyType') == 'HttpProxy':
                ptype = 'http'
            else:
                return

            user = self.settings.value('/proxy/proxyUser')
            password = self.settings.value('/proxy/proxyPassword')
            host = self.settings.value('/proxy/proxyHost')
            port = self.settings.value('/proxy/proxyPort')

            proxy_up = ''
            proxy_port = ''

            if all([user != '', password != '']):
                proxy_up = '%s:%s@' % (user, password)

            if port != '':
                proxy_port = ':%s' % port

            conn = '%s://%s%s%s' % (ptype, proxy_up, host, proxy_port)
            install_opener(build_opener(ProxyHandler({ptype: conn})))
Ejemplo n.º 46
0
class MultipleInputDialog(BASE, WIDGET):
    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 saveWindowGeometry(self):
        self.settings.setValue("/Processing/multipleInputDialogGeometry",
                               self.saveGeometry())

    def populateList(self):
        self.model = QStandardItemModel()
        for value, text in self.options:
            item = QStandardItem(text)
            item.setData(value, Qt.UserRole)
            item.setCheckState(Qt.Checked if value in
                               self.selectedoptions else Qt.Unchecked)
            item.setCheckable(True)
            self.model.appendRow(item)

        # add extra options (e.g. manually added layers)
        for t in [o for o in self.selectedoptions if not isinstance(o, int)]:
            if isinstance(t, QgsProcessingModelChildParameterSource):
                item = QStandardItem(t.staticValue())
            else:
                item = QStandardItem(t)
            item.setData(item.text(), Qt.UserRole)
            item.setCheckState(Qt.Checked)
            item.setCheckable(True)
            self.model.appendRow(item)

        self.lstLayers.setModel(self.model)

    def accept(self):
        self.selectedoptions = []
        model = self.lstLayers.model()
        for i in range(model.rowCount()):
            item = model.item(i)
            if item.checkState() == Qt.Checked:
                self.selectedoptions.append(item.data(Qt.UserRole))
        QDialog.accept(self)

    def reject(self):
        self.selectedoptions = None
        QDialog.reject(self)

    def getItemsToModify(self):
        items = []
        if len(self.lstLayers.selectedIndexes()) > 1:
            for i in self.lstLayers.selectedIndexes():
                items.append(self.model.itemFromIndex(i))
        else:
            for i in range(self.model.rowCount()):
                items.append(self.model.item(i))
        return items

    def selectAll(self, value):
        for item in self.getItemsToModify():
            item.setCheckState(Qt.Checked if value else Qt.Unchecked)

    def toggleSelection(self):
        for item in self.getItemsToModify():
            checked = item.checkState() == Qt.Checked
            item.setCheckState(Qt.Unchecked if checked else Qt.Checked)

    def getFileFilter(self, datatype):
        """
        Returns a suitable file filter pattern for the specified parameter definition
        :param param:
        :return:
        """
        if datatype == QgsProcessing.TypeRaster:
            return QgsProviderRegistry.instance().fileRasterFilters()
        elif datatype == QgsProcessing.TypeFile:
            return self.tr('All files (*.*)')
        else:
            exts = QgsVectorFileWriter.supportedFormatExtensions()
            for i in range(len(exts)):
                exts[i] = self.tr('{0} files (*.{1})').format(
                    exts[i].upper(), exts[i].lower())
            return self.tr('All files (*.*)') + ';;' + ';;'.join(exts)

    def addFiles(self):
        filter = self.getFileFilter(self.datatype)

        settings = QgsSettings()
        path = str(settings.value('/Processing/LastInputPath'))

        ret, selected_filter = QFileDialog.getOpenFileNames(
            self, self.tr('Select file(s)'), path, filter)
        if ret:
            files = list(ret)
            settings.setValue('/Processing/LastInputPath',
                              os.path.dirname(str(files[0])))
            for filename in files:
                item = QStandardItem(filename)
                item.setData(filename, Qt.UserRole)
                item.setCheckState(Qt.Checked)
                item.setCheckable(True)
                self.model.appendRow(item)
Ejemplo n.º 47
0
    def __init__(self, model=None):
        super().__init__(None)
        self.setAttribute(Qt.WA_DeleteOnClose)

        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():
                itemId = event.mimeData().text()
                if itemId in [
                        param.id() for param in QgsApplication.instance().
                        processingRegistry().parameterTypes()
                ]:
                    self.addInputOfType(itemId, event.pos())
                else:
                    alg = QgsApplication.processingRegistry(
                    ).createAlgorithmById(itemId)
                    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].data(0, Qt.UserRole)
            mimeData.setText(text)
            return mimeData

        self.inputsTree.mimeData = _mimeDataInput

        self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
        self.inputsTree.setDropIndicatorShown(True)

        def _mimeDataAlgorithm(items):
            item = items[0]
            mimeData = None
            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(
                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.textChanged)
        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.fillTreeUsingProviders()

        self.view.centerOn(0, 0)
        self.help = None

        self.hasChanged = False
Ejemplo n.º 48
0
    def doCheck(self, feedback):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT_LAYER))

        settings = QgsSettings()
        method = int(settings.value(settings_method_key, 1))

        valid_output = self.getOutputFromName(self.VALID_OUTPUT)
        valid_fields = layer.fields()
        valid_writer = valid_output.getVectorWriter(
            valid_fields,
            layer.wkbType(),
            layer.crs())
        valid_count = 0

        invalid_output = self.getOutputFromName(self.INVALID_OUTPUT)
        invalid_fields = layer.fields().toList() + [
            QgsField(name='_errors',
                     type=QVariant.String,
                     len=255)]
        invalid_writer = invalid_output.getVectorWriter(
            invalid_fields,
            layer.wkbType(),
            layer.crs())
        invalid_count = 0

        error_output = self.getOutputFromName(self.ERROR_OUTPUT)
        error_fields = [
            QgsField(name='message',
                     type=QVariant.String,
                     len=255)]
        error_writer = error_output.getVectorWriter(
            error_fields,
            QgsWkbTypes.Point,
            layer.crs())
        error_count = 0

        features = vector.features(layer)
        total = 100.0 / len(features)
        for current, inFeat in enumerate(features):
            geom = inFeat.geometry()
            attrs = inFeat.attributes()

            valid = True
            if not geom.isNull() and not geom.isEmpty():
                errors = list(geom.validateGeometry())
                if errors:
                    # QGIS method return a summary at the end
                    if method == 1:
                        errors.pop()
                    valid = False
                    reasons = []
                    for error in errors:
                        errFeat = QgsFeature()
                        error_geom = QgsGeometry.fromPoint(error.where())
                        errFeat.setGeometry(error_geom)
                        errFeat.setAttributes([error.what()])
                        error_writer.addFeature(errFeat)
                        error_count += 1

                        reasons.append(error.what())

                    reason = "\n".join(reasons)
                    if len(reason) > 255:
                        reason = reason[:252] + '...'
                    attrs.append(reason)

            outFeat = QgsFeature()
            outFeat.setGeometry(geom)
            outFeat.setAttributes(attrs)

            if valid:
                valid_writer.addFeature(outFeat)
                valid_count += 1

            else:
                invalid_writer.addFeature(outFeat)
                invalid_count += 1

            feedback.setProgress(int(current * total))

        del valid_writer
        del invalid_writer
        del error_writer

        if valid_count == 0:
            valid_output.open = False
        if invalid_count == 0:
            invalid_output.open = False
        if error_count == 0:
            error_output.open = False
Ejemplo n.º 49
0
class TestQgsSettings(unittest.TestCase):

    cnt = 0

    def setUp(self):
        self.cnt += 1
        h, path = tempfile.mkstemp('.ini')
        assert QgsSettings.setGlobalSettingsPath(path)
        self.settings = QgsSettings('testqgissettings',
                                    'testqgissettings%s' % self.cnt)
        self.globalsettings = QSettings(self.settings.globalSettingsPath(),
                                        QSettings.IniFormat)

    def tearDown(self):
        settings_file = self.settings.fileName()
        settings_default_file = self.settings.globalSettingsPath()
        del (self.settings)
        try:
            os.unlink(settings_file)
        except:
            pass
        try:
            os.unlink(settings_default_file)
        except:
            pass

    def addToDefaults(self, key, value):
        self.globalsettings.setValue(key, value)
        self.globalsettings.sync()

    def addArrayToDefaults(self, prefix, key, values):
        defaults = QSettings(self.settings.globalSettingsPath(),
                             QSettings.IniFormat)  # NOQA
        self.globalsettings.beginWriteArray(prefix)
        i = 0
        for v in values:
            self.globalsettings.setArrayIndex(i)
            self.globalsettings.setValue(key, v)
            i += 1
        self.globalsettings.endArray()
        self.globalsettings.sync()

    def addGroupToDefaults(self, prefix, kvp):
        defaults = QSettings(self.settings.globalSettingsPath(),
                             QSettings.IniFormat)  # NOQA
        self.globalsettings.beginGroup(prefix)
        for k, v in kvp.items():
            self.globalsettings.setValue(k, v)
        self.globalsettings.endGroup()
        self.globalsettings.sync()

    def test_basic_functionality(self):
        self.assertEqual(
            self.settings.value('testqgissettings/doesnotexists', 'notexist'),
            'notexist')
        self.settings.setValue('testqgissettings/name', 'qgisrocks')
        self.settings.sync()
        self.assertEqual(self.settings.value('testqgissettings/name'),
                         'qgisrocks')

    def test_defaults(self):
        self.assertIsNone(self.settings.value('testqgissettings/name'))
        self.addToDefaults('testqgissettings/name', 'qgisrocks')
        self.assertEqual(self.settings.value('testqgissettings/name'),
                         'qgisrocks')

    def test_allkeys(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/name', 'qgisrocks')
        self.addToDefaults('testqgissettings/name2', 'qgisrocks2')
        self.settings.setValue('nepoti/eman', 'osaple')

        self.assertEqual(3, len(self.settings.allKeys()))
        self.assertIn('testqgissettings/name', self.settings.allKeys())
        self.assertIn('nepoti/eman', self.settings.allKeys())
        self.assertEqual('qgisrocks',
                         self.settings.value('testqgissettings/name'))
        self.assertEqual('qgisrocks2',
                         self.settings.value('testqgissettings/name2'))
        self.assertEqual('qgisrocks',
                         self.globalsettings.value('testqgissettings/name'))
        self.assertEqual('osaple', self.settings.value('nepoti/eman'))
        self.assertEqual(3, len(self.settings.allKeys()))
        self.assertEqual(2, len(self.globalsettings.allKeys()))

    def test_precedence_simple(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/names/name1', 'qgisrocks1')
        self.settings.setValue('testqgissettings/names/name1', 'qgisrocks-1')

        self.assertEqual(self.settings.value('testqgissettings/names/name1'),
                         'qgisrocks-1')

    def test_precedence_group(self):
        """Test if user can override a group value"""
        self.assertEqual(self.settings.allKeys(), [])
        self.addGroupToDefaults(
            'connections-xyz', {
                'OSM': 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png',
                'OSM-b': 'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png',
            })
        self.settings.beginGroup('connections-xyz')
        self.assertEqual(self.settings.value('OSM'),
                         'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.assertEqual(self.settings.value('OSM-b'),
                         'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.settings.endGroup()

        # Override edit
        self.settings.beginGroup('connections-xyz')
        self.settings.setValue(
            'OSM', 'http://c.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.settings.endGroup()

        # Check it again!
        self.settings.beginGroup('connections-xyz')
        self.assertEqual(self.settings.value('OSM'),
                         'http://c.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.assertEqual(self.settings.value('OSM-b'),
                         'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.settings.endGroup()

        # Override remove: the global value will be resumed!!!
        self.settings.beginGroup('connections-xyz')
        self.settings.remove('OSM')
        self.settings.endGroup()

        # Check it again!
        self.settings.beginGroup('connections-xyz')
        self.assertEqual(self.settings.value('OSM'),
                         'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.assertEqual(self.settings.value('OSM-b'),
                         'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.settings.endGroup()

        # Override remove: store a blank!
        self.settings.beginGroup('connections-xyz')
        self.settings.setValue('OSM', '')
        self.settings.endGroup()

        # Check it again!
        self.settings.beginGroup('connections-xyz')
        self.assertEqual(self.settings.value('OSM'), '')
        self.assertEqual(self.settings.value('OSM-b'),
                         'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.settings.endGroup()

        # Override remove: store a None: will resume the global setting!
        self.settings.beginGroup('connections-xyz')
        self.settings.setValue('OSM', None)
        self.settings.endGroup()

        # Check it again!
        self.settings.beginGroup('connections-xyz')
        self.assertEqual(self.settings.value('OSM'),
                         'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.assertEqual(self.settings.value('OSM-b'),
                         'http://b.tile.openstreetmap.org/{z}/{x}/{y}.png')
        self.settings.endGroup()

    def test_uft8(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/names/namèé↓1', 'qgisrocks↓1')
        self.assertEqual(self.settings.value('testqgissettings/names/namèé↓1'),
                         'qgisrocks↓1')

        self.settings.setValue('testqgissettings/names/namèé↓2', 'qgisrocks↓2')
        self.assertEqual(self.settings.value('testqgissettings/names/namèé↓2'),
                         'qgisrocks↓2')
        self.settings.setValue('testqgissettings/names/namèé↓1',
                               'qgisrocks↓-1')
        self.assertEqual(self.settings.value('testqgissettings/names/namèé↓1'),
                         'qgisrocks↓-1')

    def test_groups(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/names/name1', 'qgisrocks1')
        self.addToDefaults('testqgissettings/names/name2', 'qgisrocks2')
        self.addToDefaults('testqgissettings/names/name3', 'qgisrocks3')
        self.addToDefaults('testqgissettings/name', 'qgisrocks')

        self.settings.beginGroup('testqgissettings')
        self.assertEqual(self.settings.group(), 'testqgissettings')
        self.assertEqual(['names'], self.settings.childGroups())

        self.settings.setValue('surnames/name1', 'qgisrocks-1')
        self.assertEqual(['surnames', 'names'], self.settings.childGroups())

        self.settings.setValue('names/name1', 'qgisrocks-1')
        self.assertEqual('qgisrocks-1', self.settings.value('names/name1'))
        self.settings.endGroup()
        self.assertEqual(self.settings.group(), '')
        self.settings.beginGroup('testqgissettings/names')
        self.assertEqual(self.settings.group(), 'testqgissettings/names')
        self.settings.setValue('name4', 'qgisrocks-4')
        keys = sorted(self.settings.childKeys())
        self.assertEqual(keys, ['name1', 'name2', 'name3', 'name4'])
        self.settings.endGroup()
        self.assertEqual(self.settings.group(), '')
        self.assertEqual('qgisrocks-1',
                         self.settings.value('testqgissettings/names/name1'))
        self.assertEqual('qgisrocks-4',
                         self.settings.value('testqgissettings/names/name4'))

    def test_global_groups(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.assertEqual(self.globalsettings.allKeys(), [])

        self.addToDefaults('testqgissettings/foo/first', 'qgis')
        self.addToDefaults('testqgissettings/foo/last', 'rocks')

        self.settings.beginGroup('testqgissettings')
        self.assertEqual(self.settings.group(), 'testqgissettings')
        self.assertEqual(['foo'], self.settings.childGroups())
        self.assertEqual(['foo'], self.settings.globalChildGroups())
        self.settings.endGroup()
        self.assertEqual(self.settings.group(), '')

        self.settings.setValue('testqgissettings/bar/first', 'qgis')
        self.settings.setValue('testqgissettings/bar/last', 'rocks')

        self.settings.beginGroup('testqgissettings')
        self.assertEqual(sorted(['bar', 'foo']),
                         sorted(self.settings.childGroups()))
        self.assertEqual(['foo'], self.settings.globalChildGroups())
        self.settings.endGroup()

        self.globalsettings.remove('testqgissettings/foo')

        self.settings.beginGroup('testqgissettings')
        self.assertEqual(['bar'], self.settings.childGroups())
        self.assertEqual([], self.settings.globalChildGroups())
        self.settings.endGroup()

    def test_group_section(self):
        # Test group by using Section
        self.settings.beginGroup('firstgroup', section=QgsSettings.Core)
        self.assertEqual(self.settings.group(), 'core/firstgroup')
        self.assertEqual([], self.settings.childGroups())
        self.settings.setValue('key', 'value')
        self.settings.setValue('key2/subkey1', 'subvalue1')
        self.settings.setValue('key2/subkey2', 'subvalue2')
        self.settings.setValue('key3', 'value3')

        self.assertEqual(['key', 'key2/subkey1', 'key2/subkey2', 'key3'],
                         self.settings.allKeys())
        self.assertEqual(['key', 'key3'], self.settings.childKeys())
        self.assertEqual(['key2'], self.settings.childGroups())
        self.settings.endGroup()
        self.assertEqual(self.settings.group(), '')
        # Set value by writing the group manually
        self.settings.setValue('firstgroup/key4',
                               'value4',
                               section=QgsSettings.Core)
        # Checking the value that have been set
        self.assertEqual(
            self.settings.value('firstgroup/key', section=QgsSettings.Core),
            'value')
        self.assertEqual(
            self.settings.value('firstgroup/key2/subkey1',
                                section=QgsSettings.Core), 'subvalue1')
        self.assertEqual(
            self.settings.value('firstgroup/key2/subkey2',
                                section=QgsSettings.Core), 'subvalue2')
        self.assertEqual(
            self.settings.value('firstgroup/key3', section=QgsSettings.Core),
            'value3')
        self.assertEqual(
            self.settings.value('firstgroup/key4', section=QgsSettings.Core),
            'value4')
        # Clean up firstgroup
        self.settings.remove('firstgroup', section=QgsSettings.Core)

    def test_array(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addArrayToDefaults('testqgissettings', 'key',
                                ['qgisrocks1', 'qgisrocks2', 'qgisrocks3'])
        self.assertEqual(self.settings.allKeys(), [
            'testqgissettings/1/key', 'testqgissettings/2/key',
            'testqgissettings/3/key', 'testqgissettings/size'
        ])
        self.assertEqual(self.globalsettings.allKeys(), [
            'testqgissettings/1/key', 'testqgissettings/2/key',
            'testqgissettings/3/key', 'testqgissettings/size'
        ])

        self.assertEqual(
            3, self.globalsettings.beginReadArray('testqgissettings'))
        self.globalsettings.endArray()
        self.assertEqual(3, self.settings.beginReadArray('testqgissettings'))

        values = []
        for i in range(3):
            self.settings.setArrayIndex(i)
            values.append(self.settings.value("key"))

        self.assertEqual(values, ['qgisrocks1', 'qgisrocks2', 'qgisrocks3'])

    def test_array_overrides(self):
        """Test if an array completely shadows the global one"""
        self.assertEqual(self.settings.allKeys(), [])
        self.addArrayToDefaults('testqgissettings', 'key',
                                ['qgisrocks1', 'qgisrocks2', 'qgisrocks3'])
        self.assertEqual(self.settings.allKeys(), [
            'testqgissettings/1/key', 'testqgissettings/2/key',
            'testqgissettings/3/key', 'testqgissettings/size'
        ])
        self.assertEqual(self.globalsettings.allKeys(), [
            'testqgissettings/1/key', 'testqgissettings/2/key',
            'testqgissettings/3/key', 'testqgissettings/size'
        ])

        self.assertEqual(
            3, self.globalsettings.beginReadArray('testqgissettings'))
        self.globalsettings.endArray()
        self.assertEqual(3, self.settings.beginReadArray('testqgissettings'))

        # Now override!
        self.settings.beginWriteArray('testqgissettings')
        self.settings.setArrayIndex(0)
        self.settings.setValue('key', 'myqgisrocksmore1')
        self.settings.setArrayIndex(1)
        self.settings.setValue('key', 'myqgisrocksmore2')
        self.settings.endArray()

        # Check it!
        self.assertEqual(2, self.settings.beginReadArray('testqgissettings'))

        values = []
        for i in range(2):
            self.settings.setArrayIndex(i)
            values.append(self.settings.value("key"))

        self.assertEqual(values, ['myqgisrocksmore1', 'myqgisrocksmore2'])

    def test_section_getters_setters(self):
        self.assertEqual(self.settings.allKeys(), [])

        self.settings.setValue('key1', 'core1', section=QgsSettings.Core)
        self.settings.setValue('key2', 'core2', section=QgsSettings.Core)

        self.settings.setValue('key1', 'server1', section=QgsSettings.Server)
        self.settings.setValue('key2', 'server2', section=QgsSettings.Server)

        self.settings.setValue('key1', 'gui1', section=QgsSettings.Gui)
        self.settings.setValue('key2', 'gui2', QgsSettings.Gui)

        self.settings.setValue('key1', 'plugins1', section=QgsSettings.Plugins)
        self.settings.setValue('key2', 'plugins2', section=QgsSettings.Plugins)

        self.settings.setValue('key1', 'misc1', section=QgsSettings.Misc)
        self.settings.setValue('key2', 'misc2', section=QgsSettings.Misc)

        self.settings.setValue('key1', 'auth1', section=QgsSettings.Auth)
        self.settings.setValue('key2', 'auth2', section=QgsSettings.Auth)

        self.settings.setValue('key1', 'app1', section=QgsSettings.App)
        self.settings.setValue('key2', 'app2', section=QgsSettings.App)

        self.settings.setValue('key1',
                               'provider1',
                               section=QgsSettings.Providers)
        self.settings.setValue('key2',
                               'provider2',
                               section=QgsSettings.Providers)

        self.settings.setValue('key1', 'auth1', section=QgsSettings.Auth)
        self.settings.setValue('key2', 'auth2', section=QgsSettings.Auth)

        # Test that the values are namespaced
        self.assertEqual(self.settings.value('core/key1'), 'core1')
        self.assertEqual(self.settings.value('core/key2'), 'core2')

        self.assertEqual(self.settings.value('server/key1'), 'server1')
        self.assertEqual(self.settings.value('server/key2'), 'server2')

        self.assertEqual(self.settings.value('gui/key1'), 'gui1')
        self.assertEqual(self.settings.value('gui/key2'), 'gui2')

        self.assertEqual(self.settings.value('plugins/key1'), 'plugins1')
        self.assertEqual(self.settings.value('plugins/key2'), 'plugins2')

        self.assertEqual(self.settings.value('misc/key1'), 'misc1')
        self.assertEqual(self.settings.value('misc/key2'), 'misc2')

        # Test getters
        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Core),
            'core1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Core),
            'core2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Server),
            'server1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Server),
            'server2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Gui), 'gui1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Gui), 'gui2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Plugins),
            'plugins1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Plugins),
            'plugins2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Misc),
            'misc1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Misc),
            'misc2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Auth),
            'auth1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Auth),
            'auth2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.App), 'app1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.App), 'app2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Providers),
            'provider1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Providers),
            'provider2')

        # Test default values on Section getter
        self.assertEqual(
            self.settings.value('key_not_exist',
                                'misc_not_exist',
                                section=QgsSettings.Misc), 'misc_not_exist')

    def test_contains(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/name', 'qgisrocks1')
        self.addToDefaults('testqgissettings/name2', 'qgisrocks2')

        self.assertTrue(self.settings.contains('testqgissettings/name'))
        self.assertTrue(self.settings.contains('testqgissettings/name2'))

        self.settings.setValue('testqgissettings/name3', 'qgisrocks3')
        self.assertTrue(self.settings.contains('testqgissettings/name3'))

    def test_remove(self):
        self.settings.setValue('testQgisSettings/temp', True)
        self.assertEqual(self.settings.value('testQgisSettings/temp'), True)
        self.settings.remove('testQgisSettings/temp')
        self.assertEqual(self.settings.value('testqQgisSettings/temp'), None)

        # Test remove by using Section
        self.settings.setValue('testQgisSettings/tempSection',
                               True,
                               section=QgsSettings.Core)
        self.assertEqual(
            self.settings.value('testQgisSettings/tempSection',
                                section=QgsSettings.Core), True)
        self.settings.remove('testQgisSettings/temp', section=QgsSettings.Core)
        self.assertEqual(
            self.settings.value('testqQgisSettings/temp',
                                section=QgsSettings.Core), None)

    def test_enumValue(self):
        self.settings.setValue('enum', 'LayerUnits')
        self.assertEqual(self.settings.enumValue('enum', QgsTolerance.Pixels),
                         QgsTolerance.LayerUnits)
        self.settings.setValue('enum', 'dummy_setting')
        self.assertEqual(self.settings.enumValue('enum', QgsTolerance.Pixels),
                         QgsTolerance.Pixels)
        self.assertEqual(
            type(self.settings.enumValue('enum', QgsTolerance.Pixels)),
            QgsTolerance.UnitType)

    def test_setEnumValue(self):
        self.settings.setValue('enum', 'LayerUnits')
        self.assertEqual(self.settings.enumValue('enum', QgsTolerance.Pixels),
                         QgsTolerance.LayerUnits)
        self.settings.setEnumValue('enum', QgsTolerance.Pixels)
        self.assertEqual(self.settings.enumValue('enum', QgsTolerance.Pixels),
                         QgsTolerance.Pixels)

    def test_flagValue(self):
        pointAndLine = QgsMapLayerProxyModel.Filters(
            QgsMapLayerProxyModel.PointLayer | QgsMapLayerProxyModel.LineLayer)
        pointAndPolygon = QgsMapLayerProxyModel.Filters(
            QgsMapLayerProxyModel.PointLayer
            | QgsMapLayerProxyModel.PolygonLayer)

        self.settings.setValue('flag', 'PointLayer|PolygonLayer')
        self.assertEqual(self.settings.flagValue('flag', pointAndLine),
                         pointAndPolygon)
        self.settings.setValue('flag', 'dummy_setting')
        self.assertEqual(self.settings.flagValue('flag', pointAndLine),
                         pointAndLine)
        self.assertEqual(type(self.settings.flagValue('enum', pointAndLine)),
                         QgsMapLayerProxyModel.Filters)
Ejemplo n.º 50
0
    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)
Ejemplo n.º 51
0
class AlgorithmDialogBase(BASE, WIDGET):
    def __init__(self, alg):
        super(AlgorithmDialogBase,
              self).__init__(iface.mainWindow() if iface else None)
        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 createFeedback(self):
        feedback = AlgorithmDialogFeedback(self)
        feedback.progressChanged.connect(self.setPercentage)
        feedback.error.connect(self.error)
        feedback.progress_text.connect(self.setText)
        feedback.info.connect(self.setInfo)
        feedback.command_info.connect(self.setCommand)
        feedback.debug_info.connect(self.setDebugInfo)
        feedback.console_info.connect(self.setConsoleInfo)

        self.buttonCancel.clicked.connect(feedback.cancel)
        return feedback

    def formatHelp(self, alg):
        text = alg.shortHelpString()
        if not text:
            return None
        return "<h2>%s</h2>%s" % (alg.displayName(), "".join(
            ["<p>%s</p>" % s for s in text.split("\n")]))

    def closeEvent(self, event):
        self._saveGeometry()
        super(AlgorithmDialogBase, self).closeEvent(event)

    def setMainWidget(self, widget):
        if self.mainWidget is not None:
            QgsProject.instance().layerWasAdded.disconnect(
                self.mainWidget.layerRegistryChanged)
            QgsProject.instance().layersWillBeRemoved.disconnect(
                self.mainWidget.layerRegistryChanged)
        self.mainWidget = widget
        self.tabWidget.widget(0).layout().addWidget(self.mainWidget)
        QgsProject.instance().layerWasAdded.connect(
            self.mainWidget.layerRegistryChanged)
        QgsProject.instance().layersWillBeRemoved.connect(
            self.mainWidget.layerRegistryChanged)

    def error(self, msg):
        self.setInfo(msg, True)
        self.resetGUI()
        self.tabWidget.setCurrentIndex(1)

    def resetGUI(self):
        self.lblProgress.setText('')
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)
        self.btnRun.setEnabled(True)
        self.btnClose.setEnabled(True)

    def setInfo(self, msg, error=False, escape_html=True):
        if error:
            self.txtLog.append(
                '<span style="color:red">{}</span><br />'.format(msg,
                                                                 quote=False))
        elif escape_html:
            self.txtLog.append(html.escape(msg))
        else:
            self.txtLog.append(msg)

    def setCommand(self, cmd):
        if self.showDebug:
            self.txtLog.append('<code>{}<code>'.format(
                html.escape(cmd, quote=False)))

    def setDebugInfo(self, msg):
        if self.showDebug:
            self.txtLog.append('<span style="color:blue">{}</span>'.format(
                html.escape(msg, quote=False)))

    def setConsoleInfo(self, msg):
        if self.showDebug:
            self.txtLog.append(
                '<code><span style="color:darkgray">{}</span></code>'.format(
                    html.escape(msg, quote=False)))

    def setPercentage(self, value):
        if self.progressBar.maximum() == 0:
            self.progressBar.setMaximum(100)
        self.progressBar.setValue(value)

    def setText(self, text):
        self.lblProgress.setText(text)
        self.setInfo(text, False)

    def getParamValues(self):
        return {}

    def accept(self):
        pass

    def reject(self):
        self._saveGeometry()
        super(AlgorithmDialogBase, self).reject()

    def finish(self, successful, result, context, feedback):
        pass

    def toggleCollapsed(self):
        if self.helpCollapsed:
            self.splitter.restoreState(self.splitterState)
            self.btnCollapse.setArrowType(Qt.RightArrow)
        else:
            self.splitterState = self.splitter.saveState()
            self.splitter.setSizes([1, 0])
            self.btnCollapse.setArrowType(Qt.LeftArrow)
        self.helpCollapsed = not self.helpCollapsed

    def splitterChanged(self, pos, index):
        if self.splitter.sizes()[1] == 0:
            self.helpCollapsed = True
            self.btnCollapse.setArrowType(Qt.LeftArrow)
        else:
            self.helpCollapsed = False
            self.btnCollapse.setArrowType(Qt.RightArrow)

    def openHelp(self):
        algHelp = self.alg.helpUrl()
        if not algHelp:
            algHelp = QgsHelp.helpUrl("processing_algs/{}/{}".format(
                self.alg.provider().id(), self.alg.id())).toString()

        if algHelp not in [None, ""]:
            webbrowser.open(algHelp)

    def _saveGeometry(self):
        self.settings.setValue("/Processing/dialogBaseSplitter",
                               self.splitter.saveState())
        self.settings.setValue("/Processing/dialogBase", self.saveGeometry())

    class InvalidParameterValue(Exception):
        def __init__(self, param, widget):
            (self.parameter, self.widget) = (param, widget)
Ejemplo n.º 52
0
                subprocess.call([
                    cmd, '{}'.format(
                        os.path.join(os.path.dirname(__file__), 'scripts',
                                     'modules_installer.py')),
                    ','.join(install_libraries)
                ])
            else:
                error = traceback.format_exc()
                QgsMessageLog.logMessage(error,
                                         tag="PyArchInit",
                                         level=Qgis.Critical)
    else:
        pass

s = QgsSettings()
if not Pyarchinit_OS_Utility.checkGraphvizInstallation() and s.value(
        'pyArchInit/graphvizBinPath'):
    os.environ['PATH'] += os.pathsep + os.path.normpath(
        s.value('pyArchInit/graphvizBinPath'))
if not Pyarchinit_OS_Utility.checkRInstallation() and s.value(
        'pyArchInit/rBinPath'):
    os.environ['PATH'] += os.pathsep + os.path.normpath(
        s.value('pyArchInit/rBinPath'))

packages = [
    'PypeR',
    'graphviz==0.8.3',
]
for p in packages:
    from qgis.PyQt.QtWidgets import QMessageBox

    if p.startswith('PypeR'):
Ejemplo n.º 53
0
class MultipleFileInputDialog(BASE, WIDGET):
    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 saveWindowGeometry(self):
        self.settings.setValue("/Processing/multipleInputDialogGeometry",
                               self.saveGeometry())

    def populateList(self):
        model = QStandardItemModel()
        for option in self.selectedoptions:
            item = QStandardItem(option)
            model.appendRow(item)

        self.lstLayers.setModel(model)

    def accept(self):
        self.selectedoptions = []
        model = self.lstLayers.model()
        for i in range(model.rowCount()):
            item = model.item(i)
            self.selectedoptions.append(item.text())
        QDialog.accept(self)

    def reject(self):
        QDialog.reject(self)

    def addFile(self):
        settings = QgsSettings()
        if settings.contains('/Processing/LastInputPath'):
            path = settings.value('/Processing/LastInputPath')
        else:
            path = ''

        files, selected_filter = QFileDialog.getOpenFileNames(
            self, self.tr('Select file(s)'), path, self.tr('All files (*.*)'))

        if len(files) == 0:
            return

        model = self.lstLayers.model()
        for filePath in files:
            item = QStandardItem(filePath)
            model.appendRow(item)

        settings.setValue('/Processing/LastInputPath',
                          os.path.dirname(files[0]))

    def removeRows(self, removeAll=False):
        if removeAll:
            self.lstLayers.model().clear()
        else:
            self.lstLayers.setUpdatesEnabled(False)
            indexes = sorted(self.lstLayers.selectionModel().selectedIndexes())
            for i in reversed(indexes):
                self.lstLayers.model().removeRow(i.row())
            self.lstLayers.setUpdatesEnabled(True)
Ejemplo n.º 54
0
    def showFileDialog(self, seldir):
        settings = QgsSettings()
        text = str(self.text.text())
        if os.path.isdir(text):
            path = text
        elif not seldir and os.path.isdir(os.path.dirname(text)):
            path = os.path.dirname(text)
        elif settings.contains('/Processing/LastInputPath'):
            path = str(settings.value('/Processing/LastInputPath'))
        else:
            path = ''

        if not seldir:
            ret, selected_filter = QFileDialog.getOpenFileNames(
                self, self.tr('Select Files'), path,
                self.param.createFileFilter())
        else:
            ret = QFileDialog.getExistingDirectory(self,
                                                   self.tr('Select Directory'),
                                                   path)

        if ret:
            if seldir:
                settings.setValue('/Processing/LastInputPath', ret)

                files = []
                for pp in Path(ret).rglob("*"):
                    if not pp.is_file():
                        continue

                    p = pp.as_posix()

                    if ((isinstance(self.param,
                                    QgsProcessingParameterRasterLayer) or
                         (isinstance(self.param,
                                     QgsProcessingParameterMultipleLayers) and
                          self.param.layerType() == QgsProcessing.TypeRaster))
                            and not QgsRasterLayer.isValidRasterFileName(p)):
                        continue

                    files.append(p)

                if not files:
                    return

            else:
                files = list(ret)
                settings.setValue('/Processing/LastInputPath',
                                  os.path.dirname(str(files[0])))

            for i, filename in enumerate(files):
                files[i] = dataobjects.getRasterSublayer(filename, self.param)
            if len(files) == 1:
                self.text.setText(files[0])
                self.textEditingFinished()
            else:
                if isinstance(self.param,
                              QgsProcessingParameterMultipleLayers):
                    self.text.setText(';'.join(str(f) for f in files))
                else:
                    rowdif = len(files) - (self._table().rowCount() - self.row)
                    for i in range(rowdif):
                        self._panel().addRow()
                    for i, f in enumerate(files):
                        self._table().cellWidget(i + self.row,
                                                 self.col).setValue(f)
Ejemplo n.º 55
0
class TestQgsSettings(unittest.TestCase):

    cnt = 0

    def setUp(self):
        self.cnt += 1
        h, path = tempfile.mkstemp('.ini')
        assert QgsSettings.setGlobalSettingsPath(path)
        self.settings = QgsSettings('testqgissettings',
                                    'testqgissettings%s' % self.cnt)
        self.globalsettings = QSettings(self.settings.globalSettingsPath(),
                                        QSettings.IniFormat)

    def tearDown(self):
        settings_file = self.settings.fileName()
        settings_default_file = self.settings.globalSettingsPath()
        del (self.settings)
        try:
            os.unlink(settings_file)
        except:
            pass
        try:
            os.unlink(settings_default_file)
        except:
            pass

    def addToDefaults(self, key, value):
        self.globalsettings.setValue(key, value)
        self.globalsettings.sync()

    def addArrayToDefaults(self, prefix, key, values):
        defaults = QSettings(self.settings.globalSettingsPath(),
                             QSettings.IniFormat)  # NOQA
        self.globalsettings.beginWriteArray(prefix)
        i = 0
        for v in values:
            self.globalsettings.setArrayIndex(i)
            self.globalsettings.setValue(key, v)
            i += 1
        self.globalsettings.endArray()
        self.globalsettings.sync()

    def test_basic_functionality(self):
        self.assertEqual(
            self.settings.value('testqgissettings/doesnotexists', 'notexist'),
            'notexist')
        self.settings.setValue('testqgissettings/name', 'qgisrocks')
        self.settings.sync()
        self.assertEqual(self.settings.value('testqgissettings/name'),
                         'qgisrocks')

    def test_defaults(self):
        self.assertIsNone(self.settings.value('testqgissettings/name'))
        self.addToDefaults('testqgissettings/name', 'qgisrocks')
        self.assertEqual(self.settings.value('testqgissettings/name'),
                         'qgisrocks')

    def test_allkeys(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/name', 'qgisrocks')
        self.addToDefaults('testqgissettings/name2', 'qgisrocks2')
        self.settings.setValue('nepoti/eman', 'osaple')

        self.assertEqual(3, len(self.settings.allKeys()))
        self.assertIn('testqgissettings/name', self.settings.allKeys())
        self.assertIn('nepoti/eman', self.settings.allKeys())
        self.assertEqual('qgisrocks',
                         self.settings.value('testqgissettings/name'))
        self.assertEqual('qgisrocks2',
                         self.settings.value('testqgissettings/name2'))
        self.assertEqual('qgisrocks',
                         self.globalsettings.value('testqgissettings/name'))
        self.assertEqual('osaple', self.settings.value('nepoti/eman'))
        self.assertEqual(3, len(self.settings.allKeys()))
        self.assertEqual(2, len(self.globalsettings.allKeys()))

    def test_precedence(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/names/name1', 'qgisrocks1')
        self.settings.setValue('testqgissettings/names/name1', 'qgisrocks-1')

        self.assertEqual(self.settings.value('testqgissettings/names/name1'),
                         'qgisrocks-1')

    def test_uft8(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/names/namèé↓1', 'qgisrocks↓1')
        self.assertEqual(self.settings.value('testqgissettings/names/namèé↓1'),
                         'qgisrocks↓1')

        self.settings.setValue('testqgissettings/names/namèé↓2', 'qgisrocks↓2')
        self.assertEqual(self.settings.value('testqgissettings/names/namèé↓2'),
                         'qgisrocks↓2')
        self.settings.setValue('testqgissettings/names/namèé↓1',
                               'qgisrocks↓-1')
        self.assertEqual(self.settings.value('testqgissettings/names/namèé↓1'),
                         'qgisrocks↓-1')

    def test_groups(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/names/name1', 'qgisrocks1')
        self.addToDefaults('testqgissettings/names/name2', 'qgisrocks2')
        self.addToDefaults('testqgissettings/names/name3', 'qgisrocks3')
        self.addToDefaults('testqgissettings/name', 'qgisrocks')

        self.settings.beginGroup('testqgissettings')
        self.assertEqual(['names'], self.settings.childGroups())

        self.settings.setValue('surnames/name1', 'qgisrocks-1')
        self.assertEqual(['surnames', 'names'], self.settings.childGroups())

        self.settings.setValue('names/name1', 'qgisrocks-1')
        self.assertEqual('qgisrocks-1', self.settings.value('names/name1'))
        self.settings.endGroup()
        self.settings.beginGroup('testqgissettings/names')
        self.settings.setValue('name4', 'qgisrocks-4')
        keys = sorted(self.settings.childKeys())
        self.assertEqual(keys, ['name1', 'name2', 'name3', 'name4'])
        self.settings.endGroup()
        self.assertEqual('qgisrocks-1',
                         self.settings.value('testqgissettings/names/name1'))
        self.assertEqual('qgisrocks-4',
                         self.settings.value('testqgissettings/names/name4'))

    def test_array(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addArrayToDefaults('testqgissettings', 'key',
                                ['qgisrocks1', 'qgisrocks2', 'qgisrocks3'])
        self.assertEqual(self.settings.allKeys(), [
            'testqgissettings/1/key', 'testqgissettings/2/key',
            'testqgissettings/3/key', 'testqgissettings/size'
        ])
        self.assertEqual(self.globalsettings.allKeys(), [
            'testqgissettings/1/key', 'testqgissettings/2/key',
            'testqgissettings/3/key', 'testqgissettings/size'
        ])

        self.assertEqual(
            3, self.globalsettings.beginReadArray('testqgissettings'))
        self.globalsettings.endArray()
        self.assertEqual(3, self.settings.beginReadArray('testqgissettings'))

        values = []
        for i in range(3):
            self.settings.setArrayIndex(i)
            values.append(self.settings.value("key"))

        self.assertEqual(values, ['qgisrocks1', 'qgisrocks2', 'qgisrocks3'])

    def test_section_getters_setters(self):
        self.assertEqual(self.settings.allKeys(), [])

        self.settings.setValue('key1', 'core1', section=QgsSettings.Core)
        self.settings.setValue('key2', 'core2', section=QgsSettings.Core)

        self.settings.setValue('key1', 'server1', section=QgsSettings.Server)
        self.settings.setValue('key2', 'server2', section=QgsSettings.Server)

        self.settings.setValue('key1', 'gui1', section=QgsSettings.Gui)
        self.settings.setValue('key2', 'gui2', QgsSettings.Gui)

        self.settings.setValue('key1', 'plugins1', section=QgsSettings.Plugins)
        self.settings.setValue('key2', 'plugins2', section=QgsSettings.Plugins)

        self.settings.setValue('key1', 'misc1', section=QgsSettings.Misc)
        self.settings.setValue('key2', 'misc2', section=QgsSettings.Misc)

        # Test that the values are namespaced
        self.assertEqual(self.settings.value('core/key1'), 'core1')
        self.assertEqual(self.settings.value('core/key2'), 'core2')

        self.assertEqual(self.settings.value('server/key1'), 'server1')
        self.assertEqual(self.settings.value('server/key2'), 'server2')

        self.assertEqual(self.settings.value('gui/key1'), 'gui1')
        self.assertEqual(self.settings.value('gui/key2'), 'gui2')

        self.assertEqual(self.settings.value('plugins/key1'), 'plugins1')
        self.assertEqual(self.settings.value('plugins/key2'), 'plugins2')

        self.assertEqual(self.settings.value('misc/key1'), 'misc1')
        self.assertEqual(self.settings.value('misc/key2'), 'misc2')

        # Test getters
        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Core),
            'core1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Core),
            'core2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Server),
            'server1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Server),
            'server2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Gui), 'gui1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Gui), 'gui2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Plugins),
            'plugins1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Plugins),
            'plugins2')

        self.assertEqual(
            self.settings.value('key1', None, section=QgsSettings.Misc),
            'misc1')
        self.assertEqual(
            self.settings.value('key2', None, section=QgsSettings.Misc),
            'misc2')

        # Test default values on Section getter
        self.assertEqual(
            self.settings.value('key_not_exist',
                                'misc_not_exist',
                                section=QgsSettings.Misc), 'misc_not_exist')

    def test_contains(self):
        self.assertEqual(self.settings.allKeys(), [])
        self.addToDefaults('testqgissettings/name', 'qgisrocks1')
        self.addToDefaults('testqgissettings/name2', 'qgisrocks2')

        self.assertTrue(self.settings.contains('testqgissettings/name'))
        self.assertTrue(self.settings.contains('testqgissettings/name2'))

        self.settings.setValue('testqgissettings/name3', 'qgisrocks3')
        self.assertTrue(self.settings.contains('testqgissettings/name3'))

    def test_remove(self):
        self.settings.setValue('testQgisSettings/temp', True)
        self.assertEqual(self.settings.value('testQgisSettings/temp'), True)
        self.settings.remove('testQgisSettings/temp')
        self.assertEqual(self.settings.value('testqQgisSettings/temp'), None)
Ejemplo n.º 56
0
    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 = QgsSettings()
        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 = QgsApplication.processingRegistry().algorithmById(
                        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 = QgsSettings()
            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 _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)

        try:
            iconSize = int(settings.value("iconsize", 24))
        except:
            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.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 alg is not None:
            self.alg = alg
            self.textGroup.setText(alg._group)
            self.textName.setText(alg.displayName())
            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
Ejemplo n.º 57
0
    def __init__(
            self,  # pylint: disable=too-many-locals,too-many-statements
            service_type,
            event_service,
            event_start_date=None,
            event_end_date=None,
            event_min_magnitude=None,
            event_max_magnitude=None,
            limit_extent_rect=False,
            min_latitude=None,
            max_latitude=None,
            min_longitude=None,
            max_longitude=None,
            limit_extent_circle=False,
            circle_latitude=None,
            circle_longitude=None,
            circle_min_radius=None,
            circle_max_radius=None,
            circle_radius_unit=QgsUnitTypes.DistanceDegrees,
            earthquake_number_mdps_greater=None,
            earthquake_max_intensity_greater=None,
            event_ids=None,
            contributor_id=None,
            network_codes=None,
            station_codes=None,
            locations=None,
            parent=None,
            output_fields=None,
            output_type=EXTENDED,
            convert_negative_depths=False,
            depth_unit=QgsUnitTypes.DistanceMeters,
            event_type: Optional[str] = None,
            updated_after: Optional[QDateTime] = None,
            split_strategy: Optional[str] = None,
            styles: Dict[str, str] = None,
            url=None):
        super().__init__(parent=parent)

        self.service_type = service_type
        self.service_id = event_service
        self.service_config = SERVICE_MANAGER.service_details(
            self.service_type, self.service_id)

        self.split_strategy = split_strategy
        self.exceeded_limit = False

        self.event_start_date = event_start_date
        self.event_end_date = event_end_date

        # if we have a split strategy set, we HAVE to have a full date range available
        if self.split_strategy is not None and self.event_start_date is None:
            self.event_start_date = QDateTime.fromString(
                self.service_config.get('datestart'), Qt.ISODate)
        if self.split_strategy is not None and self.event_end_date is None:
            self.event_end_date = QDateTime.fromString(
                self.service_config.get('dateend'),
                Qt.ISODate) if self.service_config.get(
                    'dateend') else QDateTime.currentDateTime()

        self.event_start_date_limit = self.event_start_date
        self.event_end_date_limit = self.event_end_date

        if self.split_strategy is not None:
            self.ranges = Fetcher.split_range_by_strategy(
                self.split_strategy, self.event_start_date,
                self.event_end_date)
            self.event_start_date, self.event_end_date = self.ranges[0]
            del self.ranges[0]
        else:
            self.ranges = None

        self.event_min_magnitude = event_min_magnitude
        self.event_max_magnitude = event_max_magnitude
        self.event_type = event_type
        self.limit_extent_rect = limit_extent_rect
        self.min_latitude = min_latitude
        self.max_latitude = max_latitude
        self.min_longitude = min_longitude
        self.max_longitude = max_longitude
        self.limit_extent_circle = limit_extent_circle
        self.circle_latitude = circle_latitude
        self.circle_longitude = circle_longitude
        self.circle_min_radius = circle_min_radius
        self.circle_max_radius = circle_max_radius
        self.circle_radius_unit = circle_radius_unit
        self.earthquake_number_mdps_greater = earthquake_number_mdps_greater
        self.earthquake_max_intensity_greater = earthquake_max_intensity_greater
        self.event_ids = event_ids
        self.contributor_id = contributor_id
        self.network_codes = network_codes
        self.station_codes = station_codes
        self.locations = locations
        self.pending_event_ids = event_ids
        self.macro_pending_event_ids = event_ids
        self.output_type = output_type
        self.convert_negative_depths = convert_negative_depths
        self.depth_unit = depth_unit
        self.updated_after = updated_after
        self.url = url

        s = QgsSettings()
        self.preferred_origins_only = s.value('/plugins/qquake/output_preferred_origins', True, bool) or not \
            self.service_config['settings'].get('queryincludeallorigins', False)
        self.preferred_magnitudes_only = s.value('/plugins/qquake/output_preferred_magnitude', True, bool) or not \
            self.service_config['settings'].get('queryincludeallmagnitudes', False)
        self.preferred_mdp_only = s.value(
            '/plugins/qquake/output_preferred_mdp', True, bool)

        self.output_fields = output_fields[:] if output_fields else []

        if self.output_type == self.EXTENDED:
            if not self.preferred_origins_only and "!IsPrefOrigin" not in self.output_fields:
                self.output_fields.append("!IsPrefOrigin")
            if not self.preferred_magnitudes_only and "!IsPrefMag" not in self.output_fields:
                self.output_fields.append("!IsPrefMag")
            if not self.preferred_mdp_only and "!IsPrefMdpset" not in self.output_fields:
                self.output_fields.append("!IsPrefMdpset")

            self.result = QuakeMlParser(
                convert_negative_depths=self.convert_negative_depths,
                depth_unit=self.depth_unit)
        else:
            self.result = BasicTextParser(
                convert_negative_depths=self.convert_negative_depths,
                depth_unit=self.depth_unit)

        self.missing_origins = set()
        self.is_missing_origin_request = False
        self.require_mdp_basic_text_request = self.output_type == self.BASIC and self.service_type == SERVICE_MANAGER.MACROSEISMIC
        self.is_mdp_basic_text_request = False
        self.is_first_request = True
        self.query_limit = None
        self.styles = styles
Ejemplo n.º 58
0
def test_settings(client) -> None:
    """ Test thas settings are read
    """
    settings = QgsSettings()
    val = settings.value('test/foobar')
    assert val == '42'
Ejemplo n.º 59
0
    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = HarmonyQGISDialog()

        # get stored settings
        settings = QgsSettings()

        # Fetch the currently loaded layers
        layers = QgsProject.instance().layerTreeRoot().children()
        layerNames = [layer.name() for layer in layers]

        # Clear the contents of the comboBox from previous runs
        self.dlg.comboBox.clear()
        # Populate the comboBox with names of all the loaded layers
        self.dlg.comboBox.addItems(layerNames)

        # use the previous layer as the default if it is in the existing layers
        # layerName = settings.value("harmony_qgis/layer")
        # if layerName and layerName in layerNames:
        #     self.dlg.comboBox.setCurrentIndex(layerNames.index(layerName))
        layer = self.iface.activeLayer()
        if layer:
            self.dlg.comboBox.setCurrentIndex(layerNames.index(layer.name()))

        # fill the harmnoy url input with the saved setting if available
        harmonyUrl = settings.value("harmony_qgis/harmony_url")
        if harmonyUrl:
            self.dlg.harmonyUrlLineEdit.setText(harmonyUrl)

        collectionId = settings.value("harmony_qgis/collection_id")
        if collectionId:
            self.dlg.collectionField.setText(collectionId)

        version = settings.value("harmony_qgis/version") or "1.0.0"
        self.dlg.versionField.setText(version)

        variable = settings.value("harmony_qgis/variable")
        if variable:
            self.dlg.variableField.setText(variable)

        # clear the table
        self.dlg.tableWidget.setRowCount(0)

        # set the table header
        self.dlg.tableWidget.setHorizontalHeaderLabels('Parameter;Value'.split(';'))

        # add a parameter/value when the 'Add' button is clicked
        self.dlg.addButton.clicked.connect(self.addSearchParameter)

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            collectionId = str(self.dlg.collectionField.text())
            version = str(self.dlg.versionField.text())
            variable = str(self.dlg.variableField.text())

            layerName = str(self.dlg.comboBox.currentText())
            # TODO handle the case where there is more than one layer by this name
            layer = QgsProject.instance().mapLayersByName(layerName)[0]
            opts = QgsVectorFileWriter.SaveVectorOptions()
            opts.driverName = 'GeoJson'
            tempFile = '/tmp/qgis.json'
            QgsVectorFileWriter.writeAsVectorFormatV2(layer, tempFile, QgsCoordinateTransformContext(), opts)

            harmonyUrl = self.dlg.harmonyUrlLineEdit.text()
            path = collectionId + "/" + "ogc-api-coverages/" + version + "/collections/" + variable + "/coverage/rangeset"
            url = harmonyUrl + "/" + path
            print(url)

            tempFileHandle = open(tempFile, 'r')
            contents = tempFileHandle.read()
            tempFileHandle.close()
            geoJson = rewind(contents)
            tempFileHandle = open(tempFile, 'w')
            tempFileHandle.write(geoJson)
            tempFileHandle.close()
            tempFileHandle = open(tempFile, 'rb')

            multipart_form_data = {
                'shapefile': (layerName + '.geojson', tempFileHandle, 'application/geo+json')
            }

            rowCount = self.dlg.tableWidget.rowCount()
            for row in range(rowCount):
                parameter = self.dlg.tableWidget.item(row, 0).text()
                value = self.dlg.tableWidget.item(row, 1).text()
                multipart_form_data[parameter] = (None, value)

            resp = requests.post(url, files=multipart_form_data, stream=True)
            tempFileHandle.close()
            # print(resp)
            # print(resp.text)
            with open('/tmp/harmony_output_image.tif', 'wb') as fd:
                for chunk in resp.iter_content(chunk_size=128):
                    fd.write(chunk)

            os.remove(tempFile)

            self.iface.addRasterLayer('/tmp/harmony_output_image.tif', layerName + '-' + variable)
            # QgsRasterLayer('/tmp/harmony_output_image.tif', layerName)

            # save settings
            if collectionId != "":
                settings.setValue("harmony_qgis/collection_id", collectionId)
            if version != "":
                settings.setValue("harmony_qgis/version", version)
            if variable != "":
                settings.setValue("harmony_qgis/variable", variable)
            if harmonyUrl != "":
                settings.setValue("harmony_qgis/harmony_url", harmonyUrl)
            settings.setValue("harmony_qgis/layer", layerName)