def authcfg_edit(self): dlg = QDialog(None) dlg.setWindowTitle(self.util.tr("Select Authentication")) layout = QtGui.QVBoxLayout(dlg) acs = QgsAuthConfigSelect(dlg) if self.IDC_leAuthCfg.text(): acs.setConfigId(self.IDC_leAuthCfg.text()) layout.addWidget(acs) buttonbox = QtGui.QDialogButtonBox( QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel, Qt.Horizontal, dlg ) layout.addWidget(buttonbox) buttonbox.accepted.connect(dlg.accept) buttonbox.rejected.connect(dlg.close) dlg.setLayout(layout) dlg.setWindowModality(Qt.WindowModal) if dlg.exec_(): self.IDC_leAuthCfg.setText(acs.configId()) self.cc.authcfg = acs.configId()
class AuthConfigSelectDialog(QDialog): """Dialog to select a Authentication config ID from that available in the QGIS Authentication DB. Select can be restricted to that supported by a specified and supported provider. """ def __init__(self, parent=None, authcfg=None, provider=None): super(AuthConfigSelectDialog, self).__init__(parent) self.authcfg = authcfg #self.resize(600, 350) self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint) self.setWindowTitle("Authentication config ID selector") layout = QVBoxLayout() buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.editor = QgsAuthConfigSelect(self, dataprovider=provider) self.editor.setConfigId(authcfg) layout.addWidget(self.editor) layout.addWidget(buttonBox) self.setLayout(layout) buttonBox.accepted.connect(self.okPressed) buttonBox.rejected.connect(self.cancelPressed) def okPressed(self): self.authcfg = self.editor.configId() self.accept() def cancelPressed(self): self.reject()
def add_authentication(self): """Slot for when the add auth button is clicked.""" if qgis_version() >= 21200: from qgis.gui import QgsAuthConfigSelect dlg = QDialog(self) dlg.setWindowTitle(self.tr("Select Authentication")) layout = QVBoxLayout(dlg) acs = QgsAuthConfigSelect(dlg) if self.line_edit_auth_id.text(): acs.setConfigId(self.line_edit_auth_id.text()) layout.addWidget(acs) button_box = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, dlg) layout.addWidget(button_box) button_box.accepted.connect(dlg.accept) button_box.rejected.connect(dlg.close) dlg.setLayout(layout) dlg.setWindowModality(Qt.WindowModal) if dlg.exec_(): self.line_edit_auth_id.setText(acs.configId()) del dlg
def add_authentication(self): """Slot for when the add auth button is clicked.""" if qgis_version() >= 21200: from qgis.gui import QgsAuthConfigSelect dlg = QDialog(self) dlg.setWindowTitle(self.tr("Select Authentication")) layout = QVBoxLayout(dlg) acs = QgsAuthConfigSelect(dlg) if self.line_edit_auth_id.text(): acs.setConfigId(self.line_edit_auth_id.text()) layout.addWidget(acs) button_box = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, dlg) layout.addWidget(button_box) button_box.accepted.connect(dlg.accept) button_box.rejected.connect(dlg.close) dlg.setLayout(layout) dlg.setWindowModality(Qt.WindowModal) if dlg.exec_(): self.line_edit_auth_id.setText(acs.configId()) del dlg
def authcfg_edit(self): dlg = QDialog(None) dlg.setWindowTitle(self.util.tr("Select Authentication")) layout = QVBoxLayout(dlg) acs = QgsAuthConfigSelect(dlg) if self.IDC_leAuthCfg.text(): acs.setConfigId(self.IDC_leAuthCfg.text()) layout.addWidget(acs) buttonbox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, dlg) layout.addWidget(buttonbox) buttonbox.accepted.connect(dlg.accept) buttonbox.rejected.connect(dlg.close) dlg.setLayout(layout) dlg.setWindowModality(Qt.WindowModal) if dlg.exec_(): self.IDC_leAuthCfg.setText(acs.configId()) self.cc.auth_cfg = acs.configId()
def editAuthCfgId(self): dlg = QDialog(self) dlg.setWindowModality(Qt.WindowModal) layout = QVBoxLayout() selector = QgsAuthConfigSelect(self) if self.editAuthCfg.text(): selector.setConfigId(self.editAuthCfg.text()) layout.addWidget(selector) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close) buttonBox.accepted.connect(dlg.accept) buttonBox.rejected.connect(dlg.reject) layout.addWidget(buttonBox) dlg.setLayout(layout) if dlg.exec_(): self.editAuthCfg.setText(selector.configId()) del dlg
class ALKISConf(QDialog, ConfBase): def __init__(self, plugin): QDialog.__init__(self) self.setupUi(self) self.plugin = plugin self.settings = plugin.settings self.settings.loadSettings() self.leSERVICE.setText(self.settings.service) self.leHOST.setText(self.settings.host) self.lePORT.setText(self.settings.port) self.leDBNAME.setText(self.settings.dbname) self.leSCHEMA.setText(self.settings.schema) self.leUID.setText(self.settings.uid) self.lePWD.setText(self.settings.pwd) self.cbxSignaturkatalog.setEnabled(False) if hasattr(qgis.gui, 'QgsAuthConfigSelect'): self.authCfgSelect = QgsAuthConfigSelect(self, "postgres") self.tabWidget.insertTab(1, self.authCfgSelect, "Konfigurationen") authcfg = self.settings.authcfg if authcfg: self.tabWidget.setCurrentIndex(1) self.authCfgSelect.setConfigId(authcfg) self.leUMNPath.setText(self.settings.umnpath) self.pbUMNBrowse.clicked.connect(self.browseUMNPath) self.leUMNTemplate.setText(self.settings.umntemplate) self.teFussnote.setPlainText(self.settings.footnote) self.loadModels(False) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.bb.addButton("Modelle laden", QDialogButtonBox.ActionRole).clicked.connect(self.loadModels) self.bb.addButton("Layer einbinden", QDialogButtonBox.ActionRole).clicked.connect(self.loadLayers) self.restoreGeometry(QSettings("norBIT", "norGIS-ALKIS-Erweiterung").value("confgeom", QByteArray(), type=QByteArray)) def done(self, r): QSettings("norBIT", "norGIS-ALKIS-Erweiterung").setValue("confgeom", self.saveGeometry()) return QDialog.done(self, r) def loadModels(self, error=True): self.settings.service = self.leSERVICE.text() self.settings.host = self.leHOST.text() self.settings.port = self.lePORT.text() self.settings.dbname = self.leDBNAME.text() self.settings.schema = self.leSCHEMA.text() self.settings.uid = self.leUID.text() self.settings.pwd = self.lePWD.text() if hasattr(qgis.gui, 'QgsAuthConfigSelect'): self.settings.authcfg = self.authCfgSelect.configId() self.twModellarten.clearContents() self.cbxSignaturkatalog.clear() (db, conninfo) = self.plugin.opendb() if not db: if error: QMessageBox.critical(None, "ALKIS", u"Datenbankverbindung schlug fehl.") self.settings.load() return modelle = self.settings.modellarten if modelle is None: modelle = ['DLKM', 'DKKM1000'] qry = QSqlQuery(db) if qry.exec_(""" SELECT modell,count(*) FROM ( SELECT unnest(modell) AS modell FROM po_points UNION ALL SELECT unnest(modell) AS modell FROM po_lines UNION ALL SELECT unnest(modell) AS modell FROM po_polygons UNION ALL SELECT unnest(modell) AS modell from po_lines UNION ALL SELECT unnest(modell) AS modell from po_labels ) AS foo GROUP BY modell ORDER BY count(*) DESC """): res = {} while qry.next(): res[qry.value(0)] = qry.value(1) self.twModellarten.setRowCount(len(res)) i = 0 for k, n in sorted(iter(list(res.items())), key=operator.itemgetter(1), reverse=True): item = QTableWidgetItem(k) item.setCheckState(Qt.Checked if (item.text() in modelle) else Qt.Unchecked) self.twModellarten.setItem(i, 0, item) item = QTableWidgetItem(str(n)) self.twModellarten.setItem(i, 1, item) i += 1 self.twModellarten.resizeColumnsToContents() self.twModellarten.setEnabled(True) else: self.twModellarten.clearContents() self.twModellarten.setDisabled(True) if qry.exec_("SELECT id,name FROM alkis_signaturkataloge"): while qry.next(): self.cbxSignaturkatalog.addItem(qry.value(1), int(qry.value(0))) self.cbxSignaturkatalog.setEnabled(True) else: self.cbxSignaturkatalog.addItem(u"Farbe", -1) self.cbxSignaturkatalog.setCurrentIndex(max([0, self.cbxSignaturkatalog.findData(self.settings.signaturkatalog)])) self.settings.load() def saveSettings(self): self.settings.service = self.leSERVICE.text() self.settings.host = self.leHOST.text() self.settings.port = self.lePORT.text() self.settings.dbname = self.leDBNAME.text() self.settings.schema = self.leSCHEMA.text() self.settings.uid = self.leUID.text() self.settings.pwd = self.lePWD.text() if hasattr(qgis.gui, 'QgsAuthConfigSelect'): self.settings.authcfg = self.authCfgSelect.configId() self.settings.umnpath = self.leUMNPath.text() self.settings.umntemplate = self.leUMNTemplate.text() self.settings.footnote = self.teFussnote.toPlainText() modelle = [] if self.twModellarten.isEnabled(): for i in range(self.twModellarten.rowCount()): item = self.twModellarten.item(i, 0) if item.checkState() == Qt.Checked: modelle.append(item.text()) self.settings.modellarten = modelle self.settings.signaturkatalog = self.cbxSignaturkatalog.itemData(self.cbxSignaturkatalog.currentIndex()) self.settings.saveSettings() def loadLayers(self): self.saveSettings() self.plugin.run() self.settings.load() QDialog.accept(self) def accept(self): self.saveSettings() self.settings.load() QDialog.accept(self) def browseUMNPath(self): path = self.leUMNPath.text() path = QFileDialog.getExistingDirectory(self, u"UMN-Pfad wählen", path) if path != "": self.leUMNPath.setText(path)
class GeoServerWidget(ServerWidgetBase, BASE, WIDGET): def __init__(self, parent, server_type): super().__init__(parent, server_type) self.setupUi(self) self.geoserverAuth = QgsAuthConfigSelect() self.geoserverAuth.selectedConfigIdChanged.connect(self.setDirty) self.addAuthWidget() self.populateStorageCombo() self.comboStorageType.currentIndexChanged.connect(self.datastoreChanged) self.btnRefreshDatabases.clicked.connect(partial(self.updateDbServersCombo, True)) self.btnAddDatastore.clicked.connect(self.addPostgisDatastore) self.txtGeoserverName.textChanged.connect(self.setDirty) self.txtGeoserverUrl.textChanged.connect(self.setDirty) self.chkUseOriginalDataSource.stateChanged.connect(self.setDirty) self.chkUseVectorTiles.stateChanged.connect(self.setDirty) self.comboGeoserverDatabase.currentIndexChanged.connect(self.setDirty) # Declare progress dialog self._pgdialog = None def createServerInstance(self): """ Reads the settings form fields and returns a new server instance with these settings. """ db = None storage = self.comboStorageType.currentIndex() if storage in (GeoserverStorage.POSTGIS_BRIDGE, GeoserverStorage.POSTGIS_GEOSERVER): db = self.comboGeoserverDatabase.currentText() try: name = self.txtGeoserverName.text().strip() url = self.txtGeoserverUrl.text().strip() if not name: raise RuntimeError(f'missing {self.serverType.getLabel()} name') if not url: raise RuntimeError(f'missing {self.serverType.getLabel()} URL') return self.serverType( name=name, authid=self.geoserverAuth.configId() or None, url=url, storage=storage, postgisdb=db, useOriginalDataSource=self.chkUseOriginalDataSource.isChecked(), useVectorTiles=self.chkUseVectorTiles.isChecked() ) except Exception as e: self.parent.logError(f"Failed to create {self.serverType.getLabel()} instance: {e}") return None def newFromName(self, name: str): """ Sets the name field and keeps all others empty. """ self.txtGeoserverName.setText(name) self.txtGeoserverUrl.clear() self.geoserverAuth.setConfigId(None) # Set datastore and database comboboxes self.comboStorageType.blockSignals(True) self.comboStorageType.setCurrentIndex(GeoserverStorage.FILE_BASED) self.datastoreChanged(GeoserverStorage.FILE_BASED) self.chkUseOriginalDataSource.setChecked(False) self.chkUseVectorTiles.setChecked(False) self.comboStorageType.blockSignals(False) def loadFromInstance(self, server): """ Populates the form fields with the values from the given server instance. """ self.txtGeoserverName.setText(server.serverName) self.txtGeoserverUrl.setText(server.baseUrl) self.geoserverAuth.setConfigId(server.authId) # Set datastore and database comboboxes self.comboStorageType.blockSignals(True) self.comboStorageType.setCurrentIndex(server.storage) self.datastoreChanged(server.storage, server.postgisdb) self.chkUseOriginalDataSource.setChecked(server.useOriginalDataSource) self.chkUseVectorTiles.setChecked(server.useVectorTiles) self.comboStorageType.blockSignals(False) # After the data has loaded, the form is "clean" self.setClean() def addAuthWidget(self): layout = QHBoxLayout() layout.setContentsMargins(0, 3, 0, 0) layout.addWidget(self.geoserverAuth) self.geoserverAuthWidget.setLayout(layout) self.geoserverAuthWidget.setFixedHeight(self.txtGeoserverUrl.height()) def populateStorageCombo(self): self.comboStorageType.clear() self.comboStorageType.addItems(GeoserverStorage.values()) def datastoreChanged(self, storage, init_value=None): """ Called each time the database combobox selection changed. """ if storage is None: storage = GeoserverStorage[self.comboStorageType.currentIndex()] if storage == GeoserverStorage.POSTGIS_BRIDGE: self.updateDbServersCombo(False, init_value) self.comboGeoserverDatabase.setVisible(True) self.labelGeoserverDatastore.setText('Database') self.labelGeoserverDatastore.setVisible(True) self.datastoreControls.setVisible(False) elif storage == GeoserverStorage.POSTGIS_GEOSERVER: self.comboGeoserverDatabase.setVisible(True) self.labelGeoserverDatastore.setText('Datastore') self.labelGeoserverDatastore.setVisible(True) self.datastoreControls.setVisible(True) self.updateDbServersCombo(True, init_value) elif storage == GeoserverStorage.FILE_BASED: self.comboGeoserverDatabase.setVisible(False) self.labelGeoserverDatastore.setVisible(False) self.datastoreControls.setVisible(False) self.setDirty() def addGeoserverPgDatastores(self, current, result): if self._pgdialog and self._pgdialog.isVisible(): self._pgdialog.hide() if result: # Worker result might be a list of lists, so we should flatten it datastores = list(chain.from_iterable(result)) self.comboGeoserverDatabase.addItems(datastores) if current: self.comboGeoserverDatabase.setCurrentText(current) else: self.parent.showWarningBar("Warning", "No PostGIS datastores on server or could not retrieve them") def showProgressDialog(self, text, length, handler): self._pgdialog = QProgressDialog(text, "Cancel", 0, length, self) self._pgdialog.setWindowTitle(getAppName()) self._pgdialog.setWindowModality(QtCore.Qt.WindowModal) self._pgdialog.canceled.connect(handler, type=QtCore.Qt.DirectConnection) self._pgdialog.forceShow() def updateDbServersCombo(self, managed_by_geoserver: bool, init_value=None): """ (Re)populate the combobox with database-driven datastores. :param managed_by_geoserver: If True, GeoServer manages the DB connection. If False, Bridge manages it. :param init_value: When the combobox shows for the first time and no databases have been loaded, this value can be set immediately as the only available and selected item. Doing so prevents a full refresh of GeoServer datastores. """ if managed_by_geoserver and init_value: if self.comboGeoserverDatabase.count() == 0: # Only add the given init_value item to the empty combo (user should manually refresh) self.comboGeoserverDatabase.addItem(init_value) self.comboGeoserverDatabase.setCurrentText(init_value) return # If combo has values, try and find the init_value and set it to that (user should manually refresh) index = self.comboGeoserverDatabase.findText(init_value) if index >= 0: self.comboGeoserverDatabase.setCurrentIndex(index) return current_db = self.comboGeoserverDatabase.currentText() or init_value self.comboGeoserverDatabase.clear() if managed_by_geoserver: # Database is managed by GeoServer: instantiate server and retrieve datastores # TODO: only PostGIS datastores are supported for now server = self.createServerInstance() if not server: self.parent.showErrorBar("Error", "Bad values in server definition") return try: # Retrieve workspaces (single REST request) workspaces = gui.execute(server.getWorkspaces) if not workspaces: return # Retrieve datastores for each workspace: # This is a potentially long-running operation and uses a separate QThread worker = gui.ItemProcessor(workspaces, server.getPostgisDatastores) self.showProgressDialog("Fetching PostGIS datastores...", len(workspaces), worker.stop) worker.progress.connect(self._pgdialog.setValue) worker.finished.connect(partial(self.addGeoserverPgDatastores, current_db)) worker.run() except Exception as e: msg = f'Failed to retrieve datastores for {self.serverName}' if isinstance(e, HTTPError) and e.response.status_code == 401: msg = f'{msg}: please check credentials' else: msg = f'{msg}: {e}' self.parent.showErrorBar(msg) else: # Database is managed by Bridge: iterate over all user-defined database connections db_servers = self.parent.serverManager.getDbServerNames() self.comboGeoserverDatabase.addItems(db_servers) if current_db in db_servers: self.comboGeoserverDatabase.setCurrentText(current_db) def addPostgisDatastore(self): server = self.createServerInstance() if server is None: self.parent.showErrorBar("Error", "Wrong values in server definition") return dlg = GeoserverDatastoreDialog(self) dlg.exec_() name = dlg.name if name is None: return def _entry(k, v): return {"@key": k, "$": v} ds = { "dataStore": { "name": dlg.name, "type": "PostGIS", "enabled": True, "connectionParameters": { "entry": [ _entry("schema", dlg.schema), _entry("port", dlg.port), _entry("database", dlg.database), _entry("passwd", dlg.password), _entry("user", dlg.username), _entry("host", dlg.host), _entry("dbtype", "postgis") ] } } } try: gui.execute(partial(server.addPostgisDatastore, ds)) except Exception as e: self.parent.showErrorBar("Error", "Could not create new PostGIS dataset", propagate=e) else: self.updateDbServersCombo(True)
class GeoNetworkWidget(ServerWidgetBase, BASE, WIDGET): def __init__(self, parent, server_type): super().__init__(parent, server_type) self.setupUi(self) self.geonetworkAuth = QgsAuthConfigSelect() self.geonetworkAuth.selectedConfigIdChanged.connect(self.setDirty) self.addAuthWidget() self.txtGeonetworkName.textChanged.connect(self.setDirty) self.txtGeonetworkNode.textChanged.connect(self.setDirty) self.txtGeonetworkUrl.textChanged.connect(self.setDirty) self.populateProfileCombo() self.comboMetadataProfile.currentIndexChanged.connect(self.setDirty) # TODO: implement profile stuff self.comboMetadataProfile.setVisible(False) self.labelMetadataProfile.setVisible(False) def createServerInstance(self): """ Reads the settings form fields and returns a new server instance with these settings. """ try: name = self.txtGeonetworkName.text().strip() url = self.txtGeonetworkUrl.text().strip() if not name: raise RuntimeError( f'missing {self.serverType.getLabel()} name') if not url: raise RuntimeError(f'missing {self.serverType.getLabel()} URL') return self.serverType( name=name, authid=self.geonetworkAuth.configId() or None, url=url, # profile=self.comboMetadataProfile.currentIndex(), node=self.txtGeonetworkNode.text().strip() or 'srv') except Exception as e: self.parent.logError( f"Failed to create {self.serverType.getLabel()} instance: {e}") return None def newFromName(self, name: str): """ Sets the name field and keeps all others empty. """ self.txtGeonetworkName.setText(name) self.txtGeonetworkUrl.clear() self.txtGeonetworkNode.clear() self.geonetworkAuth.setConfigId(None) # Reset profile combobox self.comboMetadataProfile.blockSignals(True) self.comboMetadataProfile.setCurrentIndex(GeoNetworkProfiles.DEFAULT) self.comboMetadataProfile.blockSignals(False) def loadFromInstance(self, server): """ Populates the form fields with the values from the given server instance. """ self.txtGeonetworkName.setText(server.serverName) self.txtGeonetworkUrl.setText(server.baseUrl) self.geonetworkAuth.setConfigId(server.authId) # Reset profile combobox self.comboMetadataProfile.blockSignals(True) self.comboMetadataProfile.setCurrentIndex(server.profile) self.comboMetadataProfile.blockSignals(False) # After the data has loaded, the form is "clean" self.setClean() def addAuthWidget(self): layout = QHBoxLayout() layout.setContentsMargins(0, 3, 0, 0) layout.addWidget(self.geonetworkAuth) self.geonetworkAuthWidget.setLayout(layout) self.geonetworkAuthWidget.setFixedHeight( self.txtGeonetworkUrl.height()) def populateProfileCombo(self): self.comboMetadataProfile.clear() self.comboMetadataProfile.addItems(GeoNetworkProfiles.values())
class PostgisWidget(ServerWidgetBase, BASE, WIDGET): def __init__(self, parent, server_type): super().__init__(parent, server_type) self.setupUi(self) self.postgisAuth = QgsAuthConfigSelect() self.postgisAuth.selectedConfigIdChanged.connect(self.setDirty) self.addAuthWidget() self.txtPostgisName.textChanged.connect(self.setDirty) self.txtPostgisServerAddress.textChanged.connect(self.setDirty) self.txtPostgisPort.textChanged.connect(self.setDirty) self.txtPostgisSchema.textChanged.connect(self.setDirty) self.txtPostgisDatabase.textChanged.connect(self.setDirty) def createServerInstance(self): """ Reads the settings form fields and returns a new server instance with these settings. """ try: name = self.txtPostgisName.text().strip() host = self.txtPostgisServerAddress.text().strip() if not name: raise RuntimeError( f'missing {self.serverType.getLabel()} name') if not host: raise RuntimeError( f'missing {self.serverType.getLabel()} host address') try: port = int(self.txtPostgisPort.text()) except (ValueError, TypeError): raise RuntimeError( f'missing or invalid {self.serverType.getLabel()} port') return self.serverType( name=name, authid=self.postgisAuth.configId(), host=host, port=port, schema=self.txtPostgisSchema.text().strip(), database=self.txtPostgisDatabase.text().strip()) except Exception as e: self.parent.logError( f"Failed to create {self.serverType.getLabel()} instance: {e}") return None def newFromName(self, name: str): """ Sets the name field and keeps all others empty. """ self.txtPostgisName.setText(name) self.txtPostgisDatabase.clear() self.txtPostgisPort.clear() self.txtPostgisServerAddress.clear() self.txtPostgisSchema.clear() self.postgisAuth.setConfigId(None) def loadFromInstance(self, server): """ Populates the form fields with the values from the given server instance. """ self.txtPostgisName.setText(server.serverName) self.txtPostgisDatabase.setText(server.database) self.txtPostgisPort.setText(server.port) self.txtPostgisServerAddress.setText(server.host) self.txtPostgisSchema.setText(server.schema) self.postgisAuth.setConfigId(server.authid) # After the data has loaded, the form is "clean" self.setClean() def addAuthWidget(self): layout = QHBoxLayout() layout.setContentsMargins(0, 3, 0, 0) layout.addWidget(self.postgisAuth) self.postgisAuthWidget.setLayout(layout) self.postgisAuthWidget.setFixedHeight( self.txtPostgisServerAddress.height())
class DistrictSettingsDialog(QDialog): """ A dialog used for plugin settings """ def __init__(self, parent=None): # pylint: disable=too-many-statements super().__init__(parent) self.setWindowTitle(self.tr('Redistrict Plugin | Settings')) layout = QVBoxLayout() self.auth_label = QLabel(self.tr('Authentication configuration')) layout.addWidget(self.auth_label) self.auth_value = QgsAuthConfigSelect() layout.addWidget(self.auth_value) auth_id = get_auth_config_id() if auth_id: self.auth_value.setConfigId(auth_id) layout.addWidget(QLabel(self.tr('API base URL'))) self.base_url_edit = QLineEdit() self.base_url_edit.setText(QgsSettings().value('redistrict/base_url', '', str, QgsSettings.Plugins)) layout.addWidget(self.base_url_edit) h_layout = QHBoxLayout() h_layout.addWidget(QLabel(self.tr('Check for completed requests every'))) self.check_every_spin = QSpinBox() self.check_every_spin.setMinimum(10) self.check_every_spin.setMaximum(600) self.check_every_spin.setSuffix(' ' + self.tr('s')) self.check_every_spin.setValue(QgsSettings().value('redistrict/check_every', '30', int, QgsSettings.Plugins)) h_layout.addWidget(self.check_every_spin) layout.addLayout(h_layout) self.use_mock_checkbox = QCheckBox(self.tr('Use mock Statistics NZ API')) self.use_mock_checkbox.setChecked(get_use_mock_api()) layout.addWidget(self.use_mock_checkbox) self.test_button = QPushButton(self.tr('Test API connection')) self.test_button.clicked.connect(self.test_api) layout.addWidget(self.test_button) self.use_overlays_checkbox = QCheckBox(self.tr('Show updated populations during interactive redistricting')) self.use_overlays_checkbox.setChecked( QgsSettings().value('redistrict/show_overlays', False, bool, QgsSettings.Plugins)) layout.addWidget(self.use_overlays_checkbox) self.use_sound_group_box = QGroupBox(self.tr('Use audio feedback')) self.use_sound_group_box.setCheckable(True) self.use_sound_group_box.setChecked( QgsSettings().value('redistrict/use_audio_feedback', False, bool, QgsSettings.Plugins)) sound_layout = QGridLayout() sound_layout.addWidget(QLabel(self.tr('When meshblock redistricted')), 0, 0) self.on_redistrict_file_widget = QgsFileWidget() self.on_redistrict_file_widget.setDialogTitle(self.tr('Select Audio File')) self.on_redistrict_file_widget.setStorageMode(QgsFileWidget.GetFile) self.on_redistrict_file_widget.setFilePath( QgsSettings().value('redistrict/on_redistrict', '', str, QgsSettings.Plugins)) self.on_redistrict_file_widget.setFilter(self.tr('Wave files (*.wav *.WAV)')) sound_layout.addWidget(self.on_redistrict_file_widget, 0, 1) self.play_on_redistrict_sound_button = QPushButton(self.tr('Test')) self.play_on_redistrict_sound_button.clicked.connect(self.play_on_redistrict_sound) sound_layout.addWidget(self.play_on_redistrict_sound_button, 0, 2) self.use_sound_group_box.setLayout(sound_layout) layout.addWidget(self.use_sound_group_box) button_box = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) layout.addWidget(button_box) button_box.rejected.connect(self.reject) button_box.accepted.connect(self.accept) self.setLayout(layout) def accept(self): # pylint: disable=missing-docstring super().accept() QgsSettings().setValue('redistrict/auth_config_id', self.auth_value.configId(), QgsSettings.Plugins) QgsSettings().setValue('redistrict/use_mock_api', self.use_mock_checkbox.isChecked(), QgsSettings.Plugins) QgsSettings().setValue('redistrict/base_url', self.base_url_edit.text(), QgsSettings.Plugins) QgsSettings().setValue('redistrict/check_every', self.check_every_spin.value(), QgsSettings.Plugins) QgsSettings().setValue('redistrict/show_overlays', self.use_overlays_checkbox.isChecked(), QgsSettings.Plugins) QgsSettings().setValue('redistrict/use_audio_feedback', self.use_sound_group_box.isChecked(), QgsSettings.Plugins) QgsSettings().setValue('redistrict/on_redistrict', self.on_redistrict_file_widget.filePath(), QgsSettings.Plugins) def test_api(self): """ Tests the API connection (real or mock!) """ connector = get_api_connector(use_mock=self.use_mock_checkbox.isChecked(), authcfg=self.auth_value.configId(), base_url=self.base_url_edit.text()) if connector.check(): QMessageBox.information(self, self.tr('Test API Connection'), self.tr('API responded OK!'), QMessageBox.Ok) else: QMessageBox.critical(self, self.tr('Test API Connection'), self.tr('Could not connect to API!'), QMessageBox.Ok) def play_on_redistrict_sound(self): """ Plays the 'on redistrict' sound """ try: playsound(self.on_redistrict_file_widget.filePath(), block=False) except FileNotFoundError: pass
class MapServerWidget(ServerWidgetBase, BASE, WIDGET): def __init__(self, parent, server_type): super().__init__(parent, server_type) self.setupUi(self) self.mapserverAuth = QgsAuthConfigSelect() self.mapserverAuth.selectedConfigIdChanged.connect(self.setDirty) self.addAuthWidget() self.radioLocalPath.toggled.connect(self.showLocalStorageFields) self.fileMapserver.setStorageMode(self.fileMapserver.GetDirectory) self.txtMapserverName.textChanged.connect(self.setDirty) self.txtMapserverUrl.textChanged.connect(self.setDirty) self.txtMapserverHost.textChanged.connect(self.setDirty) self.txtMapserverPort.textChanged.connect(self.setDirty) self.txtMapserverUrl.textChanged.connect(self.setDirty) self.txtMapServicesPath.textChanged.connect(self.setDirty) self.txtProjFolder.textChanged.connect(self.setDirty) def createServerInstance(self): """ Reads the settings form fields and returns a new server instance with these settings. """ try: port = int(self.txtMapserverPort.text()) except (ValueError, TypeError): self.parent.logError('Invalid MapServer port specified') return None local_storage = self.radioLocalPath.isChecked() if local_storage: folder = self.fileMapserver.filePath() else: folder = self.txtRemoteFolder.text() try: name = self.txtMapserverName.text().strip() url = self.txtMapserverUrl.text().strip() if not name: raise RuntimeError( f'missing {self.serverType.getLabel()} name') if not url: raise RuntimeError(f'missing {self.serverType.getLabel()} URL') return self.serverType( name=name, url=url, useLocalFolder=local_storage, folder=folder, authid=self.mapserverAuth.configId(), host=self.txtMapserverHost.text().strip(), port=port, servicesPath=self.txtMapServicesPath.text().strip(), projFolder=self.txtProjFolder.text().strip()) except Exception as e: self.parent.logError( f"Failed to create {self.serverType.getLabel()} instance: {e}") return None def newFromName(self, name: str): """ Sets the name field and keeps all others empty. """ self.txtMapserverName.setText(name) self.txtMapserverHost.clear() self.txtMapserverPort.clear() self.mapserverAuth.setConfigId(None) self.txtMapserverUrl.clear() self.txtMapServicesPath.clear() self.txtProjFolder.clear() self.radioLocalPath.setChecked(True) self.radioFtp.setChecked(False) self.showLocalStorageFields(True) def loadFromInstance(self, server): """ Populates the form fields with the values from the given server instance. """ self.txtMapserverName.setText(server.serverName) self.fileMapserver.setFilePath(server.folder) self.txtRemoteFolder.setText(server.folder) self.txtMapserverHost.setText(server.host) self.txtMapserverPort.setText(str(server.port)) self.mapserverAuth.setConfigId(server.authId) self.txtMapserverUrl.setText(server.baseUrl) self.txtMapServicesPath.setText(server.servicesPath) self.txtProjFolder.setText(server.projFolder) self.radioLocalPath.setChecked(server.useLocalFolder) self.radioFtp.setChecked(not server.useLocalFolder) self.showLocalStorageFields(server.useLocalFolder) # After the data has loaded, the form is "clean" self.setClean() def addAuthWidget(self): layout = QHBoxLayout() layout.setContentsMargins(0, 3, 0, 0) layout.addWidget(self.mapserverAuth) self.mapserverAuthWidget.setLayout(layout) self.mapserverAuthWidget.setFixedHeight(self.txtMapserverUrl.height()) def showLocalStorageFields(self, checked): self.labelLocalFolder.setVisible(checked) self.labelRemoteFolder.setVisible(not checked) self.fileMapserver.setVisible(checked) self.txtRemoteFolder.setVisible(not checked) self.labelHost.setVisible(not checked) self.labelPort.setVisible(not checked) self.labelMapserverCredentials.setVisible(not checked) self.txtMapserverHost.setVisible(not checked) self.txtMapserverPort.setVisible(not checked) self.mapserverAuthWidget.setVisible(not checked) self.setDirty()
class ALKISConf(QDialog, ConfBase): def __init__(self, plugin): QDialog.__init__(self) self.setupUi(self) self.plugin = plugin self.settings = plugin.settings self.settings.loadSettings() self.leSERVICE.setText(self.settings.service) self.leHOST.setText(self.settings.host) self.lePORT.setText(self.settings.port) self.leDBNAME.setText(self.settings.dbname) self.leSCHEMA.setText(self.settings.schema) self.leUID.setText(self.settings.uid) self.lePWD.setText(self.settings.pwd) self.cbxSignaturkatalog.setEnabled(False) if hasattr(qgis.gui, 'QgsAuthConfigSelect'): self.authCfgSelect = QgsAuthConfigSelect(self, "postgres") self.tabWidget.insertTab(1, self.authCfgSelect, "Konfigurationen") authcfg = self.settings.authcfg if authcfg: self.tabWidget.setCurrentIndex(1) self.authCfgSelect.setConfigId(authcfg) self.leUMNPath.setText(self.settings.umnpath) self.pbUMNBrowse.clicked.connect(self.browseUMNPath) self.leUMNTemplate.setText(self.settings.umntemplate) self.teFussnote.setPlainText(self.settings.footnote) self.loadModels(False) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.bb.addButton("Modelle laden", QDialogButtonBox.ActionRole).clicked.connect(self.loadModels) self.bb.addButton("Layer einbinden", QDialogButtonBox.ActionRole).clicked.connect(self.loadLayers) self.restoreGeometry(QSettings("norBIT", "norGIS-ALKIS-Erweiterung").value("confgeom", QByteArray(), type=QByteArray)) def done(self, r): QSettings("norBIT", "norGIS-ALKIS-Erweiterung").setValue("confgeom", self.saveGeometry()) return QDialog.done(self, r) def loadModels(self, error=True): self.settings.servicE = self.leSERVICE.text() self.settings.host = self.leHOST.text() self.settings.port = self.lePORT.text() self.settings.dbname = self.leDBNAME.text() self.settings.schema = self.leSCHEMA.text() self.settings.uid = self.leUID.text() self.settings.pwd = self.lePWD.text() if hasattr(qgis.gui, 'QgsAuthConfigSelect'): self.settings.authcfg = self.authCfgSelect.configId() self.twModellarten.clearContents() self.cbxSignaturkatalog.clear() (db, conninfo) = self.plugin.opendb() if not db: if error: QMessageBox.critical(None, "ALKIS", u"Datenbankverbindung schlug fehl.") self.twModellarten.clearContents() self.twModellarten.setDisabled(True) self.twModellarten.setRowCount(0) self.settings.load() return modelle = self.settings.modellarten if modelle is None: modelle = ['DLKM', 'DKKM1000'] qry = QSqlQuery(db) if qry.exec_("SELECT 1 FROM information_schema.tables WHERE table_schema={} AND table_name='po_modelle'".format(quote(self.plugin.settings.schema))) and qry.next(): sql = "SELECT modell,n FROM po_modelle WHERE modell IS NOT NULL ORDER BY n DESC" else: sql = """ SELECT modell,count(*) FROM ( SELECT unnest(modell) AS modell FROM po_points UNION ALL SELECT unnest(modell) AS modell FROM po_lines UNION ALL SELECT unnest(modell) AS modell FROM po_polygons UNION ALL SELECT unnest(modell) AS modell from po_labels ) AS foo WHERE modell IS NOT NULL GROUP BY modell ORDER BY count(*) DESC """ if qry.exec_(sql): res = {} while qry.next(): res[qry.value(0)] = qry.value(1) self.twModellarten.setRowCount(len(res)) i = 0 for k, n in sorted(iter(list(res.items())), key=operator.itemgetter(1), reverse=True): item = QTableWidgetItem(k) item.setCheckState(Qt.Checked if (item.text() in modelle) else Qt.Unchecked) self.twModellarten.setItem(i, 0, item) item = QTableWidgetItem(str(n)) self.twModellarten.setItem(i, 1, item) i += 1 self.twModellarten.resizeColumnsToContents() self.twModellarten.setEnabled(True) else: self.twModellarten.clearContents() self.twModellarten.setDisabled(True) self.twModellarten.setRowCount(0) if qry.exec_("SELECT id,name FROM alkis_signaturkataloge"): while qry.next(): self.cbxSignaturkatalog.addItem(qry.value(1), int(qry.value(0))) self.cbxSignaturkatalog.setEnabled(True) else: self.cbxSignaturkatalog.addItem(u"Farbe", -1) self.cbxSignaturkatalog.setCurrentIndex(max([0, self.cbxSignaturkatalog.findData(self.settings.signaturkatalog)])) self.settings.load() def saveSettings(self): self.settings.service = self.leSERVICE.text() self.settings.host = self.leHOST.text() self.settings.port = self.lePORT.text() self.settings.dbname = self.leDBNAME.text() self.settings.schema = self.leSCHEMA.text() self.settings.uid = self.leUID.text() self.settings.pwd = self.lePWD.text() if hasattr(qgis.gui, 'QgsAuthConfigSelect'): self.settings.authcfg = self.authCfgSelect.configId() self.settings.umnpath = self.leUMNPath.text() self.settings.umntemplate = self.leUMNTemplate.text() self.settings.footnote = self.teFussnote.toPlainText() modelle = [] if self.twModellarten.isEnabled(): for i in range(self.twModellarten.rowCount()): item = self.twModellarten.item(i, 0) if item.checkState() == Qt.Checked: modelle.append(item.text()) self.settings.modellarten = modelle self.settings.signaturkatalog = self.cbxSignaturkatalog.itemData(self.cbxSignaturkatalog.currentIndex()) self.settings.saveSettings() def loadLayers(self): self.saveSettings() self.plugin.run() self.settings.load() QDialog.accept(self) def accept(self): self.saveSettings() self.settings.load() QDialog.accept(self) def browseUMNPath(self): path = self.leUMNPath.text() path = QFileDialog.getExistingDirectory(self, u"UMN-Pfad wählen", path) if path != "": self.leUMNPath.setText(path)