class ErrorReportDialog(QDialog): def __init__(self, title, message, errors, username, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(title) self.verticalLayout = QVBoxLayout(self) self.label = QLabel(message, self) self.verticalLayout.addWidget(self.label) self.plainTextEdit = QPlainTextEdit(self) self.plainTextEdit.setPlainText(errors) self.plainTextEdit.setReadOnly(True) self.verticalLayout.addWidget(self.plainTextEdit) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.verticalLayout.addWidget(self.buttonBox) self.reportButton = self.buttonBox.addButton(self.tr("Report error"), QDialogButtonBox.ActionRole) self.reportButton.clicked.connect(self.__reportError) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.username = username self.metadata = MetaData() def __reportError(self): body = ("Please provide any additional information here:\n\n\n" "If you encountered an upload error, if possible please attach a zip file containing a minimal extract of the dataset, as well as the QGIS project file.\n\n\n" "Technical information:\n%s\n\n" "Versions:\n" " QGIS: %s\n" " Python: %s\n" " OS: %s\n" " QGIS Cloud Plugin: %s\n\n" "Username: %s\n") % ( self.plainTextEdit.toPlainText(), Qgis.QGIS_VERSION, sys.version.replace("\n", " "), platform.platform(), self.metadata.version(), self.username) url = QUrl() url.toEncoded("mailto:[email protected]?subject=%s&body=%s" % ( urllib.parse.quote(self.windowTitle()), urllib.parse.quote(body)), ) QDesktopServices.openUrl(url)
def __init__(self, title, message, errors, username, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(title) self.verticalLayout = QVBoxLayout(self) self.label = QLabel(message, self) self.verticalLayout.addWidget(self.label) self.plainTextEdit = QPlainTextEdit(self) self.plainTextEdit.setPlainText(errors) self.plainTextEdit.setReadOnly(True) self.verticalLayout.addWidget(self.plainTextEdit) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.verticalLayout.addWidget(self.buttonBox) self.reportButton = self.buttonBox.addButton(self.tr("Report error"), QDialogButtonBox.ActionRole) self.reportButton.clicked.connect(self.__reportError) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.username = username self.metadata = MetaData()
class MultilineTextPanel(QWidget): USE_TEXT = 0 def __init__(self, options, parent=None): super(MultilineTextPanel, self).__init__(parent) self.options = options self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(2) self.verticalLayout.setMargin(0) self.combo = QComboBox() self.combo.addItem(self.tr('[Use text below]')) for option in options: self.combo.addItem(option[0], option[1]) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout.addWidget(self.combo) self.textBox = QPlainTextEdit() self.verticalLayout.addWidget(self.textBox) self.setLayout(self.verticalLayout) def setText(self, text): self.textBox.setPlainText(text) def getOption(self): return self.combo.currentIndex() def getValue(self): if self.combo.currentIndex() == 0: return str(self.textBox.toPlainText()) else: return self.combo.currentData() def setValue(self, value): items = [self.combo.itemData(i) for i in range(1, self.combo.count())] for idx, item in enumerate(items): if item == value: self.combo.setCurrentIndex(idx) return self.combo.setCurrentIndex(0) if value: self.textBox.setPlainText(value)
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): w = wrapper.widget if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): try: parameters = self.parent.getParamValues() for output in self.alg.destinationParameterDefinitions(): if parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") commands = self.alg.getConsoleCommands(parameters) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description())) except: self.text.setPlainText("")
def __init__(self, options, parent=None): super(MultilineTextPanel, self).__init__(parent) self.options = options self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(2) self.verticalLayout.setMargin(0) self.combo = QComboBox() self.combo.addItem(self.tr("[Use text below]")) for option in options: self.combo.addItem(option[0], option[1]) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout.addWidget(self.combo) self.textBox = QPlainTextEdit() self.verticalLayout.addWidget(self.textBox) self.setLayout(self.verticalLayout)
def initGui(self): self.setWindowTitle('Import to GeoGig') verticalLayout = QVBoxLayout() if self.repo is None: repos = repository.repos layerLabel = QLabel('Repository') verticalLayout.addWidget(layerLabel) self.repoCombo = QComboBox() self.repoCombo.addItems(["%s - %s" % (r.group, r.title) for r in repos]) self.repoCombo.currentIndexChanged.connect(self.updateBranches) verticalLayout.addWidget(self.repoCombo) if self.layer is None: layerLabel = QLabel('Layer') verticalLayout.addWidget(layerLabel) self.layerCombo = QComboBox() layerNames = [layer.name() for layer in vectorLayers() if layer.source().lower().split("|")[0].split(".")[-1] in["gpkg", "geopkg"] and not isRepoLayer(layer)] self.layerCombo.addItems(layerNames) verticalLayout.addWidget(self.layerCombo) self.branchLabel = QLabel("Branch") verticalLayout.addWidget(self.branchLabel) self.branchCombo = QComboBox() self.branches = self.repo.branches() if self.repo is not None else repos[0].branches() self.branchCombo.addItems(self.branches) verticalLayout.addWidget(self.branchCombo) messageLabel = QLabel('Message to describe this update') verticalLayout.addWidget(messageLabel) self.messageBox = QPlainTextEdit() verticalLayout.addWidget(self.messageBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Cancel) self.importButton = QPushButton("Add layer") self.importButton.clicked.connect(self.importClicked) self.buttonBox.addButton(self.importButton, QDialogButtonBox.ApplyRole) self.buttonBox.rejected.connect(self.cancelPressed) verticalLayout.addWidget(self.buttonBox) self.setLayout(verticalLayout) self.resize(600, 300) self.messageBox.setFocus()
def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged()
def initGui(self): self.setObjectName("CommitDialog") self.resize(600, 250) self.setWindowTitle("Syncronize layer to repository branch") self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(2) self.verticalLayout.setMargin(5) self.branchLabel = QLabel("Branch") self.verticalLayout.addWidget(self.branchLabel) self.branchCombo = QComboBox() self.branches = [] branches = self.repo.branches() for branch in branches: trees = self.repo.trees(branch) if self.layername in trees: self.branches.append(branch) self.branchCombo.addItems(self.branches) try: idx = self.branches.index("master") except: idx = 0 self.branchCombo.setCurrentIndex(idx) self.verticalLayout.addWidget(self.branchCombo) self.msgLabel = QLabel("Message to describe this update") self.verticalLayout.addWidget(self.msgLabel) self.text = QPlainTextEdit() self.text.setPlainText(self._message) self.verticalLayout.addWidget(self.text) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok) self.verticalLayout.addWidget(self.buttonBox) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(self.branches)) self.setLayout(self.verticalLayout) self.buttonBox.accepted.connect(self.okPressed) self.text.setFocus()
def createWidget(self): if self.dialogType == DIALOG_STANDARD: if self.param.multiline: widget = QPlainTextEdit() if self.param.default: widget.setPlainText(self.param.default) else: widget = StringInputPanel(self.param) if self.param.default: widget.setValue(self.param.default) elif self.dialogType == DIALOG_BATCH: widget = QLineEdit() if self.param.default: widget.setText(self.param.default) else: strings = self.dialog.getAvailableValuesOfType(ParameterString, OutputString) options = [(self.dialog.resolveValueDescription(s), s) for s in strings] if self.param.multiline: widget = MultilineTextPanel(options) widget.setText(self.param.default or "") else: widget = QComboBox() widget.setEditable(True) for desc, val in options: widget.addItem(desc, val) widget.setEditText(self.param.default or "") return widget
def getWidgetFromParameter(self, param): # TODO Create Parameter widget class that holds the logic # for creating a widget that belongs to the parameter. if isinstance(param, ParameterRaster): layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) elif isinstance(param, ParameterVector): if self.somethingDependsOnThisParameter(param) or self.alg.allowOnlyOpenedLayers: item = QComboBox() layers = dataobjects.getVectorLayers(param.shapetype) layers.sort(key=lambda lay: lay.name()) if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(self.getExtendedLayerName(layer), layer) item.currentIndexChanged.connect(self.updateDependentFields) item.name = param.name else: layers = dataobjects.getVectorLayers(param.shapetype) items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) # if already set, put first in list for i, (name, layer) in enumerate(items): if layer and layer.source() == param.value: items.insert(0, items.pop(i)) item = InputLayerSelectorPanel(items, param) elif isinstance(param, ParameterTable): if self.somethingDependsOnThisParameter(param): item = QComboBox() layers = dataobjects.getTables() if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(layer.name(), layer) item.currentIndexChanged.connect(self.updateDependentFields) item.name = param.name else: layers = dataobjects.getTables() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((layer.name(), layer)) # if already set, put first in list for i, (name, layer) in enumerate(items): if layer and layer.source() == param.value: items.insert(0, items.pop(i)) item = InputLayerSelectorPanel(items, param) elif isinstance(param, ParameterBoolean): item = QCheckBox() if param.default: item.setChecked(True) else: item.setChecked(False) elif isinstance(param, ParameterTableField) or isinstance(param, ParameterTableMultipleField): if isinstance(param, ParameterTableMultipleField): item = ListMultiSelectWidget() else: item = QComboBox() if param.parent in self.dependentItems: items = self.dependentItems[param.parent] else: items = [] self.dependentItems[param.parent] = items items.append(param) parent = self.alg.getParameterFromName(param.parent) if isinstance(parent, ParameterVector): layers = dataobjects.getVectorLayers(parent.shapetype) else: layers = dataobjects.getTables() if len(layers) > 0: if param.optional and isinstance(param, ParameterTableField): item.addItem(self.tr('[not set]')) item.addItems(self.getFields(layers[0], param.datatype)) elif isinstance(param, ParameterSelection): item = QComboBox() item.addItems(param.options) if param.default: item.setCurrentIndex(param.default) elif isinstance(param, ParameterFixedTable): item = FixedTablePanel(param) elif isinstance(param, ParameterRange): item = RangePanel(param) elif isinstance(param, ParameterFile): item = FileSelectionPanel(param.isFolder, param.ext) elif isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_FILE: item = MultipleInputPanel(datatype=ParameterMultipleInput.TYPE_FILE) else: if param.datatype == ParameterMultipleInput.TYPE_RASTER: options = dataobjects.getRasterLayers(sorting=False) elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: options = dataobjects.getVectorLayers(sorting=False) else: options = dataobjects.getVectorLayers([param.datatype], sorting=False) opts = [self.getExtendedLayerName(opt) for opt in options] item = MultipleInputPanel(opts) elif isinstance(param, ParameterNumber): item = NumberInputPanel(param.default, param.min, param.max, param.isInteger) elif isinstance(param, ParameterExtent): item = ExtentSelectionPanel(self.parent, self.alg, param.default) elif isinstance(param, ParameterPoint): item = PointSelectionPanel(self.parent, param.default) elif isinstance(param, ParameterCrs): item = CrsSelectionPanel(param.default) elif isinstance(param, ParameterString): if param.multiline: verticalLayout = QVBoxLayout() verticalLayout.setSizeConstraint( QLayout.SetDefaultConstraint) textEdit = QPlainTextEdit() if param.default: textEdit.setPlainText(param.default) verticalLayout.addWidget(textEdit) item = textEdit else: item = QLineEdit() if param.default: item.setText(unicode(param.default)) elif isinstance(param, ParameterGeometryPredicate): item = GeometryPredicateSelectionPanel(param.enabledPredicates) if param.left: widget = self.valueItems[param.left] if isinstance(widget, InputLayerSelectorPanel): widget = widget.cmbText widget.currentIndexChanged.connect(item.onLeftLayerChange) item.leftLayer = widget.itemData(widget.currentIndex()) if param.right: widget = self.valueItems[param.right] if isinstance(widget, InputLayerSelectorPanel): widget = widget.cmbText widget.currentIndexChanged.connect(item.onRightLayerChange) item.rightLayer = widget.itemData(widget.currentIndex()) item.updatePredicates() if param.default: item.setValue(param.default) else: item = QLineEdit() if param.default: item.setText(unicode(param.default)) return item
class ChloeParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, ValuesSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, CustomInputLayerSelectorPanel): w.currentIndexChanged.connect(self.parametersHaveChanged) w.currentIndexChanged.connect(self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, ValuesSelectionPanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ # if isinstance(param, ParameterString) and param.name in ["VALUES_RANGES"]: # # === Overload ParameterString for special parameter name like VALUES_RANGES,.. # if param.name == "VALUES_RANGES": # item = ValuesSelectionPanel(self.parent, self.alg, param.default) # if param.default: # item.setText(unicode(param.default)) # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
class OverlayParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText( self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect( self.parametersHaveChanged) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) #@pyqtSlot(str) def parametersHaveChanged(self): try: self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) #raise e def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["INPUTS_MATRIX"]: options = dataobjects.getRasterLayers(sorting=False) opts = [self.getExtendedLayerName(opt) for opt in options] item = OrderedMultipleInputPanel(opts) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self, param) return item
class SearchAndReplaceParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() self.changeInputDependent() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) w.cmbText.currentIndexChanged.connect(self.changeInputDependent) elif isinstance(w, TableReplaceInputDialog): w.leText.textChanged.connect(self.parametersHaveChanged) w = self.widgets['MAP_CSV'] w.leText.textChanged.connect(self.updateDependantMapCSV) w = self.widgets['CHANGES'] w.pbApply.clicked.connect(self.applyCSVMap) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) #@pyqtSlot(str) def changeInputDependent(self): w = self.widgets['INPUT_LAYER_ASC'] try: val = w.getValue() if isinstance(val, QgsRasterLayer): rasterLayerParam = val.source().encode('utf-8') else: rasterLayerParam = val.encode('utf-8') except: pass # == Clean table w = self.widgets['CHANGES'] wt = w.twAssociation for row in xrange(0,wt.rowCount()): r0 = wt.item(row,0) r1 = wt.item(row,1) if isinstance(r0, QTableWidgetItem): r0.setText("") else: wt.setItem(row,0,QTableWidgetItem("")) if isinstance(r1, QTableWidgetItem): r1.setText("") else: wt.setItem(row,1,QTableWidgetItem("")) try: if rasterLayerParam: f_input = rasterLayerParam # === Parse asc value ds = gdal.Open(f_input) # DataSet band = ds.GetRasterBand(1) # -> band array = np.array(band.ReadAsArray()) # -> matrice values values = np.unique(array) values_and_nodata = np.insert(values, 0, band.GetNoDataValue()) # Add nodata values in numpy array int_values_and_nodata = [int(math.floor(x)) for x in values_and_nodata ] # == Write value in table wt = w.twAssociation int_values_and_nodata for val, row in zip(int_values_and_nodata,xrange(0,wt.rowCount())): r0 = wt.item(row,0) if isinstance(r0, QTableWidgetItem): r0.setText(str(val)) else: wt.setItem(row,0,QTableWidgetItem(str(val))) except: pass #@pyqtSlot(str) def updateDependantMapCSV(self): w = self.widgets['MAP_CSV'] f_map_csv = w.leText.text().encode('utf-8') w_change = self.widgets['CHANGES'] cmbBox = w_change.cmbBox cmbBox.clear() try: # == Get list index if f_map_csv: if os.path.exists(f_map_csv): with open(f_map_csv, 'r') as f: line = f.next() headers = filter(None, re.split('\n|;| |,', line)) cmbBox.addItems(headers[1:]) except: pass #@pyqtSlot(str) def applyCSVMap(self): w = self.widgets['MAP_CSV'] f_map_csv = w.leText.text().encode('utf-8') w_change = self.widgets['CHANGES'] # Index if f_map_csv: if os.path.exists(f_map_csv): with open(f_map_csv, 'r') as f: line = f.next() headers = filter(None, re.split('\n|;| |,', line)) name_col = w_change.cmbBox.currentText() idex_col = headers[1:].index(name_col) +1 t_ass =[] # Table d'association if f_map_csv: if os.path.exists(f_map_csv): with open(f_map_csv, 'r') as f: b_header = 1 for line in f: if b_header == 1: b_header = 0 continue # Jump the header data = filter(None, re.split('\n|;| |,', line)) t_ass.append([data[0],data[idex_col]]) # Table two dimention if t_ass: # Update with associtation table wt = w_change.twAssociation for t_as in t_ass: val_old = t_as[0] val_new = t_as[1] for row in xrange(0,wt.rowCount()): r0 = wt.item(row,0) if r0: if r0.text() == str(val_old): # Update value r1 = wt.item(row,1) if isinstance(r1, QTableWidgetItem): r1.setText(str(val_new)) else: wt.setItem(row,1,QTableWidgetItem(str(val_new))) #@pyqtSlot(str) def parametersHaveChanged(self): try: self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["CHANGES"]: item = TableReplaceInputDialog(self,param) elif param.name in ["MAP_CSV"]: item = FileSelectionCSVTXTPanel(param.isFolder, param.ext) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
class ImportDialog(QDialog): def __init__(self, parent, repo = None, layer = None): super(ImportDialog, self).__init__(parent) self.setObjectName("ImportDialog") self.repo = repo self.layer = layer self.ok = False self.initGui() def initGui(self): self.setWindowTitle('Import to GeoGig') verticalLayout = QVBoxLayout() if self.repo is None: repos = repository.repos layerLabel = QLabel('Repository') verticalLayout.addWidget(layerLabel) self.repoCombo = QComboBox() self.repoCombo.addItems(["%s - %s" % (r.group, r.title) for r in repos]) self.repoCombo.currentIndexChanged.connect(self.updateBranches) verticalLayout.addWidget(self.repoCombo) if self.layer is None: layerLabel = QLabel('Layer') verticalLayout.addWidget(layerLabel) self.layerCombo = QComboBox() layerNames = [layer.name() for layer in vectorLayers() if layer.source().lower().split("|")[0].split(".")[-1] in["gpkg", "geopkg"] and not isRepoLayer(layer)] self.layerCombo.addItems(layerNames) verticalLayout.addWidget(self.layerCombo) self.branchLabel = QLabel("Branch") verticalLayout.addWidget(self.branchLabel) self.branchCombo = QComboBox() self.branches = self.repo.branches() if self.repo is not None else repos[0].branches() self.branchCombo.addItems(self.branches) verticalLayout.addWidget(self.branchCombo) messageLabel = QLabel('Message to describe this update') verticalLayout.addWidget(messageLabel) self.messageBox = QPlainTextEdit() verticalLayout.addWidget(self.messageBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Cancel) self.importButton = QPushButton("Add layer") self.importButton.clicked.connect(self.importClicked) self.buttonBox.addButton(self.importButton, QDialogButtonBox.ApplyRole) self.buttonBox.rejected.connect(self.cancelPressed) verticalLayout.addWidget(self.buttonBox) self.setLayout(verticalLayout) self.resize(600, 300) self.messageBox.setFocus() def updateBranches(self): self.branchCombo.clear() repo = repository.repos[self.repoCombo.currentIndex()] self.branches = repo.branches() self.branchCombo.addItems(self.branches) def importClicked(self): ret = QMessageBox.warning(config.iface.mainWindow(), 'Import warning', "Importing a layer will modify the original layer and might cause data loss.\n" "Make sure you have a backup copy of your layer before importing.\n" "Do you want to import the selected layer?", QMessageBox.Yes | QMessageBox.No) if ret == QMessageBox.No: return if self.repo is None: self.repo = repository.repos[self.repoCombo.currentIndex()] if self.layer is None: text = self.layerCombo.currentText() self.layer = layerFromName(text) user, email = config.getUserInfo() if user is None: self.close() return message = self.messageBox.toPlainText() or datetime.now().strftime("%Y-%m-%d %H_%M_%S") branch = self.branchCombo.currentText() try: self.repo.importgeopkg(self.layer, branch, message, user, email, False) filename, layername = namesFromLayer(self.layer) self.repo.checkoutlayer(filename, layername, ref = branch) self.layer.reload() self.layer.triggerRepaint() except GeoGigException as e: iface.messageBar().pushMessage("Error", str(e), level=QgsMessageBar.CRITICAL, duration=5) self.close() return addTrackedLayer(self.layer, self.repo.url) self.ok = True iface.messageBar().pushMessage("Layer was correctly added to repository", level=QgsMessageBar.INFO, duration=5) self.close() def cancelPressed(self): self.close()
class CommitDialog(QDialog): def __init__(self, repo, layername, _message = "", parent = None): super(CommitDialog, self).__init__(parent) self.repo = repo self.branch = None self.layername = layername self._message = _message or suggestedMessage self.message = None self.initGui() def initGui(self): self.setObjectName("CommitDialog") self.resize(600, 250) self.setWindowTitle("Syncronize layer to repository branch") self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(2) self.verticalLayout.setMargin(5) self.branchLabel = QLabel("Branch") self.verticalLayout.addWidget(self.branchLabel) self.branchCombo = QComboBox() self.branches = [] branches = self.repo.branches() for branch in branches: trees = self.repo.trees(branch) if self.layername in trees: self.branches.append(branch) self.branchCombo.addItems(self.branches) try: idx = self.branches.index("master") except: idx = 0 self.branchCombo.setCurrentIndex(idx) self.verticalLayout.addWidget(self.branchCombo) self.msgLabel = QLabel("Message to describe this update") self.verticalLayout.addWidget(self.msgLabel) self.text = QPlainTextEdit() self.text.setPlainText(self._message) self.verticalLayout.addWidget(self.text) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok) self.verticalLayout.addWidget(self.buttonBox) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(self.branches)) self.setLayout(self.verticalLayout) self.buttonBox.accepted.connect(self.okPressed) self.text.setFocus() def okPressed(self): self.branch = self.branchCombo.currentText() self.message = self.text.toPlainText() or datetime.now().strftime("%Y-%m-%d %H_%M_%S") self.close()
class DistanceParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, ValuesSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, CustomInputLayerSelectorPanel): w.currentIndexChanged.connect(self.parametersHaveChanged) w.currentIndexChanged.connect(self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, ValuesSelectionPanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["VALUES_RANGES"]: # === Overload ParameterString for special parameter name like VALUES_RANGES,.. item = ValuesSelectionPanel(self.parent, self.alg, param.default) if param.default: item.setText(unicode(param.default)) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = CustomInputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
def keyPressEvent(self, event): print("Key: "+str(event.key())) print("Modifier: "+str(event.modifiers())) layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = 0 tc = self.textCursor() #msgBox=QMessageBox() #msgBox.setText(str(selection)) #msgBox.exec() if len(layers)>0 and event.key()==Qt.Key_Space and event.modifiers()==Qt.ControlModifier: self.createVarInputDialog() event.accept() return elif len(layers)==0 and event.key()==Qt.Key_Space and event.modifiers()==Qt.ControlModifier: msgBox=QMessageBox() msgBox.setText("No layer has been loaded in QGIS. Therefore no query variables may be created from a given QGIS layer.") msgBox.exec() event.accept() return elif (event.key()==Qt.Key_Enter or event.key()==Qt.Key_Return) and not self.completer.popup().isVisible() and event.modifiers()==Qt.ControlModifier: self.buildSearchDialog(-1,-1,-1,self,True,True) event.accept() return elif (event.key()==Qt.Key_Enter or event.key()==Qt.Key_Return) and self.completer.popup().isVisible(): self.completer.insertText.emit(self.completer.getSelected()) self.completer.setCompletionMode(QCompleter.PopupCompletion) event.accept(); return QPlainTextEdit.keyPressEvent(self, event) seltext=self.textUnderCursor(tc) tc.select(QTextCursor.LineUnderCursor) selline=tc.selectedText().strip() sellinearr=selline.split(" ") if len(sellinearr)==2 and (sellinearr[0].startswith("?")): print("subject is variable") self.updateCompleterData(list(self.autocomplete["propdict"].keys())) self.changedCompleterSetting=True #msgBox=QMessageBox() #msgBox.setText(str(list(self.autocomplete["completerClassList"].keys()))) #msgBox.exec() elif len(sellinearr)==3 and (sellinearr[0].startswith("?")): print("subject and predicate") self.updateCompleterData(list(self.autocomplete["clsdict"].keys())+list(self.autocomplete["completerClassList"].keys())) self.changedCompleterSetting=True #msgBox=QMessageBox() #msgBox.setText(str(list(self.autocomplete["completerClassList"].keys()))) #msgBox.exec() elif self.changedCompleterSetting: self.updateCompleterData(list(self.autocomplete["clsdict"].keys())+list(self.autocomplete["propdict"].keys())+list(self.autocomplete["completerClassList"].keys())) self.changedCompleterSetting=False #msgBox=QMessageBox() #msgBox.setText(str(list(self.autocomplete["completerClassList"].keys()))+" - "+str(self.changedCompleterSetting)) #msgBox.exec() for m in re.finditer(r'\S+', selline): num, part = m.start(), m.group() if (part=="." and num<len(selline)-1) or (part==";" and num<len(selline)-1) or (part=="{" and num<len(selline)-1 and num!=1) or (part=="}" and num<len(selline)-1 and num!=1): tc.setPosition(tc.selectionEnd()-1) tc.insertText(os.linesep) cr = self.cursorRect() if len(seltext) > 0: self.completer.setCompletionPrefix(seltext) popup = self.completer.popup() popup.setCurrentIndex(self.completer.completionModel().index(0,0)) cr.setWidth(self.completer.popup().sizeHintForColumn(0) + self.completer.popup().verticalScrollBar().sizeHint().width()) self.completer.complete(cr) else: self.completer.popup().hide() event.accept()
def focusInEvent(self, event): if self.completer: self.completer.setWidget(self) QPlainTextEdit.focusInEvent(self, event)
def createWidget(self): if self.dialogType == DIALOG_STANDARD: if self.param.multiline: widget = QPlainTextEdit() if self.param.default: widget.setPlainText(self.param.default) else: widget = StringInputPanel(self.param) if self.param.default: widget.setValue(self.param.default) elif self.dialogType == DIALOG_BATCH: widget = QLineEdit() if self.param.default: widget.setText(self.param.default) else: # strings, numbers, files and table fields are all allowed input types strings = self.dialog.getAvailableValuesOfType([ ParameterString, ParameterNumber, ParameterFile, ParameterTableField, ParameterExpression ], OutputString) options = [(self.dialog.resolveValueDescription(s), s) for s in strings] if self.param.multiline: widget = MultilineTextPanel(options) widget.setText(self.param.default or "") else: widget = QComboBox() widget.setEditable(True) for desc, val in options: widget.addItem(desc, val) widget.setEditText(self.param.default or "") return widget
class SlidingParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system self.types_of_metrics = {} for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() self.changeWindowShapeDependent() # === param:METRICS Widget:ListSelectionPanel === # === Init cbFilter cbFilter = self.widgets["METRICS"].cbFilter cbFilter.addItems(self.alg.types_of_metrics.keys()) # === Init listSrc filter_txt = cbFilter.currentText() w_value = self.widgets["METRICS"].cbValue w_value.clear() if self.types_of_metrics: if filter_txt in self.types_of_metrics.keys(): w_value.addItems(self.types_of_metrics[filter_txt]) def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.initCalculateMetric) w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) w.cmbText.currentIndexChanged.connect(self.updateMetric) elif isinstance(w, DoubleCmbBoxSelectionPanel): w.cbFilter.currentIndexChanged.connect(self.updateMetric) w.cbValue.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, ValuesSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) w = self.widgets["WINDOW_SHAPE"] w.currentIndexChanged.connect(self.changeWindowShapeDependent) w = self.widgets["WINDOW_SIZES"] w.spnValue.setSingleStep(2) # step incrementation and decrementation # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) w = self.widgets["METRICS"].cbFilter w.currentIndexChanged.emit(0) self.widgets["INPUT_LAYER_ASC"].cmbText.currentIndexChanged.emit(0) #@pyqtSlot(str) def initCalculateMetric(self): w = self.widgets['INPUT_LAYER_ASC'] try: val = w.getValue() if isinstance(val, QgsRasterLayer): rasterLayerParam = val.source().encode('utf-8') else: rasterLayerParam = val.encode('utf-8') int_values_and_nodata = ChloeUtils.extractValueNotNull(rasterLayerParam) self.types_of_metrics = ChloeUtils.calculateMetric( self.alg.types_of_metrics, self.alg.types_of_metrics_simple, self.alg.types_of_metrics_cross, int_values_and_nodata ) except: self.types_of_metrics = [] # === param:WINDOW_SHAPE Widget:ComboBox #@pyqtSlot(str) def changeWindowShapeDependent(self): txt = self.widgets["WINDOW_SHAPE"].currentText() if txt == "FUNCTIONAL": self.widgets["FRICTION_FILE"].setEnabled(True) else: self.widgets["FRICTION_FILE"].setDisabled(True) # === param:OUTPUTS_ASC_BOOL Widget:CheckBox === #@pyqtSlot(str) def changesOuputASCBoolDependent(self): w = self.widgets["OUTPUTS_ASC_BOOL"] w_asc = self.widgets["VISUALISE_ASC_BOOL"] if w.isChecked(): w_asc.setEnabled(True) else: w_asc.setDisabled(True) #@pyqtSlot(str) def updateMetric(self): filter_txt = self.widgets["METRICS"].cbFilter.currentText() w_value = self.widgets["METRICS"].cbValue w_value.clear() if self.types_of_metrics: if filter_txt in self.types_of_metrics.keys(): w_value.addItems(self.types_of_metrics[filter_txt]) #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) #raise e def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["METRICS"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = DoubleCmbBoxSelectionPanel(self.parent, self.alg, param.default) elif param.name in ["FILTER", "UNFILTER"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = ValuesSelectionPanel(self.parent, self.alg, param.default,'INPUT_LAYER_ASC') if param.default: item.setText(unicode(param.default)) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
class FromShapefileParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText( self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, CSVFieldSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, CustomFileSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) w.leText.textChanged.connect(self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, CSVFieldSelectionPanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message)
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): w = wrapper.widget self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParamValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[ output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()], context)): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '{0}'").format( e.parameter.description()))
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): wrapper.widgetValueHasChanged.connect(self.parametersHaveChanged) # TODO - remove when all wrappers correctly emit widgetValueHasChanged! # 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): w = wrapper.widget else: w = wrapper.wrappedWidget() self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) for output_widget in self.outputWidgets.values(): self.connectWidgetChangedSignals(output_widget) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, DestinationSelectionPanel): w.destinationChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()])): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description()))
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): w = wrapper.widget self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()], context)): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description()))
def resizeEvent(self, e): QPlainTextEdit.resizeEvent(self, e) cr = self.contentsRect() self.lineNumberArea.setGeometry(QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height()))
def getWidgetFromParameter(self, param): # TODO Create Parameter widget class that holds the logic # for creating a widget that belongs to the parameter. if isinstance(param, ParameterRaster): layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) elif isinstance(param, ParameterVector): if self.somethingDependsOnThisParameter(param) or self.alg.allowOnlyOpenedLayers: item = QComboBox() layers = dataobjects.getVectorLayers(param.datatype) layers.sort(key=lambda lay: lay.name()) if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(self.getExtendedLayerName(layer), layer) item.currentIndexChanged.connect(self.updateDependentFields) item.name = param.name else: layers = dataobjects.getVectorLayers(param.datatype) items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) # if already set, put first in list for i, (name, layer) in enumerate(items): if layer and layer.source() == param.value: items.insert(0, items.pop(i)) item = InputLayerSelectorPanel(items, param) elif isinstance(param, ParameterTable): if self.somethingDependsOnThisParameter(param): item = QComboBox() layers = dataobjects.getTables() if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(layer.name(), layer) item.currentIndexChanged.connect(self.updateDependentFields) item.name = param.name else: layers = dataobjects.getTables() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((layer.name(), layer)) # if already set, put first in list for i, (name, layer) in enumerate(items): if layer and layer.source() == param.value: items.insert(0, items.pop(i)) item = InputLayerSelectorPanel(items, param) elif isinstance(param, ParameterBoolean): item = QCheckBox() if param.default: item.setChecked(True) else: item.setChecked(False) elif isinstance(param, ParameterTableField) or isinstance(param, ParameterTableMultipleField): if isinstance(param, ParameterTableMultipleField): item = ListMultiSelectWidget() else: item = QComboBox() if param.parent in self.dependentItems: items = self.dependentItems[param.parent] else: items = [] self.dependentItems[param.parent] = items items.append(param) parent = self.alg.getParameterFromName(param.parent) if isinstance(parent, ParameterVector): layers = dataobjects.getVectorLayers(parent.datatype) else: layers = dataobjects.getTables() if len(layers) > 0: if param.optional and isinstance(param, ParameterTableField): item.addItem(self.tr('[not set]')) item.addItems(self.getFields(layers[0], param.datatype)) elif isinstance(param, ParameterSelection): item = QComboBox() item.addItems(param.options) if param.default: item.setCurrentIndex(param.default) elif isinstance(param, ParameterFixedTable): item = FixedTablePanel(param) elif isinstance(param, ParameterRange): item = RangePanel(param) elif isinstance(param, ParameterFile): item = FileSelectionPanel(param.isFolder, param.ext) elif isinstance(param, ParameterMultipleInput): if param.datatype == dataobjects.TYPE_FILE: item = MultipleInputPanel(datatype=dataobjects.TYPE_FILE) else: if param.datatype == dataobjects.TYPE_RASTER: options = dataobjects.getRasterLayers(sorting=False) elif param.datatype == dataobjects.TYPE_VECTOR_ANY: options = dataobjects.getVectorLayers(sorting=False) else: options = dataobjects.getVectorLayers([param.datatype], sorting=False) opts = [self.getExtendedLayerName(opt) for opt in options] item = MultipleInputPanel(opts) elif isinstance(param, ParameterNumber): item = NumberInputPanel(param.default, param.min, param.max, param.isInteger) elif isinstance(param, ParameterExtent): item = ExtentSelectionPanel(self.parent, self.alg, param.default) elif isinstance(param, ParameterPoint): item = PointSelectionPanel(self.parent, param.default) elif isinstance(param, ParameterCrs): item = CrsSelectionPanel(param.default) elif isinstance(param, ParameterString): if param.multiline: verticalLayout = QVBoxLayout() verticalLayout.setSizeConstraint( QLayout.SetDefaultConstraint) textEdit = QPlainTextEdit() if param.default: textEdit.setPlainText(param.default) verticalLayout.addWidget(textEdit) item = textEdit else: item = QLineEdit() if param.default: item.setText(unicode(param.default)) elif isinstance(param, ParameterGeometryPredicate): item = GeometryPredicateSelectionPanel(param.enabledPredicates) if param.left: widget = self.valueItems[param.left] if isinstance(widget, InputLayerSelectorPanel): widget = widget.cmbText widget.currentIndexChanged.connect(item.onLeftLayerChange) item.leftLayer = widget.itemData(widget.currentIndex()) if param.right: widget = self.valueItems[param.right] if isinstance(widget, InputLayerSelectorPanel): widget = widget.cmbText widget.currentIndexChanged.connect(item.onRightLayerChange) item.rightLayer = widget.itemData(widget.currentIndex()) item.updatePredicates() if param.default: item.setValue(param.default) else: item = QLineEdit() if param.default: item.setText(unicode(param.default)) return item
class CommitDialog(QDialog): def __init__(self, repo, layername, _message="", parent=None): super(CommitDialog, self).__init__(parent) self.repo = repo self.branch = None self.layername = layername self._message = _message or suggestedMessage self.message = None self.initGui() def initGui(self): self.resize(600, 250) self.setWindowTitle('GeoGig') self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(2) self.verticalLayout.setMargin(5) self.branchLabel = QLabel("Branch") self.verticalLayout.addWidget(self.branchLabel) self.branchCombo = QComboBox() self.branches = [] branches = self.repo.branches() for branch in branches: trees = self.repo.trees(branch) if self.layername in trees: self.branches.append(branch) self.branchCombo.addItems(self.branches) try: idx = self.branches.index("master") except: idx = 0 self.branchCombo.setCurrentIndex(idx) self.verticalLayout.addWidget(self.branchCombo) self.msgLabel = QLabel("Message to describe this update") self.verticalLayout.addWidget(self.msgLabel) self.text = QPlainTextEdit() self.text.setPlainText(self._message) self.text.textChanged.connect(self.textHasChanged) self.verticalLayout.addWidget(self.text) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok) self.verticalLayout.addWidget(self.buttonBox) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(self._message) and bool(self.branches)) self.setLayout(self.verticalLayout) self.buttonBox.accepted.connect(self.okPressed) self.text.setFocus() def textHasChanged(self): self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( self.text.toPlainText() != "" and bool(self.branches)) def okPressed(self): self.branch = self.branchCombo.currentText() self.message = self.text.toPlainText() self.close()
class FromCSVParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) # Add bouton pb = QPushButton(self.tr("Import header")) self.layoutMain.insertWidget(4,pb) self.pbHeader = pb self.pbHeader.clicked.connect(self.uploadHeader) self.connectParameterSignals() self.parametersHaveChanged() def uploadHeader(self): dlg = QFileDialog() dlg.setFileMode(QFileDialog.AnyFile) dlg.setFilter("ASC File (*.asc);; TXT File (*.txt);;All File (*.*)") filenames = QStringList() if dlg.exec_(): filenames = dlg.selectedFiles() self.getWidgetFromParameter # Parse header acs file name with open(str(filenames[0]), 'r') as infile: for line in infile: values = line.strip().split(' ') if values[0] == "ncols": self.widgets["N_COLS"].spnValue.setValue(int(values[1])) elif values[0] == "nrows": self.widgets["N_ROWS"].spnValue.setValue(float(values[1])) elif values[0] == "xllcorner": self.widgets["XLL_CORNER"].spnValue.setValue(float(values[1])) elif values[0] == "yllcorner": self.widgets["YLL_CORNER"].spnValue.setValue(float(values[1])) elif values[0] == "cellsize": self.widgets["CELL_SIZE"].spnValue.setValue(float(values[1])) elif values[0] == "NODATA_value": self.widgets["NODATA_VALUE"].spnValue.setValue(int(values[1])) else: break def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, CSVFieldSelectionPanel): w.leText.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.cleanFieldDependent) # Clean w.cmbText.currentIndexChanged.connect(self.parametersHaveChanged) # elif isinstance(w, CustomFileSelectionPanel): # w.leText.textChanged.connect(self.parametersHaveChanged) # w.leText.textChanged.connect(self.cleanFieldDependent) # Clean # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect(self.parametersHaveChanged) #@pyqtSlot(str) def cleanFieldDependent(self): """ cleanFieldDependent When receiving signal, clean 'leText' of QWidget selectionned """ for w in self.widgets.values(): if isinstance(w, CSVFieldSelectionPanel): w.leText.setText("") #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["FIELDS"]: # === Overload ParameterString for special parameter name like FIELDS,.. item = CSVFieldSelectionPanel(self.parent, self.alg, param.default) if param.default: item.setText(unicode(param.default)) elif param.name in ["INPUT_FILE_CSV"]: layers = dataobjects.getTables() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) for layer in layers: items.append((layer.name(), layer)) # if already set, put first in list for i, (name, layer) in enumerate(items): if layer and layer.source() == param.value: items.insert(0, items.pop(i)) item = InputLayerSelectorPanel(items, param) # # === Overload ParameterString for special parameter name like FIELDS,.. # item = CSVFieldSelectionPanel(self.parent, self.alg, param.default) # if param.default: # item.setText(unicode(param.default)) # elif isinstance(param, ParameterFile): # # === Overload of Panel for Raster in order to add signal for updating param # item = CustomFileSelectionPanel(param.isFolder, param.ext) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self,param) return item
def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system self.types_of_metrics = {} for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText(self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() self.changeWindowShapeDependent() # === param:WINDOW_SIZES Widget:IntListSelectionPanel === lineEdit = self.widgets["WINDOW_SIZES"].lineEdit lineEdit.setReadOnly(True) sbInt = self.widgets["WINDOW_SIZES"].sbInt sbInt.setValue(3) # === param:METRICS Widget:ListSelectionPanel === # === Init cbFilter cbFilter = self.widgets["METRICS"].cbFilter cbFilter.addItems(self.alg.types_of_metrics.keys()) # === Init listSrc value = cbFilter.currentText() listSrc = self.widgets["METRICS"].listSrc listSrc.clear() if self.types_of_metrics: if value in self.types_of_metrics.keys(): listSrc.addItems(self.types_of_metrics[value]) # === Init listDest listDest = self.widgets["METRICS"].listDest listDest.clear() self.metrics_selected = set() self.window_sizes_selected = set() lineEdit = self.widgets["METRICS"].lineEdit lineEdit.setReadOnly(True)
def createWidget(self, parent): return QPlainTextEdit(parent)
def createWidget(self): if self.dialogType == DIALOG_STANDARD: if self.param.multiline: widget = QPlainTextEdit() if self.param.default: widget.setPlainText(self.param.default) else: widget = StringInputPanel(self.param) if self.param.default: widget.setValue(self.param.default) elif self.dialogType == DIALOG_BATCH: widget = QLineEdit() if self.param.default: widget.setText(self.param.default) else: strings = self.dialog.getAvailableValuesOfType(ParameterString, OutputString) options = [(self.dialog.resolveValueDescription(s), s) for s in strings] if self.param.multiline: widget = MultilineTextPanel(options) widget.setText(self.param.default or "") else: widget = QComboBox() widget.setEditable(True) for desc, val in options: widget.addItem(desc, val) widget.setEditText(self.param.default or "") return widget
class MapParametersPanel(ChloeParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__( self, parent, alg) ## Création le l'interface Qt pour les paramètres ## Add console command w = QWidget() # New Qt Windows layout = QVBoxLayout() # New Qt vertical Layout layout.setMargin(0) layout.setSpacing(6) label = QLabel() # New Qt label (text) label.setText(self.tr("Chloe/Java console call")) layout.addWidget(label) # Add label in layout self.text = QPlainTextEdit() # New Qt champs de text in/out self.text.setReadOnly(True) # Read only layout.addWidget(self.text) # Add in layout w.setLayout(layout) # layout -in-> Windows self.layoutMain.addWidget(w) # windows -in-> Windows system self.types_of_metrics = {} for output in self.alg.outputs: if isinstance(output, (OutputRaster, OutputVector, OutputTable)): self.checkBoxes[output.name].setText( self.tr('Open output file after running algorithm')) self.connectParameterSignals() self.parametersHaveChanged() # === Init cbFilter cbFilter = self.widgets["METRICS"].cbFilter cbFilter.addItems(self.alg.types_of_metrics.keys()) # === Init listSrc value = cbFilter.currentText() listSrc = self.widgets["METRICS"].listSrc listSrc.clear() if self.types_of_metrics: if value in self.types_of_metrics.keys(): listSrc.addItems(self.types_of_metrics[value]) # === Init listDest listDest = self.widgets["METRICS"].listDest listDest.clear() self.metrics_selected = set() lineEdit = self.widgets["METRICS"].lineEdit lineEdit.setReadOnly(True) def connectParameterSignals(self): for w in self.widgets.values(): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, FileSelectionPanel): w.cmbText.currentIndexChanged.connect( self.parametersHaveChanged) elif isinstance(w, InputLayerSelectorPanel): w.cmbText.currentIndexChanged.connect(self.initCalculateMetric) w.cmbText.currentIndexChanged.connect( self.parametersHaveChanged) w.cmbText.currentIndexChanged.connect(self.removeAllListDst) w.cmbText.currentIndexChanged.connect( self.changeMetricDependent) elif isinstance(w, ListSelectionPanel): w.pbRight.clicked.connect(self.addInListDst) w.listSrc.itemDoubleClicked.connect(self.addInListDst) w.pbLeft.clicked.connect(self.removeInListDst) w.pbAll.clicked.connect(self.addAllInListDst) w.pbClear.clicked.connect(self.removeAllListDst) w.lineEdit.textChanged.connect(self.parametersHaveChanged) w.cbFilter.currentIndexChanged.connect( self.changeMetricDependent) # Update console display self.valueItems["SAVE_PROPERTIES"].leText.textChanged.connect( self.parametersHaveChanged) w = self.widgets["METRICS"].cbFilter w.currentIndexChanged.emit(0) self.widgets["INPUT_LAYER_ASC"].cmbText.currentIndexChanged.emit(0) #@pyqtSlot(str) def initCalculateMetric(self): w = self.widgets['INPUT_LAYER_ASC'] try: val = w.getValue() if isinstance(val, QgsRasterLayer): rasterLayerParam = val.source().encode('utf-8') else: rasterLayerParam = val.encode('utf-8') int_values_and_nodata = ChloeUtils.extractValueNotNull( rasterLayerParam) self.types_of_metrics = ChloeUtils.calculateMetric( self.alg.types_of_metrics, self.alg.types_of_metrics_simple, self.alg.types_of_metrics_cross, int_values_and_nodata) except: self.types_of_metrics = [] @staticmethod def iterAllItems(lws): for i in range(lws.count()): yield lws.item(i) #@pyqtSlot(str) def addAllInListDst(self): self.addInListDst(all=True) #@pyqtSlot(str) def addInListDst(self, item=None, all=False): """Add metrics selected in listSrc to ListDst""" if not all: selected = self.widgets["METRICS"].listSrc.selectedItems() else: selected = self.iterAllItems(self.widgets["METRICS"].listSrc) for lw in selected: self.metrics_selected.add(lw.text()) listDest = self.widgets["METRICS"].listDest listDest.clear() listDest.addItems(list(self.metrics_selected)) self.updateMetricsLigneEdit() #@pyqtSlot() def removeAllListDst(self): listDest = self.widgets["METRICS"].listDest listDest.clear() self.metrics_selected = set() self.updateMetricsLigneEdit() #@pyqtSlot(str) def removeInListDst(self): """Remove metrics selected in listDest""" selected = self.widgets["METRICS"].listDest.selectedItems() for lw in selected: self.metrics_selected.remove(lw.text()) listDest = self.widgets["METRICS"].listDest listDest.clear() listDest.addItems(list(self.metrics_selected)) self.updateMetricsLigneEdit() def updateMetricsLigneEdit(self): """update Metrics (QLineEdit in readOnly mode)""" lineEdit = self.widgets["METRICS"].lineEdit metrics = list(self.metrics_selected) if metrics: lineEdit.setText(";".join(metrics)) else: lineEdit.setText("") #@pyqtSlot(str) def changeMetricDependent(self): """ Update metric source list when the filter of metric change """ cbFilter = self.widgets["METRICS"].cbFilter # === Init list metric value = cbFilter.currentText() listSrc = self.widgets["METRICS"].listSrc listSrc.clear() if self.types_of_metrics: if value in self.types_of_metrics.keys(): listSrc.addItems(self.types_of_metrics[value]) #@pyqtSlot(str) def parametersHaveChanged(self): try: # === Update values of widgets-to->params === # For custom widget (like CustomPanel), overload AlgorithmDialog.setParamValue() # Important, can lunch exception if value is 'null' and 'required' self.parent.setParamValues() for output in self.alg.outputs: # Manage output fileds if output.value is None: output.value = self.tr("[temporary file]") properties = self.valueItems["SAVE_PROPERTIES"].leText.text() commands = self.alg.getConsoleCommands(properties) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText( self.tr("Invalid value for parameter '%s'") % e.parameter.description) except Exception as e: self.text.setPlainText("Error : " + e.message) #raise e def getWidgetFromParameter(self, param): """ Overload for custom Qwidget(Panel) from Parameter return item : Qwidget(Panel) """ if param.name in ["METRICS"]: # === Overload ParameterString for special parameter name like FIELDS,..s item = ListSelectionPanel(self.parent, self.alg, param.default) elif isinstance(param, ParameterRaster): # === Overload of Panel for Raster in order to add signal for updating param layers = dataobjects.getRasterLayers() items = [] if param.optional: items.append((self.NOT_SELECTED, None)) self.NONE_SELECTED = self.tr('Chose a layer') items.append((self.NONE_SELECTED, "")) # Not use None for layer in layers: items.append((self.getExtendedLayerName(layer), layer)) item = InputLayerSelectorPanel(items, param) else: # == default Wigdet from Parameter, i.e. use parent method item = ParametersPanel.getWidgetFromParameter(self, param) return item
class GdalParametersPanel(ParametersPanel): def __init__(self, parent, alg): ParametersPanel.__init__(self, parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("GDAL/OGR console call")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): wrapper.widgetValueHasChanged.connect(self.parametersHaveChanged) # TODO - remove when all wrappers correctly emit widgetValueHasChanged! # 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): w = wrapper.widget else: w = wrapper.wrappedWidget() self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) for output_widget in self.outputWidgets.values(): self.connectWidgetChangedSignals(output_widget) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, DestinationSelectionPanel): w.destinationChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()])): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description())) except AlgorithmDialogBase.InvalidOutputExtension as e: self.text.setPlainText(e.message)
class ImportDialog(QDialog): def __init__(self, parent, repo=None, layer=None): super(ImportDialog, self).__init__(parent) self.setObjectName("ImportDialog") self.repo = repo self.layer = layer self.ok = False self.initGui() def initGui(self): self.setWindowTitle('Import to GeoGig') verticalLayout = QVBoxLayout() if self.repo is None: repos = repository.repos layerLabel = QLabel('Repository') verticalLayout.addWidget(layerLabel) self.repoCombo = QComboBox() self.repoCombo.addItems( ["%s - %s" % (r.group, r.title) for r in repos]) self.repoCombo.currentIndexChanged.connect(self.updateBranches) verticalLayout.addWidget(self.repoCombo) if self.layer is None: layerLabel = QLabel('Layer') verticalLayout.addWidget(layerLabel) self.layerCombo = QComboBox() layerNames = [ layer.name() for layer in vectorLayers() if layer.source().lower().split("|")[0].split(".")[-1] in ["gpkg", "geopkg"] and not isRepoLayer(layer) ] self.layerCombo.addItems(layerNames) verticalLayout.addWidget(self.layerCombo) self.branchLabel = QLabel("Branch") verticalLayout.addWidget(self.branchLabel) self.branchCombo = QComboBox() self.branches = self.repo.branches( ) if self.repo is not None else repos[0].branches() self.branchCombo.addItems(self.branches) verticalLayout.addWidget(self.branchCombo) messageLabel = QLabel('Message to describe this update') verticalLayout.addWidget(messageLabel) self.messageBox = QPlainTextEdit() verticalLayout.addWidget(self.messageBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Cancel) self.importButton = QPushButton("Add layer") self.importButton.clicked.connect(self.importClicked) self.buttonBox.addButton(self.importButton, QDialogButtonBox.ApplyRole) self.buttonBox.rejected.connect(self.cancelPressed) verticalLayout.addWidget(self.buttonBox) self.setLayout(verticalLayout) self.resize(600, 300) self.messageBox.setFocus() def updateBranches(self): self.branchCombo.clear() repo = repository.repos[self.repoCombo.currentIndex()] self.branches = repo.branches() self.branchCombo.addItems(self.branches) def importClicked(self): ret = QMessageBox.warning( config.iface.mainWindow(), 'Import warning', "Importing a layer will modify the original layer and might cause data loss.\n" "Make sure you have a backup copy of your layer before importing.\n" "Do you want to import the selected layer?", QMessageBox.Yes | QMessageBox.No) if ret == QMessageBox.No: return if self.repo is None: self.repo = repository.repos[self.repoCombo.currentIndex()] if self.layer is None: text = self.layerCombo.currentText() self.layer = layerFromName(text) user, email = config.getUserInfo() if user is None: self.close() return message = self.messageBox.toPlainText() or datetime.now().strftime( "%Y-%m-%d %H_%M_%S") branch = self.branchCombo.currentText() try: self.repo.importgeopkg(self.layer, branch, message, user, email, False) filename, layername = namesFromLayer(self.layer) self.repo.checkoutlayer(filename, layername, ref=branch) self.layer.reload() self.layer.triggerRepaint() except GeoGigException as e: iface.messageBar().pushMessage("Error", str(e), level=QgsMessageBar.CRITICAL, duration=5) self.close() return addTrackedLayer(self.layer, self.repo.url) self.ok = True iface.messageBar().pushMessage( "Layer was correctly added to repository", level=QgsMessageBar.INFO, duration=5) self.close() def cancelPressed(self): self.close()
def createWidget(self): if self.dialogType == DIALOG_STANDARD: if self.param.multiline: widget = QPlainTextEdit() if self.param.default: widget.setPlainText(self.param.default) else: widget = StringInputPanel(self.param) if self.param.default: widget.setValue(self.param.default) elif self.dialogType == DIALOG_BATCH: widget = QLineEdit() if self.param.default: widget.setText(self.param.default) else: # strings, numbers, files and table fields are all allowed input types strings = self.dialog.getAvailableValuesOfType([ParameterString, ParameterNumber, ParameterFile, ParameterTableField, ParameterExpression], OutputString) options = [(self.dialog.resolveValueDescription(s), s) for s in strings] if self.param.multiline: widget = MultilineTextPanel(options) widget.setText(self.param.default or "") else: widget = QComboBox() widget.setEditable(True) for desc, val in options: widget.addItem(desc, val) widget.setEditText(self.param.default or "") return widget
class ChloeParametersPanel(ParametersPanel): def __init__(self, parent, alg): super().__init__(parent, alg) w = QWidget() layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(6) label = QLabel() label.setText(self.tr("Chloe Command line")) layout.addWidget(label) self.text = QPlainTextEdit() self.text.setReadOnly(True) layout.addWidget(self.text) w.setLayout(layout) self.layoutMain.addWidget(w) self.connectParameterSignals() self.parametersHaveChanged() # def initWidgets(self): # """Init widget panel for each input output""" # super().initWidgets() # for output_name, output_panel in self.outputWidgets.items(): # # # Add check box for automacial load after process algorithm # # for 'OUTPUT_ASC' (QgsProcessingParameterFileDestination) # if output_name == 'OUTPUT_ASC': # check = QCheckBox() # check.setText(QCoreApplication.translate('ParametersPanel', 'Open output file after running algorithm')) # # def skipOutputChanged(checkbox, skipped): # checkbox.setEnabled(not skipped) # if skipped: # checkbox.setChecked(False) # check.setChecked(not output_panel.outputIsSkipped()) # check.setEnabled(not output_panel.outputIsSkipped()) # # output_panel.skipOutputChanged.connect(partial(skipOutputChanged, check)) # self.layoutMain.insertWidget(self.layoutMain.count() - 1, check) # self.checkBoxes[output_name] = check def initWidgets(self): # Heavy overload # If there are advanced parameters — show corresponding groupbox for param in self.alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.grpAdvanced.show() break #widget_context = QgsProcessingParameterWidgetContext() #if iface is not None: # widget_context.setMapCanvas(iface.mapCanvas()) # Create widgets and put them in layouts for param in self.alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue print('initWidgets - param.name(): {}'.format(param.name())) if param.isDestination(): # and param.name() != 'OUTPUT_ASC': continue else: wrapper = WidgetWrapperFactory.create_wrapper(param, self.parent) self.wrappers[param.name()] = wrapper #widget = wrapper.widget # 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 is_python_wrapper = issubclass(wrapper.__class__, WidgetWrapper) if not is_python_wrapper: from qgis.gui import (QgsProcessingContextGenerator, QgsProcessingParameterWidgetContext) widget_context = QgsProcessingParameterWidgetContext() if iface is not None: widget_context.setMapCanvas(iface.mapCanvas()) wrapper.setWidgetContext(widget_context) widget = wrapper.createWrappedWidget(self.processing_context) wrapper.registerProcessingContextGenerator(self.context_generator) else: widget = wrapper.widget #if self.in_place and param.name() in ('INPUT', 'OUTPUT'): # don't show the input/output parameter widgets in in-place mode # we still need to CREATE them, because other wrappers may need to interact # with them (e.g. those parameters which need the input layer for field # selections/crs properties/etc) # continue if widget is not None: if is_python_wrapper: widget.setToolTip(param.toolTip()) if isinstance(param, QgsProcessingParameterFeatureSource): layout = QHBoxLayout() layout.setSpacing(6) layout.setMargin(0) layout.addWidget(widget) button = QToolButton() icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png')) button.setIcon(icon) button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) button.setToolTip(self.tr('Iterate over this layer, creating a separate output for every feature in the layer')) button.setCheckable(True) layout.addWidget(button) layout.setAlignment(button, Qt.AlignTop) self.iterateButtons[param.name()] = button button.toggled.connect(self.buttonToggled) widget = QWidget() widget.setLayout(layout) label = None if not is_python_wrapper: label = wrapper.createWrappedLabel() else: label = wrapper.label if label is not None: if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.layoutAdvanced.addWidget(label) else: self.layoutMain.insertWidget( self.layoutMain.count() - 2, label) elif is_python_wrapper: desc = param.description() if isinstance(param, QgsProcessingParameterExtent): desc += self.tr(' (xmin, xmax, ymin, ymax)') if isinstance(param, QgsProcessingParameterPoint): desc += self.tr(' (x, y)') if param.flags() & QgsProcessingParameterDefinition.FlagOptional: desc += self.tr(' [optional]') widget.setText(desc) if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.layoutAdvanced.addWidget(widget) else: self.layoutMain.insertWidget( self.layoutMain.count() - 2, widget) for output in self.alg.destinationParameterDefinitions(): if output.flags() & QgsProcessingParameterDefinition.FlagHidden: continue #if self.in_place and param.name() in ('INPUT', 'OUTPUT'): # continue label = QLabel(output.description()) #print('initWidgets 2 - param.name(): {}'.format(param.name())) widget = DestinationSelectionPanel(output, self.alg) # TODO, overload self.layoutMain.insertWidget(self.layoutMain.count() - 1, label) self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget) if isinstance(output, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterVectorDestination # alk: checkboxes for Chloe handling ,ChloeCSVParameterFileDestination, ChloeASCParameterFileDestination, ChloeParameterFolderDestination) ): check = QCheckBox() check.setText(QCoreApplication.translate('ParametersPanel', 'Open output file(s) after running algorithm')) def skipOutputChanged(checkbox, skipped): checkbox.setEnabled(not skipped) if skipped: checkbox.setChecked(False) check.setChecked(not widget.outputIsSkipped()) check.setEnabled(not widget.outputIsSkipped()) widget.skipOutputChanged.connect(partial(skipOutputChanged, check)) self.layoutMain.insertWidget(self.layoutMain.count() - 1, check) self.checkBoxes[output.name()] = check # initial state if hasattr(output,'addToMapDefaultState'): check.setChecked(output.addToMapDefaultState) widget.setToolTip(param.toolTip()) self.outputWidgets[output.name()] = widget for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values())) # # alk: checkboxes for Chloe handling # for output in self.alg.destinationParameterDefinitions(): # if output.flags() & QgsProcessingParameterDefinition.FlagHidden: # continue # if isinstance(output, (ChloeCSVParameterFileDestination)) or isinstance(output, (ChloeASCParameterFileDestination)): # check = QCheckBox() # check.setText(QCoreApplication.translate('ParametersPanel', 'Open output file(s) after running algorithm')) # def skipOutputChanged(checkbox, skipped): # checkbox.setEnabled(not skipped) # if skipped: # checkbox.setChecked(False) # check.setChecked(not widget.outputIsSkipped()) # check.setEnabled(not widget.outputIsSkipped()) # widget.skipOutputChanged.connect(partial(skipOutputChanged, check)) # print(str(self.layoutMain)+1) # self.layoutMain.insertWidget(self.layoutMain.count() - 1, check) # self.checkBoxes[output.name()] = check # # connecting alg outputLoading info with checkbox state # self.alg.outputLoading[output.name()] = check.isChecked() # def updateOutputLoadingState(alg, outputName, checkbox, state): # self.alg.outputLoading[outputName] = checkbox.isChecked() # print( outputName + " " + str(checkbox.isChecked()) + " " + str(self.alg.outputLoading) + " " + str(self.alg)) # #print(str(self.alg.parameters)) # check.stateChanged.connect(partial(updateOutputLoadingState, self, output.name(), check)) # alk: addition of wrapper special config handling # for dependancy between wrapper, i.e. changing the value # of a FileSelectionPanel entails the update of another widget for k in self.wrappers: w = self.wrappers[k] if hasattr(w,'getParentWidgetConfig'): print(str(w) + " " + "getParentWidgetConfig") config = w.getParentWidgetConfig() if config != None: p = self.wrappers[config['paramName']] m = getattr(w, config['refreshMethod']) if m!=None: print(str(p) + " " + str(p.widget)) # todo generalize valueChanged handling # to any type of widget componant if isinstance(p.widget, FileSelectionPanel): p.widget.leText.textChanged.connect(m) elif isinstance(p, RasterWidgetWrapper): try: p.combo.valueChanged.connect(m) # QGIS 3.8 version except: p.combo.currentIndexChanged.connect(m) # QGIS LTR 3.4 def connectParameterSignals(self): for wrapper in list(self.wrappers.values()): wrapper.widgetValueHasChanged.connect(self.parametersHaveChanged) # TODO - remove when all wrappers correctly emit widgetValueHasChanged! # 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): w = wrapper.widget else: w = wrapper.wrappedWidget() self.connectWidgetChangedSignals(w) for c in w.findChildren(QWidget): self.connectWidgetChangedSignals(c) for output_widget in self.outputWidgets.values(): self.connectWidgetChangedSignals(output_widget) def connectWidgetChangedSignals(self, w): if isinstance(w, QLineEdit): w.textChanged.connect(self.parametersHaveChanged) elif isinstance(w, QComboBox): w.currentIndexChanged.connect(self.parametersHaveChanged) elif isinstance(w, QgsProjectionSelectionWidget): w.crsChanged.connect(self.parametersHaveChanged) elif isinstance(w, QCheckBox): w.stateChanged.connect(self.parametersHaveChanged) elif isinstance(w, MultipleInputPanel): w.selectionChanged.connect(self.parametersHaveChanged) elif isinstance(w, NumberInputPanel): w.hasChanged.connect(self.parametersHaveChanged) elif isinstance(w, DestinationSelectionPanel): w.destinationChanged.connect(self.parametersHaveChanged) def parametersHaveChanged(self): context = createContext() feedback = QgsProcessingFeedback() try: parameters = self.parent.getParameterValues() for output in self.alg.destinationParameterDefinitions(): if not output.name() in parameters or parameters[output.name()] is None: parameters[output.name()] = self.tr("[temporary file]") for p in self.alg.parameterDefinitions(): if (not p.name() in parameters and not p.flags() & QgsProcessingParameterDefinition.FlagOptional) \ or (not p.checkValueIsAcceptable(parameters[p.name()])): # not ready yet self.text.setPlainText('') return commands = self.alg.getConsoleCommands(parameters, context, feedback, executing=False) commands = [c for c in commands if c not in ['cmd.exe', '/C ']] self.text.setPlainText(" ".join(commands)) except AlgorithmDialogBase.InvalidParameterValue as e: self.text.setPlainText(self.tr("Invalid value for parameter '{0}'").format(e.parameter.description())) if e.parameter.name()=='MAP_CSV': raise