def __init__(self, text): QPushButton.__init__(self) self.setText(text) buttons_size_policy = QSizePolicy( QSizePolicy.Fixed, QSizePolicy.Fixed) self.setSizePolicy(buttons_size_policy) self.setMaximumSize(QSize(30, 30))
def __init__(self): super(HistoryDialog, self).__init__(None) self.setupUi(self) QgsGui.instance().enableAutoGeometryRestore(self) self.groupIcon = QgsApplication.getThemeIcon('mIconFolder.svg') self.keyIcon = self.style().standardIcon(QStyle.SP_FileIcon) self.clearButton = QPushButton(self.tr('Clear')) self.clearButton.setToolTip(self.tr('Clear history')) self.buttonBox.addButton(self.clearButton, QDialogButtonBox.ActionRole) self.saveButton = QPushButton(QCoreApplication.translate('HistoryDialog', 'Save As…')) self.saveButton.setToolTip(self.tr('Save history')) self.buttonBox.addButton(self.saveButton, QDialogButtonBox.ActionRole) self.tree.doubleClicked.connect(self.executeAlgorithm) self.tree.currentItemChanged.connect(self.changeText) self.clearButton.clicked.connect(self.clearLog) self.saveButton.clicked.connect(self.saveLog) self.tree.setContextMenuPolicy(Qt.CustomContextMenu) self.tree.customContextMenuRequested.connect(self.showPopupMenu) self.fillTree()
def __init__(self, param, table): super(FixedTableDialog, self).__init__(None) self.setupUi(self) self.tblView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.param = param self.rettable = None # Additional buttons self.btnAdd = QPushButton(self.tr('Add row')) self.buttonBox.addButton(self.btnAdd, QDialogButtonBox.ActionRole) self.btnRemove = QPushButton(self.tr('Remove row(s)')) self.buttonBox.addButton(self.btnRemove, QDialogButtonBox.ActionRole) self.btnRemoveAll = QPushButton(self.tr('Remove all')) self.buttonBox.addButton(self.btnRemoveAll, QDialogButtonBox.ActionRole) self.btnAdd.clicked.connect(self.addRow) self.btnRemove.clicked.connect(lambda: self.removeRows()) self.btnRemoveAll.clicked.connect(lambda: self.removeRows(True)) if self.param.fixedNumOfRows: self.btnAdd.setEnabled(False) self.btnRemove.setEnabled(False) self.btnRemoveAll.setEnabled(False) self.populateTable(table)
def __init__(self): super(HistoryDialog, self).__init__(None) self.setupUi(self) self.groupIcon = QIcon() self.groupIcon.addPixmap(self.style().standardPixmap( QStyle.SP_DirClosedIcon), QIcon.Normal, QIcon.Off) self.groupIcon.addPixmap(self.style().standardPixmap( QStyle.SP_DirOpenIcon), QIcon.Normal, QIcon.On) self.keyIcon = QIcon() self.keyIcon.addPixmap(self.style().standardPixmap(QStyle.SP_FileIcon)) self.clearButton = QPushButton(self.tr('Clear')) self.clearButton.setToolTip(self.tr('Clear history')) self.buttonBox.addButton(self.clearButton, QDialogButtonBox.ActionRole) self.saveButton = QPushButton(self.tr('Save As...')) self.saveButton.setToolTip(self.tr('Save history')) self.buttonBox.addButton(self.saveButton, QDialogButtonBox.ActionRole) self.tree.doubleClicked.connect(self.executeAlgorithm) self.tree.currentItemChanged.connect(self.changeText) self.clearButton.clicked.connect(self.clearLog) self.saveButton.clicked.connect(self.saveLog) self.tree.setContextMenuPolicy(Qt.CustomContextMenu) self.tree.customContextMenuRequested.connect(self.showPopupMenu) self.fillTree()
def setupUi(self): self.resize(500, 350) self.setWindowTitle("Remote connections manager") self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setSpacing(2) self.horizontalLayout.setMargin(0) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Vertical) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.table = QTableWidget() self.table.verticalHeader().setVisible(False) self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.addRowButton = QPushButton() self.addRowButton.setText("Add connection") self.editRowButton = QPushButton() self.editRowButton.setText("Edit connection") self.removeRowButton = QPushButton() self.removeRowButton.setText("Remove connection") self.buttonBox.addButton(self.addRowButton, QDialogButtonBox.ActionRole) self.buttonBox.addButton(self.editRowButton, QDialogButtonBox.ActionRole) self.buttonBox.addButton(self.removeRowButton, QDialogButtonBox.ActionRole) self.setTableContent() self.horizontalLayout.addWidget(self.table) self.horizontalLayout.addWidget(self.buttonBox) self.setLayout(self.horizontalLayout) self.buttonBox.rejected.connect(self.close) self.editRowButton.clicked.connect(self.editRow) self.addRowButton.clicked.connect(self.addRow) self.removeRowButton.clicked.connect(self.removeRow) QMetaObject.connectSlotsByName(self) self.editRowButton.setEnabled(False) self.removeRowButton.setEnabled(False)
def treeItemClicked(self, item): if item.childCount(): return color = {"MODIFIED": QColor(255, 170, 0), "ADDED":Qt.green, "REMOVED":Qt.red , "NO_CHANGE":Qt.white} changeTypeName = ["", "ADDED", "MODIFIED", "REMOVED"] path = item.text(0) if path not in self.changes: return oldfeature = self.changes[path].oldfeature newfeature = self.changes[path].newfeature changetype = self.changes[path].changetype self.attributesTable.clear() self.attributesTable.verticalHeader().show() self.attributesTable.horizontalHeader().show() self.attributesTable.setRowCount(len(newfeature)) self.attributesTable.setVerticalHeaderLabels([a for a in newfeature]) self.attributesTable.setHorizontalHeaderLabels(["Old value", "New value", "Change type"]) for i, attrib in enumerate(newfeature): self.attributesTable.setItem(i, 0, DiffItem(oldfeature.get(attrib, None))) self.attributesTable.setItem(i, 1, DiffItem(newfeature.get(attrib, None))) attribChangeType = changeTypeName[changetype] isChangedGeom = False if changetype == LOCAL_FEATURE_MODIFIED: oldvalue = oldfeature.get(attrib, None) newvalue = newfeature.get(attrib, None) try:# to avoid false change detection due to different precisions oldvalue = QgsGeometry.fromWkt(oldvalue).exportToWkt(7) newvalue = QgsGeometry.fromWkt(newvalue).exportToWkt(7) if oldvalue != newvalue and None not in [oldvalue, newvalue]: widget = QWidget() btn = QPushButton() btn.setText("View detail") g1 = QgsGeometry.fromWkt(oldvalue) g2 = QgsGeometry.fromWkt(newvalue) btn.clicked.connect(lambda: self.viewGeometryChanges(g1, g2)) label = QLabel() label.setText(attribChangeType) layout = QHBoxLayout(widget) layout.addWidget(label); layout.addWidget(btn); layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) self.attributesTable.setItem(i, 2, QTableWidgetItem("")) self.attributesTable.setCellWidget(i, 2, widget) isChangedGeom = True except: pass if oldvalue == newvalue: attribChangeType = "NO_CHANGE" if not isChangedGeom: self.attributesTable.setItem(i, 2, QTableWidgetItem(attribChangeType)) for col in range(3): self.attributesTable.item(i, col).setBackgroundColor(color[attribChangeType]); self.attributesTable.resizeColumnsToContents() self.attributesTable.horizontalHeader().setResizeMode(QHeaderView.Stretch)
def _reverseAdresCallback(self, point): self._addMarker( point ) lam72 = QgsCoordinateReferenceSystem(31370) mapCrs = self.gh.getGetMapCrs(self.iface) xform = QgsCoordinateTransform(mapCrs, lam72, QgsProject.instance()) lam72clickt = xform.transform(point) #to clear or not clear that is the question self.iface.messageBar().clearWidgets() #fetch Location from geopunt adres = self.gp.fetchLocation( str( lam72clickt.x() ) + "," + str( lam72clickt.y() ), 1) Timer( 3, self._clearGraphicLayer, ()).start() if len(adres) and type( adres ) is list: #only one result in list, was set in request FormattedAddress = adres[0]["FormattedAddress"] #add a button to the messageBar widget xlam72, ylam72 = adres[0]["Location"]["X_Lambert72"], adres[0]["Location"]["Y_Lambert72"] diff = int(((xlam72 - lam72clickt.x())**2 +(ylam72 - lam72clickt.y())**2 )**(0.5)) widget = self.iface.messageBar().createMessage(QCoreApplication.translate( "geopunt4Qgis", "Resultaat: "), "{0} (verschil: {1}m)".format(FormattedAddress, diff)) xy = self.gh.prjPtToMapCrs([xlam72, ylam72], 31370) self._addMarker( xy, QColor(0,255,200)) button = QPushButton(widget) button.clicked.connect(lambda: self._addReverse(adres[0])) button.setText(QCoreApplication.translate("geopunt4Qgis" ,"Voeg toe")) widget.layout().addWidget(button) self.iface.messageBar().clearWidgets() self.iface.messageBar().pushWidget(widget, level=Qgis.Info) elif len(adres) == 0: self.iface.messageBar().pushMessage(QCoreApplication.translate("geopunt4Qgis","Waarschuwing"), QCoreApplication.translate("geopunt4Qgis", "Geen resultaten gevonden"), level=QgsMessageBar.INFO, duration=3) elif type( adres ) is str: self.iface.messageBar().pushMessage(QCoreApplication.translate("geopunt4Qgis", "Waarschuwing"), adres, level=QgsMessageBar.WARNING) else: self.iface.messageBar().pushMessage("Error", QCoreApplication.translate("geopunt4Qgis","onbekende fout"), level=Qgis.Critical)
def parseresponse(self, response): # Trim callback result = response[len(self.config['callback']) + 1: -1] try: obj = json.loads(result) except: QgsApplication.messageLog().logMessage( 'Invalid JSON response from server: ' + result, __package__ ) # Check if we have an auth error if "User not authorized" in response: title = self.tr(u'Afvist af Kortforsyningen') message = self.tr(u'Manglende eller ukorrekt token til Kortforsyningen.') button_text = self.tr(u'Ă…bn settings') widget = self.qgisIface.messageBar().createMessage(title, message) button = QPushButton(widget) button.setText(button_text) button.pressed.connect(lambda : self.qgisIface.showOptionsDialog(currentPage='geosearchOptions')) widget.layout().addWidget(button) self.qgisIface.messageBar().pushWidget(widget, level=Qgis.Warning, duration=15) return None if 'status' not in obj: QgsApplication.messageLog().logMessage( 'Unexpected result from server: ' + result, __package__ ) return None if not obj['status'] == 'OK': QgsApplication.messageLog().logMessage( 'Server reported an error: ' + obj['message'], __package__ ) return None if "data" not in obj: return None data = obj['data'] if not data: return [(self.tr("Ingen resultater"),None)] # Make tuple with ("text", object) for each result return [(e['presentationString'], e) for e in data]
def __init__(self, param, table): """ Constructor for FixedTableDialog :param param: linked processing parameter :param table: initial table contents - squashed to 1-dimensional! """ super().__init__(None) self.setupUi(self) QgsGui.instance().enableAutoGeometryRestore(self) self.tblView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.param = param self.rettable = None # Additional buttons self.btnAdd = QPushButton(self.tr('Add row')) self.buttonBox.addButton(self.btnAdd, QDialogButtonBox.ActionRole) self.btnRemove = QPushButton(self.tr('Remove row(s)')) self.buttonBox.addButton(self.btnRemove, QDialogButtonBox.ActionRole) self.btnRemoveAll = QPushButton(self.tr('Remove all')) self.buttonBox.addButton(self.btnRemoveAll, QDialogButtonBox.ActionRole) self.btnAdd.clicked.connect(self.addRow) self.btnRemove.clicked.connect(lambda: self.removeRows()) self.btnRemoveAll.clicked.connect(lambda: self.removeRows(True)) if self.param.hasFixedNumberRows(): self.btnAdd.setEnabled(False) self.btnRemove.setEnabled(False) self.btnRemoveAll.setEnabled(False) self.populateTable(table)
def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.workerThread = None self.state = False self.outputLoc = None self.resultStatus = None self.reRun = False self.savedProj = None # Build GUI Elements self.setWindowTitle("SEILAPLAN wird ausgefĂĽhrt") self.resize(500, 100) self.container = QVBoxLayout() self.progressBar = QProgressBar(self) self.progressBar.setMinimumWidth(500) self.statusLabel = QLabel(self) self.hbox = QHBoxLayout() self.cancelButton = QDialogButtonBox() self.closeButton = QDialogButtonBox() self.resultLabel = ClickLabel(self) self.resultLabel.setMaximumWidth(500) self.resultLabel.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)) self.resultLabel.setWordWrap(True) self.rerunButton = QPushButton("Berechnungen wiederholen") self.rerunButton.setVisible(False) spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.cancelButton.setStandardButtons(QDialogButtonBox.Cancel) self.cancelButton.clicked.connect(self.onAbort) self.closeButton.setStandardButtons(QDialogButtonBox.Close) self.closeButton.clicked.connect(self.onClose) self.hbox.addWidget(self.rerunButton) self.hbox.addItem(spacer) self.hbox.addWidget(self.cancelButton) self.hbox.setAlignment(self.cancelButton, Qt.AlignHCenter) self.hbox.addWidget(self.closeButton) self.hbox.setAlignment(self.closeButton, Qt.AlignHCenter) self.closeButton.hide() self.container.addWidget(self.progressBar) self.container.addWidget(self.statusLabel) self.container.addWidget(self.resultLabel) self.container.addLayout(self.hbox) self.container.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(self.container)
def __init__(self, param, row, col, dialog): super(BatchInputSelectionPanel, self).__init__(None) self.param = param self.dialog = dialog self.row = row self.col = col self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(0) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setObjectName("text") self.text.setMinimumWidth(300) self.setValue("") self.text.editingFinished.connect(self.textEditingFinished) self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText("...") self.pushButton.clicked.connect(self.showPopupMenu) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout)
def __init__(self, param, row, col, panel): super(BatchInputSelectionPanel, self).__init__(None) self.param = param self.panel = panel self.table = self.panel.tblParameters self.row = row self.col = col self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(0) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setMinimumWidth(300) self.text.setText('') self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText('...') self.pushButton.clicked.connect(self.showPopupMenu) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout)
def __init__(self, output, alg, row, col, panel): super(BatchOutputSelectionPanel, self).__init__(None) self.alg = alg self.row = row self.col = col self.output = output self.panel = panel self.table = self.panel.tblParameters self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(2) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setText('') self.text.setMinimumWidth(300) self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText('…') self.pushButton.clicked.connect(self.showSelectionDialog) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout)
class HistoryDialog(BASE, WIDGET): def __init__(self): super(HistoryDialog, self).__init__(None) self.setupUi(self) self.groupIcon = QIcon() self.groupIcon.addPixmap(self.style().standardPixmap( QStyle.SP_DirClosedIcon), QIcon.Normal, QIcon.Off) self.groupIcon.addPixmap(self.style().standardPixmap( QStyle.SP_DirOpenIcon), QIcon.Normal, QIcon.On) self.keyIcon = QIcon() self.keyIcon.addPixmap(self.style().standardPixmap(QStyle.SP_FileIcon)) self.clearButton = QPushButton(self.tr('Clear')) self.clearButton.setToolTip(self.tr('Clear history')) self.buttonBox.addButton(self.clearButton, QDialogButtonBox.ActionRole) self.saveButton = QPushButton(self.tr('Save As...')) self.saveButton.setToolTip(self.tr('Save history')) self.buttonBox.addButton(self.saveButton, QDialogButtonBox.ActionRole) self.tree.doubleClicked.connect(self.executeAlgorithm) self.tree.currentItemChanged.connect(self.changeText) self.clearButton.clicked.connect(self.clearLog) self.saveButton.clicked.connect(self.saveLog) self.tree.setContextMenuPolicy(Qt.CustomContextMenu) self.tree.customContextMenuRequested.connect(self.showPopupMenu) self.fillTree() def clearLog(self): reply = QMessageBox.question(self, self.tr('Confirmation'), self.tr('Are you sure you want to clear the history?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) if reply == QMessageBox.Yes: ProcessingLog.clearLog() self.fillTree() def saveLog(self): fileName, filter = QFileDialog.getSaveFileName(self, self.tr('Save file'), '.', self.tr('Log files (*.log *.LOG)')) if fileName == '': return if not fileName.lower().endswith('.log'): fileName += '.log' ProcessingLog.saveLog(fileName) def fillTree(self): self.tree.clear() entries = ProcessingLog.getLogEntries() groupItem = QTreeWidgetItem() groupItem.setText(0, 'ALGORITHM') groupItem.setIcon(0, self.groupIcon) for entry in entries: item = TreeLogEntryItem(entry, True) item.setIcon(0, self.keyIcon) groupItem.insertChild(0, item) self.tree.addTopLevelItem(groupItem) def executeAlgorithm(self): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): if item.isAlg: script = 'import processing\n' script += item.entry.text.replace('run(', 'runAndLoadResults(') exec(script) def changeText(self): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): self.text.setText(item.entry.text.replace('|', '\n')) def createTest(self): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): if item.isAlg: TestTools.createTest(item.entry.text) def showPopupMenu(self, point): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): if item.isAlg: popupmenu = QMenu() createTestAction = QAction(self.tr('Create test'), self.tree) createTestAction.triggered.connect(self.createTest) popupmenu.addAction(createTestAction) popupmenu.exec_(self.tree.mapToGlobal(point))
def __init__(self, text): QPushButton.__init__(self) self.setText(text) buttons_size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setSizePolicy(buttons_size_policy) self.setMaximumSize(QSize(30, 30))
class FixedTableDialog(BASE, WIDGET): def __init__(self, param, table): """ Constructor for FixedTableDialog :param param: linked processing parameter :param table: initial table contents - squashed to 1-dimensional! """ super().__init__(None) self.setupUi(self) QgsGui.instance().enableAutoGeometryRestore(self) self.tblView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.param = param self.rettable = None # Additional buttons self.btnAdd = QPushButton(self.tr('Add row')) self.buttonBox.addButton(self.btnAdd, QDialogButtonBox.ActionRole) self.btnRemove = QPushButton(self.tr('Remove row(s)')) self.buttonBox.addButton(self.btnRemove, QDialogButtonBox.ActionRole) self.btnRemoveAll = QPushButton(self.tr('Remove all')) self.buttonBox.addButton(self.btnRemoveAll, QDialogButtonBox.ActionRole) self.btnAdd.clicked.connect(self.addRow) self.btnRemove.clicked.connect(lambda: self.removeRows()) self.btnRemoveAll.clicked.connect(lambda: self.removeRows(True)) if self.param.hasFixedNumberRows(): self.btnAdd.setEnabled(False) self.btnRemove.setEnabled(False) self.btnRemoveAll.setEnabled(False) self.populateTable(table) def populateTable(self, table): cols = len(self.param.headers()) rows = len(table) // cols model = QStandardItemModel(rows, cols) # Set headers model.setHorizontalHeaderLabels(self.param.headers()) # Populate table for row in range(rows): for col in range(cols): item = QStandardItem(str(table[row * cols + col])) model.setItem(row, col, item) self.tblView.setModel(model) def accept(self): cols = self.tblView.model().columnCount() rows = self.tblView.model().rowCount() # Table MUST BE 1-dimensional to match core QgsProcessingParameterMatrix expectations self.rettable = [] for row in range(rows): for col in range(cols): self.rettable.append(str(self.tblView.model().item(row, col).text())) QDialog.accept(self) def reject(self): QDialog.reject(self) def removeRows(self, removeAll=False): if removeAll: self.tblView.model().clear() self.tblView.model().setHorizontalHeaderLabels(self.param.headers()) else: indexes = sorted(self.tblView.selectionModel().selectedRows()) self.tblView.setUpdatesEnabled(False) for i in reversed(indexes): self.tblView.model().removeRows(i.row(), 1) self.tblView.setUpdatesEnabled(True) def addRow(self): items = [QStandardItem('0') for i in range(self.tblView.model().columnCount())] self.tblView.model().appendRow(items)
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue 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]') label = QLabel(desc) self.labels[param.name()] = label wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget tooltip = param.description() label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name()] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
class HistoryDialog(BASE, WIDGET): def __init__(self): super(HistoryDialog, self).__init__(None) self.setupUi(self) self.groupIcon = QIcon() self.groupIcon.addPixmap(self.style().standardPixmap( QStyle.SP_DirClosedIcon), QIcon.Normal, QIcon.Off) self.groupIcon.addPixmap(self.style().standardPixmap( QStyle.SP_DirOpenIcon), QIcon.Normal, QIcon.On) self.keyIcon = QIcon() self.keyIcon.addPixmap(self.style().standardPixmap(QStyle.SP_FileIcon)) self.clearButton = QPushButton(self.tr('Clear')) self.clearButton.setToolTip(self.tr('Clear history')) self.buttonBox.addButton(self.clearButton, QDialogButtonBox.ActionRole) self.saveButton = QPushButton(self.tr('Save As...')) self.saveButton.setToolTip(self.tr('Save history')) self.buttonBox.addButton(self.saveButton, QDialogButtonBox.ActionRole) self.tree.doubleClicked.connect(self.executeAlgorithm) self.tree.currentItemChanged.connect(self.changeText) self.clearButton.clicked.connect(self.clearLog) self.saveButton.clicked.connect(self.saveLog) self.tree.setContextMenuPolicy(Qt.CustomContextMenu) self.tree.customContextMenuRequested.connect(self.showPopupMenu) self.fillTree() def clearLog(self): reply = QMessageBox.question(self, self.tr('Confirmation'), self.tr('Are you sure you want to clear the history?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) if reply == QMessageBox.Yes: ProcessingLog.clearLog() self.fillTree() def saveLog(self): fileName, filter = QFileDialog.getSaveFileName(self, self.tr('Save file'), '.', self.tr('Log files (*.log *.LOG)')) if fileName == '': return if not fileName.lower().endswith('.log'): fileName += '.log' ProcessingLog.saveLog(fileName) def fillTree(self): self.tree.clear() entries = ProcessingLog.getLogEntries() groupItem = QTreeWidgetItem() groupItem.setText(0, 'ALGORITHM') groupItem.setIcon(0, self.groupIcon) for entry in entries: item = TreeLogEntryItem(entry, True) item.setIcon(0, self.keyIcon) groupItem.insertChild(0, item) self.tree.addTopLevelItem(groupItem) def executeAlgorithm(self): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): if item.isAlg: script = 'import processing\n' script += 'from qgis.core import QgsProcessingOutputLayerDefinition, QgsProcessingFeatureSourceDefinition\n' script += item.entry.text.replace('processing.run(', 'processing.runAndLoadResults(') exec(script) def changeText(self): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): self.text.setText(item.entry.text.replace('|', '\n')) def createTest(self): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): if item.isAlg: TestTools.createTest(item.entry.text) def showPopupMenu(self, point): item = self.tree.currentItem() if isinstance(item, TreeLogEntryItem): if item.isAlg: popupmenu = QMenu() createTestAction = QAction(self.tr('Create test'), self.tree) createTestAction.triggered.connect(self.createTest) popupmenu.addAction(createTestAction) popupmenu.exec_(self.tree.mapToGlobal(point))
class FixedTableDialog(BASE, WIDGET): def __init__(self, param, table): super(FixedTableDialog, self).__init__(None) self.setupUi(self) self.tblView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.param = param self.rettable = None # Additional buttons self.btnAdd = QPushButton(self.tr('Add row')) self.buttonBox.addButton(self.btnAdd, QDialogButtonBox.ActionRole) self.btnRemove = QPushButton(self.tr('Remove row(s)')) self.buttonBox.addButton(self.btnRemove, QDialogButtonBox.ActionRole) self.btnRemoveAll = QPushButton(self.tr('Remove all')) self.buttonBox.addButton(self.btnRemoveAll, QDialogButtonBox.ActionRole) self.btnAdd.clicked.connect(self.addRow) self.btnRemove.clicked.connect(lambda: self.removeRows()) self.btnRemoveAll.clicked.connect(lambda: self.removeRows(True)) if self.param.fixedNumOfRows: self.btnAdd.setEnabled(False) self.btnRemove.setEnabled(False) self.btnRemoveAll.setEnabled(False) self.populateTable(table) def populateTable(self, table): cols = len(self.param.cols) rows = len(table) model = QStandardItemModel(rows, cols) # Set headers model.setHorizontalHeaderLabels(self.param.cols) # Populate table for i in range(rows): for j in range(cols): item = QStandardItem(table[i][j]) model.setItem(i, j, item) self.tblView.setModel(model) def accept(self): cols = self.tblView.model().columnCount() rows = self.tblView.model().rowCount() self.rettable = [] for i in range(rows): self.rettable.append(list()) for j in range(cols): self.rettable[i].append(str(self.tblView.model().item(i, j).text())) QDialog.accept(self) def reject(self): QDialog.reject(self) def removeRows(self, removeAll=False): if removeAll: self.tblView.model().clear() self.tblView.model().setHorizontalHeaderLabels(self.param.cols) else: indexes = sorted(self.tblView.selectionModel().selectedRows()) self.tblView.setUpdatesEnabled(False) for i in reversed(indexes): self.tblView.model().removeRows(i.row(), 1) self.tblView.setUpdatesEnabled(True) def addRow(self): items = [QStandardItem('0') for i in range(self.tblView.model().columnCount())] self.tblView.model().appendRow(items)
class BatchOutputSelectionPanel(QWidget): def __init__(self, output, alg, row, col, panel): super(BatchOutputSelectionPanel, self).__init__(None) self.alg = alg self.row = row self.col = col self.output = output self.panel = panel self.table = self.panel.tblParameters self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(2) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setText('') self.text.setMinimumWidth(300) self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText('…') self.pushButton.clicked.connect(self.showSelectionDialog) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout) def showSelectionDialog(self): if isinstance(self.output, QgsProcessingParameterFolderDestination): self.selectDirectory() return filefilter = getFileFilter(self.output) settings = QgsSettings() if settings.contains('/Processing/LastBatchOutputPath'): path = str(settings.value('/Processing/LastBatchOutputPath')) else: path = '' filename, selectedFileFilter = QFileDialog.getSaveFileName(self, self.tr('Save File'), path, filefilter) if filename: if not filename.lower().endswith( tuple(re.findall("\\*(\\.[a-z]{1,10})", filefilter))): ext = re.search("\\*(\\.[a-z]{1,10})", selectedFileFilter) if ext: filename += ext.group(1) settings.setValue('/Processing/LastBatchOutputPath', os.path.dirname(filename)) dlg = AutofillDialog(self.alg) dlg.exec_() if dlg.mode is not None: try: if dlg.mode == AutofillDialog.DO_NOT_AUTOFILL: self.table.cellWidget(self.row, self.col).setValue(filename) elif dlg.mode == AutofillDialog.FILL_WITH_NUMBERS: n = self.table.rowCount() - self.row for i in range(n): name = filename[:filename.rfind('.')] \ + str(i + 1) + filename[filename.rfind('.'):] self.table.cellWidget(i + self.row, self.col).setValue(name) elif dlg.mode == AutofillDialog.FILL_WITH_PARAMETER: n = self.table.rowCount() - self.row for i in range(n): widget = self.table.cellWidget(i + self.row, dlg.param_index) param = self.alg.parameterDefinitions()[dlg.param_index] if isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers)): v = widget.value() if isinstance(v, QgsMapLayer): s = v.name() else: s = os.path.basename(v) s = os.path.splitext(s)[0] elif isinstance(param, QgsProcessingParameterBoolean): s = str(widget.currentIndex() == 0) elif isinstance(param, QgsProcessingParameterEnum): s = str(widget.currentText()) elif isinstance(param, QgsProcessingParameterMatrix): s = str(widget.table) else: s = str(widget.text()) name = filename[:filename.rfind('.')] + s \ + filename[filename.rfind('.'):] self.table.cellWidget(i + self.row, self.col).setValue(name) except: pass def selectDirectory(self): settings = QgsSettings() if settings.contains('/Processing/LastBatchOutputPath'): lastDir = str(settings.value('/Processing/LastBatchOutputPath')) else: lastDir = '' dirName = QFileDialog.getExistingDirectory(self, self.tr('Output Directory'), lastDir, QFileDialog.ShowDirsOnly) if dirName: self.table.cellWidget(self.row, self.col).setValue(dirName) settings.setValue('/Processing/LastBatchOutputPath', dirName) def setValue(self, text): return self.text.setText(text) def getValue(self): return str(self.text.text())
class BatchInputSelectionPanel(QWidget): valueChanged = pyqtSignal() def __init__(self, param, row, col, dialog): super(BatchInputSelectionPanel, self).__init__(None) self.param = param self.dialog = dialog self.row = row self.col = col self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(0) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setObjectName('text') self.text.setMinimumWidth(300) self.setValue('') self.text.editingFinished.connect(self.textEditingFinished) self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText('...') self.pushButton.clicked.connect(self.showPopupMenu) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout) def _panel(self): return self.dialog.mainWidget def _table(self): return self._panel().tblParameters def showPopupMenu(self): popupmenu = QMenu() if not (isinstance(self.param, ParameterMultipleInput) and self.param.datatype == dataobjects.TYPE_FILE): selectLayerAction = QAction( self.tr('Select from open layers'), self.pushButton) selectLayerAction.triggered.connect(self.showLayerSelectionDialog) popupmenu.addAction(selectLayerAction) selectFileAction = QAction( self.tr('Select from filesystem'), self.pushButton) selectFileAction.triggered.connect(self.showFileSelectionDialog) popupmenu.addAction(selectFileAction) popupmenu.exec_(QCursor.pos()) def showLayerSelectionDialog(self): if (isinstance(self.param, ParameterRaster) or (isinstance(self.param, ParameterMultipleInput) and self.param.datatype == dataobjects.TYPE_RASTER)): layers = dataobjects.getRasterLayers() elif isinstance(self.param, ParameterTable): layers = dataobjects.getTables() else: if isinstance(self.param, ParameterVector): datatype = self.param.datatype else: datatype = [self.param.datatype] layers = dataobjects.getVectorLayers(datatype) dlg = MultipleInputDialog([layer.name() for layer in layers]) dlg.exec_() if dlg.selectedoptions is not None: selected = dlg.selectedoptions if len(selected) == 1: self.setValue(layers[selected[0]]) else: if isinstance(self.param, ParameterMultipleInput): self.text.setText(';'.join(layers[idx].name() for idx in selected)) else: rowdif = len(selected) - (self._table().rowCount() - self.row) for i in range(rowdif): self._panel().addRow() for i, layeridx in enumerate(selected): self._table().cellWidget(i + self.row, self.col).setValue(layers[layeridx]) def showFileSelectionDialog(self): settings = QSettings() text = str(self.text.text()) if os.path.isdir(text): path = text elif os.path.isdir(os.path.dirname(text)): path = os.path.dirname(text) elif settings.contains('/Processing/LastInputPath'): path = str(settings.value('/Processing/LastInputPath')) else: path = '' ret, selected_filter = QFileDialog.getOpenFileNames(self, self.tr('Open file'), path, self.tr('All files(*.*);;') + self.param.getFileFilter()) if ret: files = list(ret) settings.setValue('/Processing/LastInputPath', os.path.dirname(str(files[0]))) for i, filename in enumerate(files): files[i] = dataobjects.getRasterSublayer(filename, self.param) if len(files) == 1: self.text.setText(files[0]) self.textEditingFinished() else: if isinstance(self.param, ParameterMultipleInput): self.text.setText(';'.join(str(f) for f in files)) else: rowdif = len(files) - (self._table().rowCount() - self.row) for i in range(rowdif): self._panel().addRow() for i, f in enumerate(files): self._table().cellWidget(i + self.row, self.col).setValue(f) def textEditingFinished(self): self._value = self.text.text() self.valueChanged.emit() def value(self): return self._value def setValue(self, value): self._value = value if isinstance(value, QgsMapLayer): self.text.setText(value.name()) else: # should be basestring self.text.setText(value) self.valueChanged.emit()
class ModelerParametersDialog(QDialog): ENTER_NAME = '[Enter name if this is a final result]' NOT_SELECTED = '[Not selected]' USE_MIN_COVERING_EXTENT = '[Use min covering extent]' def __init__(self, alg, model, algName=None): QDialog.__init__(self) self.setModal(True) # The algorithm to define in this dialog. It is an instance of QgsProcessingModelAlgorithm self._alg = alg # The model this algorithm is going to be added to self.model = model # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self.childId = algName self.setupUi() self.params = None settings = QgsSettings() self.restoreGeometry( settings.value("/Processing/modelParametersDialogGeometry", QByteArray())) def closeEvent(self, event): settings = QgsSettings() settings.setValue("/Processing/modelParametersDialogGeometry", self.saveGeometry()) super(ModelerParametersDialog, self).closeEvent(event) def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination( ) or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue 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]') label = QLabel(desc) self.labels[param.name()] = label wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget tooltip = param.description() label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.flags( ) & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name()] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values())) def getAvailableDependencies(self): # spellok if self.childId is None: dependent = [] else: dependent = list(self.model.dependentChildAlgorithms(self.childId)) dependent.append(self.childId) opts = [] for alg in list(self.model.childAlgorithms().values()): if alg.childId() not in dependent: opts.append(alg) return opts def getDependenciesPanel(self): return MultipleInputPanel([ alg.description() for alg in self.getAvailableDependencies() ]) # spellok def showAdvancedParametersClicked(self): self.showAdvanced = not self.showAdvanced if self.showAdvanced: self.advancedButton.setText(self.tr('Hide advanced parameters')) else: self.advancedButton.setText(self.tr('Show advanced parameters')) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.labels[param.name()].setVisible(self.showAdvanced) self.widgets[param.name()].setVisible(self.showAdvanced) def getAvailableValuesOfType(self, paramType, outTypes=[], dataTypes=[]): # upgrade paramType to list if paramType is None: paramType = [] elif not isinstance(paramType, (tuple, list)): paramType = [paramType] if outTypes is None: outTypes = [] elif not isinstance(outTypes, (tuple, list)): outTypes = [outTypes] return self.model.availableSourcesForChild(self.childId, [ p.typeName() for p in paramType if issubclass(p, QgsProcessingParameterDefinition) ], [ o.typeName() for o in outTypes if issubclass(o, QgsProcessingOutputDefinition) ], dataTypes) def resolveValueDescription(self, value): if isinstance(value, QgsProcessingModelChildParameterSource): if value.source( ) == QgsProcessingModelChildParameterSource.StaticValue: return value.staticValue() elif value.source( ) == QgsProcessingModelChildParameterSource.ModelParameter: return self.model.parameterDefinition( value.parameterName()).description() elif value.source( ) == QgsProcessingModelChildParameterSource.ChildOutput: alg = self.model.childAlgorithm(value.outputChildId()) return self.tr("'{0}' from algorithm '{1}'").format( alg.algorithm().outputDefinition( value.outputName()).description(), alg.description()) return value def setPreviousValues(self): if self.childId is not None: alg = self.model.childAlgorithm(self.childId) self.descriptionBox.setText(alg.description()) for param in alg.algorithm().parameterDefinitions(): if param.isDestination() or param.flags( ) & QgsProcessingParameterDefinition.FlagHidden: continue value = None if param.name() in alg.parameterSources(): value = alg.parameterSources()[param.name()] if isinstance(value, list) and len(value) == 1: value = value[0] elif isinstance(value, list) and len(value) == 0: value = None if value is None: value = param.defaultValue() if isinstance( value, QgsProcessingModelChildParameterSource ) and value.source( ) == QgsProcessingModelChildParameterSource.StaticValue: value = value.staticValue() self.wrappers[param.name()].setValue(value) for name, out in list(alg.modelOutputs().items()): if out.childOutputName() in self.valueItems: self.valueItems[out.childOutputName()].setText(out.name()) selected = [] dependencies = self.getAvailableDependencies() # spellok for idx, dependency in enumerate(dependencies): if dependency.childId() in alg.dependencies(): selected.append(idx) self.dependenciesPanel.setSelectedItems(selected) def createAlgorithm(self): alg = QgsProcessingModelChildAlgorithm(self._alg.id()) if not self.childId: alg.generateChildId(self.model) else: alg.setChildId(self.childId) alg.setDescription(self.descriptionBox.text()) for param in self._alg.parameterDefinitions(): if param.isDestination( ) or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue try: val = self.wrappers[param.name()].value() except InvalidParameterValue: self.bar.pushMessage( self.tr("Error"), self.tr( "Wrong or missing value for parameter '{}'").format( param.description()), level=QgsMessageBar.WARNING) return None if isinstance(val, QgsProcessingModelChildParameterSource): val = [val] elif not (isinstance(val, list) and all([ isinstance(subval, QgsProcessingModelChildParameterSource) for subval in val ])): val = [ QgsProcessingModelChildParameterSource.fromStaticValue(val) ] for subval in val: if (isinstance(subval, QgsProcessingModelChildParameterSource) and subval.source() == QgsProcessingModelChildParameterSource.StaticValue and not param.checkValueIsAcceptable(subval.staticValue())) \ or (subval is None and not param.flags() & QgsProcessingParameterDefinition.FlagOptional): self.bar.pushMessage( self.tr("Error"), self.tr("Wrong or missing value for parameter '{}'" ).format(param.description()), level=QgsMessageBar.WARNING) return None alg.addParameterSources(param.name(), val) outputs = {} for dest in self._alg.destinationParameterDefinitions(): if not dest.flags() & QgsProcessingParameterDefinition.FlagHidden: name = str(self.valueItems[dest.name()].text()) if name.strip( ) != '' and name != ModelerParametersDialog.ENTER_NAME: output = QgsProcessingModelOutput(name, name) output.setChildId(alg.childId()) output.setChildOutputName(dest.name()) outputs[name] = output alg.setModelOutputs(outputs) selectedOptions = self.dependenciesPanel.selectedoptions availableDependencies = self.getAvailableDependencies() # spellok dep_ids = [] for selected in selectedOptions: dep_ids.append( availableDependencies[selected].childId()) # spellok alg.setDependencies(dep_ids) #try: # self._alg.processBeforeAddingToModeler(alg, self.model) #except: # pass return alg def okPressed(self): alg = self.createAlgorithm() if alg is not None: self.accept() def cancelPressed(self): self.reject() def openHelp(self): algHelp = self._alg.helpUrl() if not algHelp: algHelp = QgsHelp.helpUrl("processing_algs/{}/{}.html{}".format( self._alg.provider().id(), self._alg.groupId(), self._alg.name())).toString() if algHelp not in [None, ""]: webbrowser.open(algHelp)
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination( ) or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue 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]') label = QLabel(desc) self.labels[param.name()] = label wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget tooltip = param.description() label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.flags( ) & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name()] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
class BatchInputSelectionPanel(QWidget): valueChanged = pyqtSignal() def __init__(self, param, row, col, dialog): super(BatchInputSelectionPanel, self).__init__(None) self.param = param self.dialog = dialog self.row = row self.col = col self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(0) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setObjectName('text') self.text.setMinimumWidth(300) self.setValue('') self.text.editingFinished.connect(self.textEditingFinished) self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText('…') self.pushButton.clicked.connect(self.showPopupMenu) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout) def _panel(self): return self.dialog.mainWidget() def _table(self): return self._panel().tblParameters def showPopupMenu(self): popupmenu = QMenu() if not (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType == dataobjects.TYPE_FILE): selectLayerAction = QAction( QCoreApplication.translate('BatchInputSelectionPanel', 'Select from Open Layers…'), self.pushButton) selectLayerAction.triggered.connect(self.showLayerSelectionDialog) popupmenu.addAction(selectLayerAction) selectFileAction = QAction( QCoreApplication.translate('BatchInputSelectionPanel', 'Select from File System…'), self.pushButton) selectFileAction.triggered.connect(self.showFileSelectionDialog) popupmenu.addAction(selectFileAction) popupmenu.exec_(QCursor.pos()) def showLayerSelectionDialog(self): layers = [] if (isinstance(self.param, QgsProcessingParameterRasterLayer) or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType() == QgsProcessing.TypeRaster)): layers = QgsProcessingUtils.compatibleRasterLayers( QgsProject.instance()) elif isinstance(self.param, QgsProcessingParameterVectorLayer): layers = QgsProcessingUtils.compatibleVectorLayers( QgsProject.instance()) elif (isinstance(self.param, QgsProcessingParameterMeshLayer) or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType() == QgsProcessing.TypeMesh)): layers = QgsProcessingUtils.compatibleMeshLayers( QgsProject.instance()) else: datatypes = [QgsProcessing.TypeVectorAnyGeometry] if isinstance(self.param, QgsProcessingParameterFeatureSource): datatypes = self.param.dataTypes() elif isinstance(self.param, QgsProcessingParameterMultipleLayers): datatypes = [self.param.layerType()] if QgsProcessing.TypeVectorAnyGeometry not in datatypes: layers = QgsProcessingUtils.compatibleVectorLayers( QgsProject.instance(), datatypes) else: layers = QgsProcessingUtils.compatibleVectorLayers( QgsProject.instance()) dlg = MultipleInputDialog([layer.name() for layer in layers]) dlg.exec_() def generate_layer_id(layer): # prefer layer name if unique if len([ l for l in layers if l.name().lower() == layer.name().lower() ]) == 1: return layer.name() else: # otherwise fall back to layer id return layer.id() if dlg.selectedoptions is not None: selected = dlg.selectedoptions if len(selected) == 1: self.setValue(generate_layer_id(layers[selected[0]])) else: if isinstance(self.param, QgsProcessingParameterMultipleLayers): self.text.setText(';'.join(layers[idx].id() for idx in selected)) else: rowdif = len(selected) - (self._table().rowCount() - self.row) for i in range(rowdif): self._panel().addRow() for i, layeridx in enumerate(selected): self._table().cellWidget( i + self.row, self.col).setValue( generate_layer_id(layers[layeridx])) def showFileSelectionDialog(self): settings = QgsSettings() text = str(self.text.text()) if os.path.isdir(text): path = text elif os.path.isdir(os.path.dirname(text)): path = os.path.dirname(text) elif settings.contains('/Processing/LastInputPath'): path = str(settings.value('/Processing/LastInputPath')) else: path = '' ret, selected_filter = QFileDialog.getOpenFileNames( self, self.tr('Select Files'), path, getFileFilter(self.param)) if ret: files = list(ret) settings.setValue('/Processing/LastInputPath', os.path.dirname(str(files[0]))) for i, filename in enumerate(files): files[i] = dataobjects.getRasterSublayer(filename, self.param) if len(files) == 1: self.text.setText(files[0]) self.textEditingFinished() else: if isinstance(self.param, QgsProcessingParameterMultipleLayers): self.text.setText(';'.join(str(f) for f in files)) else: rowdif = len(files) - (self._table().rowCount() - self.row) for i in range(rowdif): self._panel().addRow() for i, f in enumerate(files): self._table().cellWidget(i + self.row, self.col).setValue(f) def textEditingFinished(self): self._value = self.text.text() self.valueChanged.emit() def value(self): return self._value if self._value else None def setValue(self, value): self._value = value if isinstance(value, QgsMapLayer): self.text.setText(value.name()) else: # should be basestring self.text.setText(value) self.valueChanged.emit()
def pkWidget(self): """ Instanciates a push button with no border using a key as an icon to be used on rows associated with primary key attributes. """ pb = QPushButton() pb.setIcon(QIcon(':/plugins/DsgTools/icons/key.png')) pb.setFlat(True) pb.blockSignals(True) pb.setObjectName("pkWidget") pb.setText("") return pb
def attributeNameWidget(self, fieldName, isNotNull): """ Retrieves a widget to be used into field table to expose field's name. :param fieldName: (str) fieldName to be exhibited. :param isNotNull: (bool) whether field is a mandatory attribute. :return: (QPushButton) a button ready to be setup to GUI. """ pb = QPushButton() pb.setText(fieldName) pb.setFlat(True) pb.setEnabled(False) if isNotNull: pb.setStyleSheet( "*{ color:rgb(150, 10, 25); "\ "background-color:rgba(255, 88, 116, 1.00); }" ) pb.setToolTip(self.tr("Field cannot be empty")) else: pb.setStyleSheet("color: black;") return pb
class BatchOutputSelectionPanel(QWidget): def __init__(self, output, alg, row, col, panel): super(BatchOutputSelectionPanel, self).__init__(None) self.alg = alg self.row = row self.col = col self.output = output self.panel = panel self.table = self.panel.tblParameters self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(2) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setText('') self.text.setMinimumWidth(300) self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText('…') self.pushButton.clicked.connect(self.showSelectionDialog) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout) def showSelectionDialog(self): if isinstance(self.output, QgsProcessingParameterFolderDestination): self.selectDirectory() return filefilter = getFileFilter(self.output) settings = QgsSettings() if settings.contains('/Processing/LastBatchOutputPath'): path = str(settings.value('/Processing/LastBatchOutputPath')) else: path = '' filename, selectedFileFilter = QFileDialog.getSaveFileName( self, self.tr('Save file'), path, filefilter) if filename: if not filename.lower().endswith( tuple(re.findall("\\*(\\.[a-z]{1,10})", filefilter))): ext = re.search("\\*(\\.[a-z]{1,10})", selectedFileFilter) if ext: filename += ext.group(1) settings.setValue('/Processing/LastBatchOutputPath', os.path.dirname(filename)) dlg = AutofillDialog(self.alg) dlg.exec_() if dlg.mode is not None: try: if dlg.mode == AutofillDialog.DO_NOT_AUTOFILL: self.table.cellWidget(self.row, self.col).setValue(filename) elif dlg.mode == AutofillDialog.FILL_WITH_NUMBERS: n = self.table.rowCount() - self.row for i in range(n): name = filename[:filename.rfind('.')] \ + str(i + 1) + filename[filename.rfind('.'):] self.table.cellWidget(i + self.row, self.col).setValue(name) elif dlg.mode == AutofillDialog.FILL_WITH_PARAMETER: n = self.table.rowCount() - self.row for i in range(n): widget = self.table.cellWidget( i + self.row, dlg.param_index) param = self.alg.parameterDefinitions()[ dlg.param_index] if isinstance( param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers)): v = widget.value() if isinstance(v, QgsMapLayer): s = v.name() else: s = os.path.basename(v) s = os.path.splitext(s)[0] elif isinstance(param, QgsProcessingParameterBoolean): s = str(widget.currentIndex() == 0) elif isinstance(param, QgsProcessingParameterEnum): s = str(widget.currentText()) elif isinstance(param, QgsProcessingParameterMatrix): s = str(widget.table) else: s = str(widget.text()) name = filename[:filename.rfind('.')] + s \ + filename[filename.rfind('.'):] self.table.cellWidget(i + self.row, self.col).setValue(name) except: pass def selectDirectory(self): settings = QgsSettings() if settings.contains('/Processing/LastBatchOutputPath'): lastDir = str(settings.value('/Processing/LastBatchOutputPath')) else: lastDir = '' dirName = QFileDialog.getExistingDirectory(self, self.tr('Select directory'), lastDir, QFileDialog.ShowDirsOnly) if dirName: self.table.cellWidget(self.row, self.col).setValue(dirName) settings.setValue('/Processing/LastBatchOutputPath', dirName) def setValue(self, text): return self.text.setText(text) def getValue(self): return str(self.text.text())
class ModelerParametersDialog(QDialog): ENTER_NAME = '[Enter name if this is a final result]' NOT_SELECTED = '[Not selected]' USE_MIN_COVERING_EXTENT = '[Use min covering extent]' def __init__(self, alg, model, algName=None): QDialog.__init__(self) self.setModal(True) # The algorithm to define in this dialog. It is an instance of GeoAlgorithm self._alg = alg # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class self.alg = None # The model this algorithm is going to be added to self.model = model # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self.childId = algName self.setupUi() self.params = None settings = QgsSettings() self.restoreGeometry(settings.value("/Processing/modelParametersDialogGeometry", QByteArray())) def closeEvent(self, event): settings = QgsSettings() settings.setValue("/Processing/modelParametersDialogGeometry", self.saveGeometry()) super(ModelerParametersDialog, self).closeEvent(event) def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue 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]') label = QLabel(desc) self.labels[param.name()] = label wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget tooltip = param.description() label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name()] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values())) def getAvailableDependencies(self): # spellok if self.childId is None: dependent = [] else: dependent = list(self.model.dependentChildAlgorithms(self.childId)) dependent.append(self.childId) opts = [] for alg in list(self.model.childAlgorithms().values()): if alg.childId() not in dependent: opts.append(alg) return opts def getDependenciesPanel(self): return MultipleInputPanel([alg.description() for alg in self.getAvailableDependencies()]) # spellok def showAdvancedParametersClicked(self): self.showAdvanced = not self.showAdvanced if self.showAdvanced: self.advancedButton.setText(self.tr('Hide advanced parameters')) else: self.advancedButton.setText(self.tr('Show advanced parameters')) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.labels[param.name()].setVisible(self.showAdvanced) self.widgets[param.name()].setVisible(self.showAdvanced) def getAvailableValuesOfType(self, paramType, outTypes=[], dataTypes=[]): # upgrade paramType to list if paramType is None: paramType = [] elif not isinstance(paramType, list): paramType = [paramType] if outTypes is None: outTypes = [] elif not isinstance(outTypes, list): outTypes = [outTypes] return self.model.availableSourcesForChild(self.childId, [p.typeName() for p in paramType if issubclass(p, QgsProcessingParameterDefinition)], [o.typeName() for o in outTypes if issubclass(o, QgsProcessingOutputDefinition)], dataTypes) def resolveValueDescription(self, value): if isinstance(value, QgsProcessingModelChildParameterSource): if value.source() == QgsProcessingModelChildParameterSource.StaticValue: return value.staticValue() elif value.source() == QgsProcessingModelChildParameterSource.ModelParameter: return self.model.parameterDefinition(value.parameterName()).description() elif value.source() == QgsProcessingModelChildParameterSource.ChildOutput: alg = self.model.childAlgorithm(value.outputChildId()) return self.tr("'{0}' from algorithm '{1}'").format( alg.algorithm().outputDefinition(value.outputName()).description(), alg.description()) return value def setPreviousValues(self): if self.childId is not None: alg = self.model.childAlgorithm(self.childId) self.descriptionBox.setText(alg.description()) for param in alg.algorithm().parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue value = None if param.name() in alg.parameterSources(): value = alg.parameterSources()[param.name()] if isinstance(value, list) and len(value) == 1: value = value[0] elif isinstance(value, list) and len(value) == 0: value = None if value is None: value = param.defaultValue() if isinstance(value, QgsProcessingModelChildParameterSource) and value.source() == QgsProcessingModelChildParameterSource.StaticValue: value = value.staticValue() self.wrappers[param.name()].setValue(value) for name, out in list(alg.modelOutputs().items()): if out.childOutputName() in self.valueItems: self.valueItems[out.childOutputName()].setText(out.name()) selected = [] dependencies = self.getAvailableDependencies() # spellok for idx, dependency in enumerate(dependencies): if dependency.childId() in alg.dependencies(): selected.append(idx) self.dependenciesPanel.setSelectedItems(selected) def createAlgorithm(self): alg = QgsProcessingModelChildAlgorithm(self._alg.id()) if not self.childId: alg.generateChildId(self.model) else: alg.setChildId(self.childId) alg.setDescription(self.descriptionBox.text()) for param in self._alg.parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue val = self.wrappers[param.name()].value() if (isinstance(val, QgsProcessingModelChildParameterSource) and val.source() == QgsProcessingModelChildParameterSource.StaticValue and not param.checkValueIsAcceptable( val.staticValue())) \ or (val is None and not param.flags() & QgsProcessingParameterDefinition.FlagOptional): self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description(), level=QgsMessageBar.WARNING) return None if val is None: continue elif isinstance(val, QgsProcessingModelChildParameterSource): alg.addParameterSources(param.name(), [val]) elif isinstance(val, list): alg.addParameterSources(param.name(), val) else: alg.addParameterSources(param.name(), [QgsProcessingModelChildParameterSource.fromStaticValue(val)]) outputs = {} for dest in self._alg.destinationParameterDefinitions(): if not dest.flags() & QgsProcessingParameterDefinition.FlagHidden: name = str(self.valueItems[dest.name()].text()) if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME: output = QgsProcessingModelOutput(name, name) output.setChildId(alg.childId()) output.setChildOutputName(dest.name()) outputs[name] = output alg.setModelOutputs(outputs) selectedOptions = self.dependenciesPanel.selectedoptions availableDependencies = self.getAvailableDependencies() # spellok dep_ids = [] for selected in selectedOptions: dep_ids.append(availableDependencies[selected].childId()) # spellok alg.setDependencies(dep_ids) try: self._alg.processBeforeAddingToModeler(alg, self.model) except: pass return alg def okPressed(self): self.alg = self.createAlgorithm() if self.alg is not None: self.close() def cancelPressed(self): self.alg = None self.close() def openHelp(self): algHelp = self._alg.help() if algHelp is not None: webbrowser.open(algHelp)
class ModelerParametersDialog(QDialog): def __init__(self, alg, model, algName=None, configuration=None): QDialog.__init__(self) self.setModal(True) self._alg = alg # The algorithm to define in this dialog. It is an instance of QgsProcessingAlgorithm self.model = model # The model this algorithm is going to be added to. It is an instance of QgsProcessingModelAlgorithm self.childId = algName # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self.configuration = configuration self.context = createContext() self.widget_labels = {} class ContextGenerator(QgsProcessingContextGenerator): def __init__(self, context): super().__init__() self.processing_context = context def processingContext(self): return self.processing_context self.context_generator = ContextGenerator(self.context) self.setupUi() self.params = None settings = QgsSettings() self.restoreGeometry(settings.value("/Processing/modelParametersDialogGeometry", QByteArray())) def closeEvent(self, event): settings = QgsSettings() settings.setValue("/Processing/modelParametersDialogGeometry", self.saveGeometry()) super(ModelerParametersDialog, self).closeEvent(event) def setupUi(self): self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.algorithmItem = None self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) widget_context = QgsProcessingParameterWidgetContext() widget_context.setProject(QgsProject.instance()) if iface is not None: widget_context.setMapCanvas(iface.mapCanvas()) widget_context.setModel(self.model) widget_context.setModelChildAlgorithmId(self.childId) self.algorithmItem = QgsGui.instance().processingGuiRegistry().algorithmConfigurationWidget(self._alg) if self.algorithmItem: self.algorithmItem.setWidgetContext(widget_context) self.algorithmItem.registerProcessingContextGenerator(self.context_generator) if self.configuration: self.algorithmItem.setConfiguration(self.configuration) self.verticalLayout.addWidget(self.algorithmItem) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper wrapper.setWidgetContext(widget_context) wrapper.registerProcessingContextGenerator(self.context_generator) if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): widget = wrapper else: widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): label = wrapper.createLabel() else: tooltip = param.description() widget.setToolTip(tooltip) label = wrapper.label self.widget_labels[param.name()] = label if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(self.tr('[Enter name if this is a final result]')) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self) def getAvailableDependencies(self): # spellok if self.childId is None: dependent = [] else: dependent = list(self.model.dependentChildAlgorithms(self.childId)) dependent.append(self.childId) opts = [] for alg in list(self.model.childAlgorithms().values()): if alg.childId() not in dependent: opts.append(alg) return opts def getDependenciesPanel(self): return MultipleInputPanel([alg.description() for alg in self.getAvailableDependencies()]) # spellok def showAdvancedParametersClicked(self): self.showAdvanced = not self.showAdvanced if self.showAdvanced: self.advancedButton.setText(self.tr('Hide advanced parameters')) else: self.advancedButton.setText(self.tr('Show advanced parameters')) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: wrapper = self.wrappers[param.name()] if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): wrapper.setVisible(self.showAdvanced) else: wrapper.widget.setVisible(self.showAdvanced) self.widget_labels[param.name()].setVisible(self.showAdvanced) def getAvailableValuesOfType(self, paramType, outTypes=[], dataTypes=[]): # upgrade paramType to list if paramType is None: paramType = [] elif not isinstance(paramType, (tuple, list)): paramType = [paramType] if outTypes is None: outTypes = [] elif not isinstance(outTypes, (tuple, list)): outTypes = [outTypes] return self.model.availableSourcesForChild(self.childId, [p.typeName() for p in paramType if issubclass(p, QgsProcessingParameterDefinition)], [o.typeName() for o in outTypes if issubclass(o, QgsProcessingOutputDefinition)], dataTypes) def resolveValueDescription(self, value): if isinstance(value, QgsProcessingModelChildParameterSource): if value.source() == QgsProcessingModelChildParameterSource.StaticValue: return value.staticValue() elif value.source() == QgsProcessingModelChildParameterSource.ModelParameter: return self.model.parameterDefinition(value.parameterName()).description() elif value.source() == QgsProcessingModelChildParameterSource.ChildOutput: alg = self.model.childAlgorithm(value.outputChildId()) return self.tr("'{0}' from algorithm '{1}'").format( alg.algorithm().outputDefinition(value.outputName()).description(), alg.description()) return value def setPreviousValues(self): if self.childId is not None: alg = self.model.childAlgorithm(self.childId) self.descriptionBox.setText(alg.description()) for param in alg.algorithm().parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue value = None if param.name() in alg.parameterSources(): value = alg.parameterSources()[param.name()] if isinstance(value, list) and len(value) == 1: value = value[0] elif isinstance(value, list) and len(value) == 0: value = None wrapper = self.wrappers[param.name()] if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): if value is None: value = QgsProcessingModelChildParameterSource.fromStaticValue(param.defaultValue()) wrapper.setWidgetValue(value) else: if value is None: value = param.defaultValue() if isinstance(value, QgsProcessingModelChildParameterSource) and value.source() == QgsProcessingModelChildParameterSource.StaticValue: value = value.staticValue() wrapper.setValue(value) for name, out in alg.modelOutputs().items(): if out.childOutputName() in self.valueItems: self.valueItems[out.childOutputName()].setText(out.name()) selected = [] dependencies = self.getAvailableDependencies() # spellok for idx, dependency in enumerate(dependencies): if dependency.childId() in alg.dependencies(): selected.append(idx) self.dependenciesPanel.setSelectedItems(selected) def createAlgorithm(self): alg = QgsProcessingModelChildAlgorithm(self._alg.id()) if not self.childId: alg.generateChildId(self.model) else: alg.setChildId(self.childId) alg.setDescription(self.descriptionBox.text()) if self.algorithmItem: alg.setConfiguration(self.algorithmItem.configuration()) self._alg = alg.algorithm().create(self.algorithmItem.configuration()) for param in self._alg.parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue try: wrapper = self.wrappers[param.name()] if issubclass(wrapper.__class__, WidgetWrapper): val = wrapper.value() elif issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): val = wrapper.value() else: val = wrapper.parameterValue() except InvalidParameterValue: self.bar.pushMessage(self.tr("Error"), self.tr("Wrong or missing value for parameter '{}'").format(param.description()), level=Qgis.Warning) return None if isinstance(val, QgsProcessingModelChildParameterSource): val = [val] elif not (isinstance(val, list) and all( [isinstance(subval, QgsProcessingModelChildParameterSource) for subval in val])): val = [QgsProcessingModelChildParameterSource.fromStaticValue(val)] for subval in val: if (isinstance(subval, QgsProcessingModelChildParameterSource) and subval.source() == QgsProcessingModelChildParameterSource.StaticValue and not param.checkValueIsAcceptable(subval.staticValue())) \ or (subval is None and not param.flags() & QgsProcessingParameterDefinition.FlagOptional): self.bar.pushMessage(self.tr("Error"), self.tr("Wrong or missing value for parameter '{}'").format( param.description()), level=Qgis.Warning) return None alg.addParameterSources(param.name(), val) outputs = {} for dest in self._alg.destinationParameterDefinitions(): if not dest.flags() & QgsProcessingParameterDefinition.FlagHidden: name = self.valueItems[dest.name()].text() if name.strip() != '': output = QgsProcessingModelOutput(name, name) output.setChildId(alg.childId()) output.setChildOutputName(dest.name()) outputs[name] = output if dest.flags() & QgsProcessingParameterDefinition.FlagIsModelOutput: if dest.name() not in outputs: output = QgsProcessingModelOutput(dest.name(), dest.name()) output.setChildId(alg.childId()) output.setChildOutputName(dest.name()) outputs[dest.name()] = output alg.setModelOutputs(outputs) selectedOptions = self.dependenciesPanel.selectedoptions availableDependencies = self.getAvailableDependencies() # spellok dep_ids = [] for selected in selectedOptions: dep_ids.append(availableDependencies[selected].childId()) # spellok alg.setDependencies(dep_ids) #try: # self._alg.processBeforeAddingToModeler(alg, self.model) #except: # pass return alg def okPressed(self): alg = self.createAlgorithm() if alg is not None: self.accept() def cancelPressed(self): self.reject() def openHelp(self): algHelp = self._alg.helpUrl() if not algHelp: algHelp = QgsHelp.helpUrl("processing_algs/{}/{}.html#{}".format( self._alg.provider().helpId(), self._alg.groupId(), "{}{}".format(self._alg.provider().helpId(), self._alg.name()))).toString() if algHelp not in [None, ""]: webbrowser.open(algHelp)
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.name) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') if param.optional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name] = label wrapper = param.wrapper(self) self.wrappers[param.name] = wrapper widget = wrapper.widget self.valueItems[param.name] = widget if param.name in list(tooltips.keys()): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.name) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.txtHelp = QTextBrowser() html = None isText, algHelp = self._alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr( '<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) self.tabWidget.addTab(self.txtHelp, 'Help') self.reply = QgsNetworkAccessManager.instance().get( QNetworkRequest(algHelp)) self.reply.finished.connect(self.requestFinished) except: pass self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
def __init__(self, iface, parent=None, qsetting=''): """Constructor for the dialog. :param iface: A Quantum GIS QgisAppInterface instance. :type iface: QgisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param qsetting: String to specify the QSettings. By default, use empty string. :type qsetting: str """ QDialog.__init__(self, parent) self.setupUi(self) icon = resources_path('img', 'icons', 'configure-inasafe.svg') self.setWindowIcon(QIcon(icon)) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent if qsetting: self.settings = QSettings(qsetting) else: self.settings = QSettings() # InaSAFE default values self.default_value_parameters = [] self.default_value_parameter_containers = [] # Flag for restore default values self.is_restore_default = False # List of setting key and control self.boolean_settings = { 'visibleLayersOnlyFlag': self.cbxVisibleLayersOnly, 'set_layer_from_title_flag': self.cbxSetLayerNameFromTitle, 'setZoomToImpactFlag': self.cbxZoomToImpact, 'set_show_only_impact_on_report': self.cbx_show_only_impact, 'print_atlas_report': self.cbx_print_atlas_report, 'setHideExposureFlag': self.cbxHideExposure, 'useSelectedFeaturesOnly': self.cbxUseSelectedFeaturesOnly, 'useSentry': self.cbxUseSentry, 'template_warning_verbose': self.template_warning_checkbox, 'showOrganisationLogoInDockFlag': self.organisation_on_dock_checkbox, 'developer_mode': self.cbxDevMode, 'generate_report': self.checkbox_generate_reports, 'memory_profile': self.check_box_memory, 'always_show_welcome_message': self.welcome_message_check_box } self.text_settings = { 'keywordCachePath': self.leKeywordCachePath, 'ISO19115_ORGANIZATION': self.organisation_line_edit, 'ISO19115_URL': self.website_line_edit, 'ISO19115_EMAIL': self.email_line_edit, 'ISO19115_LICENSE': self.license_line_edit, } # Export and Import button # Export button self.export_button = QPushButton(tr('Export')) # noinspection PyUnresolvedReferences self.export_button.clicked.connect(self.export_setting) self.button_box.addButton( self.export_button, QDialogButtonBox.ActionRole) # Import button self.import_button = QPushButton(tr('Import')) # noinspection PyUnresolvedReferences self.import_button.clicked.connect(self.import_setting) self.button_box.addButton( self.import_button, QDialogButtonBox.ActionRole) # Set up things for context help self.help_button = self.button_box.button(QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Always set first tab to be open, 0-th index self.tabWidget.setCurrentIndex(0) # Hide not implemented group self.grpNotImplemented.hide() self.adjustSize() # Population parameter Tab # Label self.preference_label = QLabel() self.preference_label.setText(tr( 'Please set parameters for each hazard class below. Affected ' 'status and displacement rates selected on this tab are only ' 'applied to exposed populations. ' )) self.preference_layout.addWidget(self.preference_label) # Profile preference widget self.profile_widget = ProfileWidget() self.preference_layout.addWidget(self.profile_widget) # Demographic tab self.demographic_label = QLabel() self.demographic_label.setText(tr( 'Please set the global default demographic ratio below.')) self.default_values_layout.addWidget(self.demographic_label) self.scroll_area = QScrollArea() self.scroll_area.setWidgetResizable(True) self.widget_container = QWidget() self.scroll_area.setWidget(self.widget_container) self.container_layout = QVBoxLayout() self.widget_container.setLayout(self.container_layout) self.default_values_layout.addWidget(self.scroll_area) # Restore state from setting self.restore_state() # Hide checkbox if not developers if not self.cbxDevMode.isChecked(): self.checkbox_generate_reports.hide() # Connections # Check boxes self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer) self.custom_organisation_logo_check_box.toggled.connect( self.toggle_logo_path) # Buttons self.toolKeywordCachePath.clicked.connect(self.open_keyword_cache_path) self.toolUserDirectoryPath.clicked.connect( self.open_user_directory_path) self.toolNorthArrowPath.clicked.connect(self.open_north_arrow_path) self.open_organisation_logo_path_button.clicked.connect( self.open_organisation_logo_path) self.toolReportTemplatePath.clicked.connect( self.open_report_template_path) # Others self.organisation_logo_path_line_edit.textChanged.connect( self.update_logo_preview) self.earthquake_function.currentIndexChanged.connect( self.update_earthquake_info) # Set up listener for restore defaults button self.demographic_restore_defaults = self.button_box_restore_defaults.\ button(QDialogButtonBox.RestoreDefaults) self.demographic_restore_defaults.setText( self.demographic_restore_defaults.text().capitalize()) self.demographic_restore_defaults.setCheckable(True) self.demographic_restore_defaults.clicked.connect( self.restore_defaults_ratio) # Restore button in population parameter tab self.parameter_population_restore_button = \ self.button_box_restore_preference.button( QDialogButtonBox.RestoreDefaults) self.parameter_population_restore_button.setText( self.parameter_population_restore_button.text().capitalize()) self.parameter_population_restore_button.clicked.connect( partial(self.restore_population_parameters, global_default=True)) # TODO: Hide this until behaviour is defined # hide template warning toggle self.template_warning_checkbox.hide() # hide custom template dir toggle self.custom_templates_dir_checkbox.hide() self.splitter_custom_report.hide() # Welcome message self.set_welcome_message()
class FixedTableDialog(BASE, WIDGET): def __init__(self, param, table): super(FixedTableDialog, self).__init__(None) self.setupUi(self) self.tblView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.param = param self.rettable = None # Additional buttons self.btnAdd = QPushButton(self.tr('Add row')) self.buttonBox.addButton(self.btnAdd, QDialogButtonBox.ActionRole) self.btnRemove = QPushButton(self.tr('Remove row(s)')) self.buttonBox.addButton(self.btnRemove, QDialogButtonBox.ActionRole) self.btnRemoveAll = QPushButton(self.tr('Remove all')) self.buttonBox.addButton(self.btnRemoveAll, QDialogButtonBox.ActionRole) self.btnAdd.clicked.connect(self.addRow) self.btnRemove.clicked.connect(lambda: self.removeRows()) self.btnRemoveAll.clicked.connect(lambda: self.removeRows(True)) if self.param.fixedNumOfRows: self.btnAdd.setEnabled(False) self.btnRemove.setEnabled(False) self.btnRemoveAll.setEnabled(False) self.populateTable(table) def populateTable(self, table): cols = len(self.param.cols) rows = len(table) model = QStandardItemModel(rows, cols) # Set headers model.setHorizontalHeaderLabels(self.param.cols) # Populate table for i in range(rows): for j in range(cols): item = QStandardItem(table[i][j]) model.setItem(i, j, item) self.tblView.setModel(model) def accept(self): cols = self.tblView.model().columnCount() rows = self.tblView.model().rowCount() self.rettable = [] for i in range(rows): self.rettable.append(list()) for j in range(cols): self.rettable[i].append( str(self.tblView.model().item(i, j).text())) QDialog.accept(self) def reject(self): QDialog.reject(self) def removeRows(self, removeAll=False): if removeAll: self.tblView.model().clear() self.tblView.model().setHorizontalHeaderLabels(self.param.cols) else: indexes = sorted(self.tblView.selectionModel().selectedRows()) self.tblView.setUpdatesEnabled(False) for i in reversed(indexes): self.tblView.model().removeRows(i.row(), 1) self.tblView.setUpdatesEnabled(True) def addRow(self): items = [ QStandardItem('0') for i in range(self.tblView.model().columnCount()) ] self.tblView.model().appendRow(items)
class ModelerParametersDialog(QDialog): ENTER_NAME = '[Enter name if this is a final result]' NOT_SELECTED = '[Not selected]' USE_MIN_COVERING_EXTENT = '[Use min covering extent]' def __init__(self, alg, model, algName=None): QDialog.__init__(self) self.setModal(True) # The algorithm to define in this dialog. It is an instance of GeoAlgorithm self._alg = alg # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class self.alg = None # The model this algorithm is going to be added to self.model = model # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self._algName = algName self.setupUi() self.params = None def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.name) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') if param.optional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name] = label wrapper = param.wrapper(self) self.wrappers[param.name] = wrapper widget = wrapper.widget if widget: self.valueItems[param.name] = widget if param.name in list(tooltips.keys()): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.name) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.txtHelp = QTextBrowser() html = None isText, algHelp = self._alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr('<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) self.tabWidget.addTab(self.txtHelp, 'Help') self.reply = QgsNetworkAccessManager.instance().get(QNetworkRequest(algHelp)) self.reply.finished.connect(self.requestFinished) except: pass self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values())) def requestFinished(self): """Change the webview HTML content""" reply = self.sender() if reply.error() != QNetworkReply.NoError: html = self.tr('<h2>No help available for this algorithm</h2><p>{}</p>'.format(reply.errorString())) else: html = str(reply.readAll()) reply.deleteLater() self.txtHelp.setHtml(html) def getAvailableDependencies(self): if self._algName is None: dependent = [] else: dependent = self.model.getDependentAlgorithms(self._algName) opts = [] for alg in list(self.model.algs.values()): if alg.name not in dependent: opts.append(alg) return opts def getDependenciesPanel(self): return MultipleInputPanel([alg.description for alg in self.getAvailableDependencies()]) def showAdvancedParametersClicked(self): self.showAdvanced = not self.showAdvanced if self.showAdvanced: self.advancedButton.setText(self.tr('Hide advanced parameters')) else: self.advancedButton.setText(self.tr('Show advanced parameters')) for param in self._alg.parameters: if param.isAdvanced: self.labels[param.name].setVisible(self.showAdvanced) self.widgets[param.name].setVisible(self.showAdvanced) def getAvailableValuesOfType(self, paramType, outType=None, dataType=None): # upgrade paramType to list if type(paramType) is not list: paramType = [paramType] values = [] inputs = self.model.inputs for i in list(inputs.values()): param = i.param for t in paramType: if isinstance(param, t): if dataType is not None: if param.datatype in dataType: values.append(ValueFromInput(param.name)) else: values.append(ValueFromInput(param.name)) break if outType is None: return values if self._algName is None: dependent = [] else: dependent = self.model.getDependentAlgorithms(self._algName) for alg in list(self.model.algs.values()): if alg.name not in dependent: for out in alg.algorithm.outputs: if isinstance(out, outType): if dataType is not None and out.datatype in dataType: values.append(ValueFromOutput(alg.name, out.name)) else: values.append(ValueFromOutput(alg.name, out.name)) return values def resolveValueDescription(self, value): if isinstance(value, ValueFromInput): return self.model.inputs[value.name].param.description else: alg = self.model.algs[value.alg] return self.tr("'%s' from algorithm '%s'") % (alg.algorithm.getOutputFromName(value.output).description, alg.description) def setPreviousValues(self): if self._algName is not None: alg = self.model.algs[self._algName] self.descriptionBox.setText(alg.description) for param in alg.algorithm.parameters: if param.hidden: continue if param.name in alg.params: value = alg.params[param.name] else: value = param.default self.wrappers[param.name].setValue(value) for name, out in list(alg.outputs.items()): self.valueItems[name].setText(out.description) selected = [] dependencies = self.getAvailableDependencies() for idx, dependency in enumerate(dependencies): if dependency.name in alg.dependencies: selected.append(idx) self.dependenciesPanel.setSelectedItems(selected) def createAlgorithm(self): alg = Algorithm(self._alg.commandLineName()) alg.setName(self.model) alg.description = self.descriptionBox.text() params = self._alg.parameters outputs = self._alg.outputs for param in params: if param.hidden: continue if not self.setParamValue(alg, param, self.wrappers[param.name]): self.bar.pushMessage("Error", "Wrong or missing value for parameter '%s'" % param.description, level=QgsMessageBar.WARNING) return None for output in outputs: if not output.hidden: name = str(self.valueItems[output.name].text()) if name.strip() != '' and name != ModelerParametersDialog.ENTER_NAME: alg.outputs[output.name] = ModelerOutput(name) selectedOptions = self.dependenciesPanel.selectedoptions availableDependencies = self.getAvailableDependencies() for selected in selectedOptions: alg.dependencies.append(availableDependencies[selected].name) self._alg.processBeforeAddingToModeler(alg, self.model) return alg def setParamValue(self, alg, param, wrapper): try: if wrapper.widget: value = wrapper.value() alg.params[param.name] = value return True except InvalidParameterValue: return False def okPressed(self): self.alg = self.createAlgorithm() if self.alg is not None: self.close() def cancelPressed(self): self.alg = None self.close()
def setupUi(self): self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.algorithmItem = None self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) widget_context = QgsProcessingParameterWidgetContext() widget_context.setProject(QgsProject.instance()) if iface is not None: widget_context.setMapCanvas(iface.mapCanvas()) widget_context.setModel(self.model) widget_context.setModelChildAlgorithmId(self.childId) self.algorithmItem = QgsGui.instance().processingGuiRegistry( ).algorithmConfigurationWidget(self._alg) if self.algorithmItem: self.algorithmItem.setWidgetContext(widget_context) self.algorithmItem.registerProcessingContextGenerator( self.context_generator) if self.configuration: self.algorithmItem.setConfiguration(self.configuration) self.verticalLayout.addWidget(self.algorithmItem) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination( ) or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper wrapper.setWidgetContext(widget_context) wrapper.registerProcessingContextGenerator(self.context_generator) if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): widget = wrapper else: widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): label = wrapper.createLabel() else: tooltip = param.description() widget.setToolTip(tooltip) label = wrapper.label self.widget_labels[param.name()] = label if param.flags( ) & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText( self.tr('[Enter name if this is a final result]')) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self)
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.name) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') if param.optional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name] = label wrapper = param.wrapper(self) self.wrappers[param.name] = wrapper widget = wrapper.widget if widget: self.valueItems[param.name] = widget if param.name in list(tooltips.keys()): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.name) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.txtHelp = QTextBrowser() html = None isText, algHelp = self._alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr('<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) self.tabWidget.addTab(self.txtHelp, 'Help') self.reply = QgsNetworkAccessManager.instance().get(QNetworkRequest(algHelp)) self.reply.finished.connect(self.requestFinished) except: pass self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
class BatchInputSelectionPanel(QWidget): valueChanged = pyqtSignal() def __init__(self, param, row, col, dialog): super(BatchInputSelectionPanel, self).__init__(None) self.param = param self.dialog = dialog self.row = row self.col = col self.horizontalLayout = QHBoxLayout(self) self.horizontalLayout.setSpacing(0) self.horizontalLayout.setMargin(0) self.text = QLineEdit() self.text.setObjectName('text') self.text.setMinimumWidth(300) self.setValue('') self.text.editingFinished.connect(self.textEditingFinished) self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.horizontalLayout.addWidget(self.text) self.pushButton = QPushButton() self.pushButton.setText('…') self.pushButton.clicked.connect(self.showPopupMenu) self.horizontalLayout.addWidget(self.pushButton) self.setLayout(self.horizontalLayout) def _panel(self): return self.dialog.mainWidget() def _table(self): return self._panel().tblParameters def showPopupMenu(self): popupmenu = QMenu() if not (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType == dataobjects.TYPE_FILE): selectLayerAction = QAction( QCoreApplication.translate('BatchInputSelectionPanel', 'Select from Open Layers…'), self.pushButton) selectLayerAction.triggered.connect(self.showLayerSelectionDialog) popupmenu.addAction(selectLayerAction) selectFileAction = QAction( QCoreApplication.translate('BatchInputSelectionPanel', 'Select from File System…'), self.pushButton) selectFileAction.triggered.connect(self.showFileSelectionDialog) popupmenu.addAction(selectFileAction) popupmenu.exec_(QCursor.pos()) def showLayerSelectionDialog(self): layers = [] if (isinstance(self.param, QgsProcessingParameterRasterLayer) or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType() == QgsProcessing.TypeRaster)): layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance()) elif isinstance(self.param, QgsProcessingParameterVectorLayer): layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance()) elif (isinstance(self.param, QgsProcessingParameterMeshLayer) or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType() == QgsProcessing.TypeMesh)): layers = QgsProcessingUtils.compatibleMeshLayers(QgsProject.instance()) else: datatypes = [QgsProcessing.TypeVectorAnyGeometry] if isinstance(self.param, QgsProcessingParameterFeatureSource): datatypes = self.param.dataTypes() elif isinstance(self.param, QgsProcessingParameterMultipleLayers): datatypes = [self.param.layerType()] if QgsProcessing.TypeVectorAnyGeometry not in datatypes: layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), datatypes) else: layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance()) dlg = MultipleInputDialog([layer.name() for layer in layers]) dlg.exec_() def generate_layer_id(layer): # prefer layer name if unique if len([l for l in layers if l.name().lower() == layer.name().lower()]) == 1: return layer.name() else: # otherwise fall back to layer id return layer.id() if dlg.selectedoptions is not None: selected = dlg.selectedoptions if len(selected) == 1: self.setValue(generate_layer_id(layers[selected[0]])) else: if isinstance(self.param, QgsProcessingParameterMultipleLayers): self.text.setText(';'.join(layers[idx].id() for idx in selected)) else: rowdif = len(selected) - (self._table().rowCount() - self.row) for i in range(rowdif): self._panel().addRow() for i, layeridx in enumerate(selected): self._table().cellWidget(i + self.row, self.col).setValue(generate_layer_id(layers[layeridx])) def showFileSelectionDialog(self): settings = QgsSettings() text = str(self.text.text()) if os.path.isdir(text): path = text elif os.path.isdir(os.path.dirname(text)): path = os.path.dirname(text) elif settings.contains('/Processing/LastInputPath'): path = str(settings.value('/Processing/LastInputPath')) else: path = '' ret, selected_filter = QFileDialog.getOpenFileNames(self, self.tr('Select Files'), path, getFileFilter(self.param)) if ret: files = list(ret) settings.setValue('/Processing/LastInputPath', os.path.dirname(str(files[0]))) for i, filename in enumerate(files): files[i] = dataobjects.getRasterSublayer(filename, self.param) if len(files) == 1: self.text.setText(files[0]) self.textEditingFinished() else: if isinstance(self.param, QgsProcessingParameterMultipleLayers): self.text.setText(';'.join(str(f) for f in files)) else: rowdif = len(files) - (self._table().rowCount() - self.row) for i in range(rowdif): self._panel().addRow() for i, f in enumerate(files): self._table().cellWidget(i + self.row, self.col).setValue(f) def textEditingFinished(self): self._value = self.text.text() self.valueChanged.emit() def value(self): return self._value if self._value else None def setValue(self, value): self._value = value if isinstance(value, QgsMapLayer): self.text.setText(value.name()) else: # should be basestring self.text.setText(value) self.valueChanged.emit()
def __init__(self, interface, toolWindow, options): QDialog.__init__(self, interface.mainWindow()) self.iface = interface self.tool = toolWindow self.options = options self.setWindowTitle("Output Optionen") main_widget = QWidget(self) # Build up gui hbox = QHBoxLayout() saveLabel = QLabel("Speicherpfad") self.pathField = QComboBox() self.pathField.setMinimumWidth(400) self.pathField.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) openButton = QPushButton() openButton.setMaximumSize(QSize(27, 27)) icon = QIcon() iconPath = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'icons', 'icon_open.png') icon.addPixmap(QPixmap(iconPath), QIcon.Normal, QIcon.Off) openButton.setIcon(icon) openButton.setIconSize(QSize(24, 24)) openButton.clicked.connect(self.onOpenDialog) hbox.addWidget(saveLabel) hbox.addWidget(self.pathField) hbox.addWidget(openButton) # Create checkboxes questionLabel = \ QLabel(u"Welche Produkte sollen erzeugt werden?") self.checkBoxReport = QCheckBox(u"Technischer Bericht") self.checkBoxPlot = QCheckBox(u"Diagramm") self.checkBoxGeodata = \ QCheckBox(u"Shape-Daten der StĂĽtzen und Seillinie") self.checkBoxCoords = \ QCheckBox(u"Koordinaten-Tabellen der StĂĽtzen und Seillinie") # Set tick correctly self.checkBoxReport.setChecked(self.options['report']) self.checkBoxPlot.setChecked(self.options['plot']) self.checkBoxGeodata.setChecked(self.options['geodata']) self.checkBoxCoords.setChecked(self.options['coords']) # Create Ok/Cancel Button and connect signal buttonBox = QDialogButtonBox(main_widget) buttonBox.setStandardButtons(QDialogButtonBox.Ok| QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.Apply) buttonBox.rejected.connect(self.Reject) # Layout container = QVBoxLayout(main_widget) container.addLayout(hbox) container.addWidget(QLabel("")) container.addWidget(questionLabel) container.addWidget(self.checkBoxReport) container.addWidget(self.checkBoxPlot) container.addWidget(self.checkBoxGeodata) container.addWidget(self.checkBoxCoords) container.addWidget(buttonBox) container.setAlignment(Qt.AlignLeft) self.setLayout(container)
def startWorker(self): """Initialises and starts the worker thread.""" try: layerindex = self.inputRaster.currentIndex() layerId = self.inputRaster.itemData(layerindex) inputlayer = QgsProject.instance().mapLayer(layerId) #inputlayer = QgsMapLayerRegistry.instance().mapLayer(layerId) if inputlayer is None: self.showError(self.tr('No input layer defined')) return # create a reference to the layer that is being processed # (for use when creating the resulting raster layer) self.thinninglayer = inputlayer self.levels = [] #self.levelsListView.selectAll() #selected = self.levelsListView.selectedIndexes() if self.levelsListView.model().rowCount() == 0: self.showInfo("Levels must be specified!") return for i in range(self.levelsListView.model().rowCount()): levelstring = self.levelsListView.model().item(i).text() #for i in selected: # levelstring = self.levelsListView.model().itemData(i)[0] if self.intband: self.levels.append(int(levelstring)) else: self.levels.append(float(levelstring)) #self.levelsListView.clearSelection() # create a new worker instance worker = Worker(inputlayer, self.levels, self.intband) # configure the QgsMessageBar msgBar = self.iface.messageBar().createMessage( self.tr('Skeletonising'), '') self.aprogressBar = QProgressBar() self.aprogressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) acancelButton = QPushButton() acancelButton.setText(self.CANCEL) acancelButton.clicked.connect(self.killWorker) msgBar.layout().addWidget(self.aprogressBar) msgBar.layout().addWidget(acancelButton) # Has to be popped after the thread has finished (in # workerFinished). self.iface.messageBar().pushWidget(msgBar, Qgis.Info) self.messageBar = msgBar # start the worker in a new thread thread = QThread(self) worker.moveToThread(thread) worker.finished.connect(self.workerFinished) worker.error.connect(self.workerError) worker.status.connect(self.workerInfo) worker.progress.connect(self.progressBar.setValue) worker.progress.connect(self.aprogressBar.setValue) worker.iterprogress.connect(self.iterProgressBar.setValue) thread.started.connect(worker.run) thread.start() self.thread = thread self.worker = worker self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.button_box.button(QDialogButtonBox.Close).setEnabled(False) self.button_box.button(QDialogButtonBox.Cancel).setEnabled(True) except: import traceback self.showError(traceback.format_exc()) else: pass
def fillTreeUsingProviders(self): self.items = {} self.model.clear() self.model.setHorizontalHeaderLabels([self.tr('Setting'), self.tr('Value')]) settings = ProcessingConfig.getSettings() rootItem = self.model.invisibleRootItem() """ Filter 'General', 'Models' and 'Scripts' items """ priorityKeys = [self.tr('General'), self.tr('Models'), self.tr('Scripts')] for group in priorityKeys: groupItem = QStandardItem(group) icon = ProcessingConfig.getGroupIcon(group) groupItem.setIcon(icon) groupItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) rootItem.insertRow(0, [groupItem, emptyItem]) if not group in settings: continue # add menu item only if it has any search matches for setting in settings[group]: if setting.hidden or setting.name.startswith("MENU_"): continue labelItem = QStandardItem(setting.description) labelItem.setIcon(icon) labelItem.setEditable(False) self.items[setting] = SettingItem(setting) groupItem.insertRow(0, [labelItem, self.items[setting]]) """ Filter 'Providers' items """ providersItem = QStandardItem(self.tr('Providers')) icon = QgsApplication.getThemeIcon("/processingAlgorithm.svg") providersItem.setIcon(icon) providersItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) rootItem.insertRow(0, [providersItem, emptyItem]) for group in list(settings.keys()): if group in priorityKeys or group == menusSettingsGroup: continue groupItem = QStandardItem(group) icon = ProcessingConfig.getGroupIcon(group) groupItem.setIcon(icon) groupItem.setEditable(False) for setting in settings[group]: if setting.hidden: continue labelItem = QStandardItem(setting.description) labelItem.setIcon(icon) labelItem.setEditable(False) self.items[setting] = SettingItem(setting) groupItem.insertRow(0, [labelItem, self.items[setting]]) emptyItem = QStandardItem() emptyItem.setEditable(False) providersItem.appendRow([groupItem, emptyItem]) """ Filter 'Menus' items """ self.menusItem = QStandardItem(self.tr('Menus')) icon = QIcon(os.path.join(pluginPath, 'images', 'menu.png')) self.menusItem.setIcon(icon) self.menusItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) rootItem.insertRow(0, [self.menusItem, emptyItem]) button = QPushButton(self.tr('Reset to defaults')) button.clicked.connect(self.resetMenusToDefaults) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(button) layout.addStretch() widget = QWidget() widget.setLayout(layout) self.tree.setIndexWidget(emptyItem.index(), widget) for provider in QgsApplication.processingRegistry().providers(): providerDescription = provider.name() groupItem = QStandardItem(providerDescription) icon = provider.icon() groupItem.setIcon(icon) groupItem.setEditable(False) for alg in provider.algorithms(): algItem = QStandardItem(alg.displayName()) algItem.setIcon(icon) algItem.setEditable(False) try: settingMenu = ProcessingConfig.settings["MENU_" + alg.id()] settingButton = ProcessingConfig.settings["BUTTON_" + alg.id()] settingIcon = ProcessingConfig.settings["ICON_" + alg.id()] except: continue self.items[settingMenu] = SettingItem(settingMenu) self.items[settingButton] = SettingItem(settingButton) self.items[settingIcon] = SettingItem(settingIcon) menuLabelItem = QStandardItem("Menu path") menuLabelItem.setEditable(False) buttonLabelItem = QStandardItem("Add button in toolbar") buttonLabelItem.setEditable(False) iconLabelItem = QStandardItem("Icon") iconLabelItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) algItem.insertRow(0, [menuLabelItem, self.items[settingMenu]]) algItem.insertRow(0, [buttonLabelItem, self.items[settingButton]]) algItem.insertRow(0, [iconLabelItem, self.items[settingIcon]]) groupItem.insertRow(0, [algItem, emptyItem]) emptyItem = QStandardItem() emptyItem.setEditable(False) self.menusItem.appendRow([groupItem, emptyItem]) self.tree.sortByColumn(0, Qt.AscendingOrder) self.adjustColumns()
def setupUi(self): self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.algorithmItem = None self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) widget_context = QgsProcessingParameterWidgetContext() widget_context.setProject(QgsProject.instance()) if iface is not None: widget_context.setMapCanvas(iface.mapCanvas()) widget_context.setModel(self.model) widget_context.setModelChildAlgorithmId(self.childId) self.algorithmItem = QgsGui.instance().processingGuiRegistry().algorithmConfigurationWidget(self._alg) if self.algorithmItem: self.algorithmItem.setWidgetContext(widget_context) self.algorithmItem.registerProcessingContextGenerator(self.context_generator) if self.configuration: self.algorithmItem.setConfiguration(self.configuration) self.verticalLayout.addWidget(self.algorithmItem) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper wrapper.setWidgetContext(widget_context) wrapper.registerProcessingContextGenerator(self.context_generator) if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): widget = wrapper else: widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget if issubclass(wrapper.__class__, QgsProcessingModelerParameterWidget): label = wrapper.createLabel() else: tooltip = param.description() widget.setToolTip(tooltip) label = wrapper.label self.widget_labels[param.name()] = label if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(self.tr('[Enter name if this is a final result]')) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self)
class OptionsDialog(QDialog, FORM_CLASS): """Options dialog for the InaSAFE plugin.""" def __init__(self, iface, parent=None, qsetting=''): """Constructor for the dialog. :param iface: A Quantum GIS QgisAppInterface instance. :type iface: QgisAppInterface :param parent: Parent widget of this dialog :type parent: QWidget :param qsetting: String to specify the QSettings. By default, use empty string. :type qsetting: str """ QDialog.__init__(self, parent) self.setupUi(self) icon = resources_path('img', 'icons', 'configure-inasafe.svg') self.setWindowIcon(QIcon(icon)) self.setWindowTitle(self.tr('InaSAFE %s Options' % get_version())) # Save reference to the QGIS interface and parent self.iface = iface self.parent = parent if qsetting: self.settings = QSettings(qsetting) else: self.settings = QSettings() # InaSAFE default values self.default_value_parameters = [] self.default_value_parameter_containers = [] # Flag for restore default values self.is_restore_default = False # List of setting key and control self.boolean_settings = { 'visibleLayersOnlyFlag': self.cbxVisibleLayersOnly, 'set_layer_from_title_flag': self.cbxSetLayerNameFromTitle, 'setZoomToImpactFlag': self.cbxZoomToImpact, 'set_show_only_impact_on_report': self.cbx_show_only_impact, 'print_atlas_report': self.cbx_print_atlas_report, 'setHideExposureFlag': self.cbxHideExposure, 'useSelectedFeaturesOnly': self.cbxUseSelectedFeaturesOnly, 'useSentry': self.cbxUseSentry, 'template_warning_verbose': self.template_warning_checkbox, 'showOrganisationLogoInDockFlag': self.organisation_on_dock_checkbox, 'developer_mode': self.cbxDevMode, 'generate_report': self.checkbox_generate_reports, 'memory_profile': self.check_box_memory, 'always_show_welcome_message': self.welcome_message_check_box } self.text_settings = { 'keywordCachePath': self.leKeywordCachePath, 'ISO19115_ORGANIZATION': self.organisation_line_edit, 'ISO19115_URL': self.website_line_edit, 'ISO19115_EMAIL': self.email_line_edit, 'ISO19115_LICENSE': self.license_line_edit, } # Export and Import button # Export button self.export_button = QPushButton(tr('Export')) # noinspection PyUnresolvedReferences self.export_button.clicked.connect(self.export_setting) self.button_box.addButton( self.export_button, QDialogButtonBox.ActionRole) # Import button self.import_button = QPushButton(tr('Import')) # noinspection PyUnresolvedReferences self.import_button.clicked.connect(self.import_setting) self.button_box.addButton( self.import_button, QDialogButtonBox.ActionRole) # Set up things for context help self.help_button = self.button_box.button(QDialogButtonBox.Help) # Allow toggling the help button self.help_button.setCheckable(True) self.help_button.toggled.connect(self.help_toggled) self.main_stacked_widget.setCurrentIndex(1) # Always set first tab to be open, 0-th index self.tabWidget.setCurrentIndex(0) # Hide not implemented group self.grpNotImplemented.hide() self.adjustSize() # Population parameter Tab # Label self.preference_label = QLabel() self.preference_label.setText(tr( 'Please set parameters for each hazard class below. Affected ' 'status and displacement rates selected on this tab are only ' 'applied to exposed populations. ' )) self.preference_layout.addWidget(self.preference_label) # Profile preference widget self.profile_widget = ProfileWidget() self.preference_layout.addWidget(self.profile_widget) # Demographic tab self.demographic_label = QLabel() self.demographic_label.setText(tr( 'Please set the global default demographic ratio below.')) self.default_values_layout.addWidget(self.demographic_label) self.scroll_area = QScrollArea() self.scroll_area.setWidgetResizable(True) self.widget_container = QWidget() self.scroll_area.setWidget(self.widget_container) self.container_layout = QVBoxLayout() self.widget_container.setLayout(self.container_layout) self.default_values_layout.addWidget(self.scroll_area) # Restore state from setting self.restore_state() # Hide checkbox if not developers if not self.cbxDevMode.isChecked(): self.checkbox_generate_reports.hide() # Connections # Check boxes self.custom_north_arrow_checkbox.toggled.connect(self.set_north_arrow) self.custom_UseUserDirectory_checkbox.toggled.connect( self.set_user_dir) self.custom_templates_dir_checkbox.toggled.connect( self.set_templates_dir) self.custom_org_disclaimer_checkbox.toggled.connect( self.set_org_disclaimer) self.custom_organisation_logo_check_box.toggled.connect( self.toggle_logo_path) # Buttons self.toolKeywordCachePath.clicked.connect(self.open_keyword_cache_path) self.toolUserDirectoryPath.clicked.connect( self.open_user_directory_path) self.toolNorthArrowPath.clicked.connect(self.open_north_arrow_path) self.open_organisation_logo_path_button.clicked.connect( self.open_organisation_logo_path) self.toolReportTemplatePath.clicked.connect( self.open_report_template_path) # Others self.organisation_logo_path_line_edit.textChanged.connect( self.update_logo_preview) self.earthquake_function.currentIndexChanged.connect( self.update_earthquake_info) # Set up listener for restore defaults button self.demographic_restore_defaults = self.button_box_restore_defaults.\ button(QDialogButtonBox.RestoreDefaults) self.demographic_restore_defaults.setText( self.demographic_restore_defaults.text().capitalize()) self.demographic_restore_defaults.setCheckable(True) self.demographic_restore_defaults.clicked.connect( self.restore_defaults_ratio) # Restore button in population parameter tab self.parameter_population_restore_button = \ self.button_box_restore_preference.button( QDialogButtonBox.RestoreDefaults) self.parameter_population_restore_button.setText( self.parameter_population_restore_button.text().capitalize()) self.parameter_population_restore_button.clicked.connect( partial(self.restore_population_parameters, global_default=True)) # TODO: Hide this until behaviour is defined # hide template warning toggle self.template_warning_checkbox.hide() # hide custom template dir toggle self.custom_templates_dir_checkbox.hide() self.splitter_custom_report.hide() # Welcome message self.set_welcome_message() def save_boolean_setting(self, key, check_box): """Save boolean setting according to check_box state. :param key: Key to retrieve setting value. :type key: str :param check_box: Check box to show and set the setting. :type check_box: PyQt5.QtWidgets.QCheckBox.QCheckBox """ set_setting(key, check_box.isChecked(), qsettings=self.settings) def restore_boolean_setting(self, key, check_box): """Set check_box according to setting of key. :param key: Key to retrieve setting value. :type key: str :param check_box: Check box to show and set the setting. :type check_box: PyQt5.QtWidgets.QCheckBox.QCheckBox """ flag = setting(key, expected_type=bool, qsettings=self.settings) check_box.setChecked(flag) def save_text_setting(self, key, line_edit): """Save text setting according to line_edit value. :param key: Key to retrieve setting value. :type key: str :param line_edit: Line edit for user to edit the setting :type line_edit: PyQt5.QtWidgets.QLineEdit.QLineEdit """ set_setting(key, line_edit.text(), self.settings) def restore_text_setting(self, key, line_edit): """Set line_edit text according to setting of key. :param key: Key to retrieve setting value. :type key: str :param line_edit: Line edit for user to edit the setting :type line_edit: PyQt5.QtWidgets.QLineEdit.QLineEdit """ value = setting(key, expected_type=str, qsettings=self.settings) line_edit.setText(value) def restore_state(self): """Reinstate the options based on the user's stored session info.""" # Restore boolean setting as check box. for key, check_box in list(self.boolean_settings.items()): self.restore_boolean_setting(key, check_box) # Restore text setting as line edit. for key, line_edit in list(self.text_settings.items()): self.restore_text_setting(key, line_edit) # User Directory user_directory_path = setting( key='defaultUserDirectory', default=temp_dir('impacts'), expected_type=str, qsettings=self.settings) custom_user_directory_flag = ( user_directory_path != temp_dir('impacts')) self.custom_UseUserDirectory_checkbox.setChecked( custom_user_directory_flag) self.splitter_user_directory.setEnabled(custom_user_directory_flag) self.leUserDirectoryPath.setText(user_directory_path) # Currency # Populate the currency list for currency in currencies: self.currency_combo_box.addItem(currency['name'], currency['key']) # Then make selected the default one. default_currency = setting('currency', expected_type=str) keys = [currency['key'] for currency in currencies] if default_currency not in keys: default_currency = currencies[0]['key'] index = self.currency_combo_box.findData(default_currency) self.currency_combo_box.setCurrentIndex(index) # Earthquake function. # Populate the combobox first. for model in EARTHQUAKE_FUNCTIONS: self.earthquake_function.addItem(model['name'], model['key']) # Then make selected the default one. default_earthquake_function = setting( 'earthquake_function', expected_type=str) keys = [model['key'] for model in EARTHQUAKE_FUNCTIONS] if default_earthquake_function not in keys: default_earthquake_function = EARTHQUAKE_FUNCTIONS[0]['key'] index = self.earthquake_function.findData(default_earthquake_function) self.earthquake_function.setCurrentIndex(index) self.update_earthquake_info() # Restore North Arrow Image Path north_arrow_path = setting( key='north_arrow_path', default=default_north_arrow_path(), expected_type=str, qsettings=self.settings) custom_north_arrow_flag = ( north_arrow_path != default_north_arrow_path()) self.custom_north_arrow_checkbox.setChecked(custom_north_arrow_flag) self.splitter_north_arrow.setEnabled(custom_north_arrow_flag) self.leNorthArrowPath.setText(north_arrow_path) # Restore Report Template Directory Path report_template_directory = setting( key='reportTemplatePath', default='', expected_type=str, qsettings=self.settings) custom_templates_dir_flag = (report_template_directory != '') self.custom_templates_dir_checkbox.setChecked( custom_templates_dir_flag) self.leReportTemplatePath.setText(report_template_directory) # Restore Disclaimer org_disclaimer = setting( key='reportDisclaimer', default=disclaimer(), expected_type=str, qsettings=self.settings) custom_org_disclaimer_flag = (org_disclaimer != disclaimer()) self.custom_org_disclaimer_checkbox.setChecked( custom_org_disclaimer_flag) self.txtDisclaimer.setPlainText(org_disclaimer) # Restore Organisation Logo Path org_logo_path = setting( key='organisation_logo_path', default=supporters_logo_path(), expected_type=str, qsettings=self.settings) # Check if the path is default one or not custom_org_logo_flag = org_logo_path != supporters_logo_path() self.organisation_logo_path_line_edit.setText(org_logo_path) self.custom_organisation_logo_check_box.setChecked( custom_org_logo_flag) self.organisation_logo_path_line_edit.setEnabled( custom_org_logo_flag) self.open_organisation_logo_path_button.setEnabled( custom_org_logo_flag) # Manually call here self.update_logo_preview() # Restore InaSAFE default values self.restore_default_values_page() # Restore Population Parameter self.restore_population_parameters(global_default=False) def save_state(self): """Store the options into the user's stored session info.""" # Save boolean settings for key, check_box in list(self.boolean_settings.items()): self.save_boolean_setting(key, check_box) # Save text settings for key, line_edit in list(self.text_settings.items()): self.save_text_setting(key, line_edit) set_setting( 'north_arrow_path', self.leNorthArrowPath.text(), self.settings) set_setting( 'organisation_logo_path', self.organisation_logo_path_line_edit.text(), self.settings) set_setting( 'reportTemplatePath', self.leReportTemplatePath.text(), self.settings) set_setting( 'reportDisclaimer', self.txtDisclaimer.toPlainText(), self.settings) set_setting( 'defaultUserDirectory', self.leUserDirectoryPath.text(), self.settings) index = self.earthquake_function.currentIndex() value = self.earthquake_function.itemData(index) set_setting('earthquake_function', value, qsettings=self.settings) currency_index = self.currency_combo_box.currentIndex() currency_key = self.currency_combo_box.itemData(currency_index) set_setting('currency', currency_key, qsettings=self.settings) # Save InaSAFE default values self.save_default_values() # Save population parameters self.save_population_parameters() def accept(self): """Method invoked when OK button is clicked.""" self.save_state() super(OptionsDialog, self).accept() def update_earthquake_info(self): """Update information about earthquake info.""" self.label_earthquake_model() current_index = self.earthquake_function.currentIndex() model = EARTHQUAKE_FUNCTIONS[current_index] notes = '' for note in model['notes']: notes += note + '\n\n' citations = '' for citation in model['citations']: citations += citation['text'] + '\n\n' text = tr( 'Description:\n\n%s\n\n' 'Notes:\n\n%s\n\n' 'Citations:\n\n%s') % ( model['description'], notes, citations) self.earthquake_fatality_model_notes.setText(text) def label_earthquake_model(self): model = self.earthquake_function.currentText() help_text = tr( 'Please select your preferred earthquake fatality model. The ' 'default fatality model is the {model}.').format(model=model) self.label_default_earthquake.setText(help_text) def open_keyword_cache_path(self): """Open File dialog to choose the keyword cache path.""" # noinspection PyCallByClass,PyTypeChecker file_name, __ = QFileDialog.getSaveFileName( self, self.tr('Set keyword cache file'), self.leKeywordCachePath.text(), self.tr('Sqlite DB File (*.db)')) if file_name: self.leKeywordCachePath.setText(file_name) def open_user_directory_path(self): """Open File dialog to choose the user directory path.""" # noinspection PyCallByClass,PyTypeChecker directory_name = QFileDialog.getExistingDirectory( self, self.tr('Results directory'), self.leUserDirectoryPath.text(), QFileDialog.ShowDirsOnly) if directory_name: self.leUserDirectoryPath.setText(directory_name) def open_north_arrow_path(self): """Open File dialog to choose the north arrow path.""" # noinspection PyCallByClass,PyTypeChecker file_name, __ = QFileDialog.getOpenFileName( self, self.tr('Set north arrow image file'), self.leNorthArrowPath.text(), self.tr( 'Portable Network Graphics files (*.png *.PNG);;' 'JPEG Images (*.jpg *.jpeg);;' 'GIF Images (*.gif *.GIF);;' 'SVG Images (*.svg *.SVG);;')) if file_name: self.leNorthArrowPath.setText(file_name) def open_organisation_logo_path(self): """Open File dialog to choose the organisation logo path.""" # noinspection PyCallByClass,PyTypeChecker file_name, __ = QFileDialog.getOpenFileName( self, self.tr('Set organisation logo file'), self.organisation_logo_path_line_edit.text(), self.tr( 'Portable Network Graphics files (*.png *.PNG);;' 'JPEG Images (*.jpg *.jpeg);;' 'GIF Images (*.gif *.GIF);;' 'SVG Images (*.svg *.SVG);;')) if file_name: self.organisation_logo_path_line_edit.setText(file_name) def open_report_template_path(self): """Open File dialog to choose the report template path.""" # noinspection PyCallByClass,PyTypeChecker directory_name = QFileDialog.getExistingDirectory( self, self.tr('Templates directory'), self.leReportTemplatePath.text(), QFileDialog.ShowDirsOnly) if directory_name: self.leReportTemplatePath.setText(directory_name) def toggle_logo_path(self): """Set state of logo path line edit and button.""" is_checked = self.custom_organisation_logo_check_box.isChecked() if is_checked: # Use previous org logo path path = setting( key='organisation_logo_path', default=supporters_logo_path(), expected_type=str, qsettings=self.settings) else: # Set organisation path line edit to default one path = supporters_logo_path() self.organisation_logo_path_line_edit.setText(path) self.organisation_logo_path_line_edit.setEnabled(is_checked) self.open_organisation_logo_path_button.setEnabled(is_checked) def update_logo_preview(self): """Update logo based on the current logo path.""" logo_path = self.organisation_logo_path_line_edit.text() if os.path.exists(logo_path): icon = QPixmap(logo_path) label_size = self.organisation_logo_label.size() label_size.setHeight(label_size.height() - 2) label_size.setWidth(label_size.width() - 2) scaled_icon = icon.scaled( label_size, Qt.KeepAspectRatio) self.organisation_logo_label.setPixmap(scaled_icon) else: self.organisation_logo_label.setText(tr("Logo not found")) def set_north_arrow(self): """Auto-connect slot activated when north arrow checkbox is toggled.""" is_checked = self.custom_north_arrow_checkbox.isChecked() if is_checked: # Show previous north arrow path path = setting( key='north_arrow_path', default=default_north_arrow_path(), expected_type=str, qsettings=self.settings) else: # Set the north arrow line edit to default one path = default_north_arrow_path() self.leNorthArrowPath.setText(path) self.splitter_north_arrow.setEnabled(is_checked) def set_user_dir(self): """Auto-connect slot activated when user dir checkbox is toggled. """ is_checked = self.custom_UseUserDirectory_checkbox.isChecked() if is_checked: # Show previous templates dir path = setting( key='defaultUserDirectory', default='', expected_type=str, qsettings=self.settings) else: # Set the template report dir to '' path = temp_dir('impacts') self.leUserDirectoryPath.setText(path) self.splitter_user_directory.setEnabled(is_checked) def set_templates_dir(self): """Auto-connect slot activated when templates dir checkbox is toggled. """ is_checked = self.custom_templates_dir_checkbox.isChecked() if is_checked: # Show previous templates dir path = setting( key='reportTemplatePath', default='', expected_type=str, qsettings=self.settings) else: # Set the template report dir to '' path = '' self.leReportTemplatePath.setText(path) self.splitter_custom_report.setEnabled(is_checked) def set_org_disclaimer(self): """Auto-connect slot activated when org disclaimer checkbox is toggled. """ is_checked = self.custom_org_disclaimer_checkbox.isChecked() if is_checked: # Show previous organisation disclaimer org_disclaimer = setting( 'reportDisclaimer', default=disclaimer(), expected_type=str, qsettings=self.settings) else: # Set the organisation disclaimer to the default one org_disclaimer = disclaimer() self.txtDisclaimer.setPlainText(org_disclaimer) self.txtDisclaimer.setEnabled(is_checked) @pyqtSlot(bool) # prevents actions being handled twice def help_toggled(self, flag): """Show or hide the help tab in the stacked widget. .. versionadded: 3.2.1 :param flag: Flag indicating whether help should be shown or hidden. :type flag: bool """ if flag: self.help_button.setText(self.tr('Hide Help')) self.show_help() else: self.help_button.setText(self.tr('Show Help')) self.hide_help() def hide_help(self): """Hide the usage info from the user. .. versionadded: 3.2.1 """ self.main_stacked_widget.setCurrentIndex(1) def show_help(self): """Show usage info to the user.""" # Read the header and footer html snippets self.main_stacked_widget.setCurrentIndex(0) header = html_header() footer = html_footer() string = header message = options_help() string += message.to_html() string += footer self.help_web_view.setHtml(string) def restore_default_values_page(self): """Setup UI for default values setting.""" # Clear parameters so it doesn't add parameters when # restore from changes. if self.default_value_parameters: self.default_value_parameters = [] if self.default_value_parameter_containers: self.default_value_parameter_containers = [] for i in reversed(list(range(self.container_layout.count()))): widget = self.container_layout.itemAt(i).widget() if widget is not None: widget.setParent(None) default_fields = all_default_fields() for field_group in all_field_groups: settable_fields = [] for field in field_group['fields']: if field not in default_fields: continue else: settable_fields.append(field) default_fields.remove(field) if not settable_fields: continue # Create group box for each field group group_box = QGroupBox(self) group_box.setTitle(field_group['name']) self.container_layout.addWidget(group_box) parameters = [] for settable_field in settable_fields: parameter = self.default_field_to_parameter(settable_field) if parameter: parameters.append(parameter) parameter_container = ParameterContainer( parameters, description_text=field_group['description'], extra_parameters=extra_parameter ) parameter_container.setup_ui(must_scroll=False) group_box_inner_layout = QVBoxLayout() group_box_inner_layout.addWidget(parameter_container) group_box.setLayout(group_box_inner_layout) # Add to attribute self.default_value_parameter_containers.append(parameter_container) # Only show non-groups default fields if there is one if len(default_fields) > 0: for default_field in default_fields: parameter = self.default_field_to_parameter(default_field) if parameter: self.default_value_parameters.append(parameter) description_text = tr( 'In this options you can change the global default values for ' 'these variables.') parameter_container = ParameterContainer( self.default_value_parameters, description_text=description_text, extra_parameters=extra_parameter ) parameter_container.setup_ui(must_scroll=False) self.other_group_box = QGroupBox(tr('Non-group fields')) other_group_inner_layout = QVBoxLayout() other_group_inner_layout.addWidget(parameter_container) self.other_group_box.setLayout(other_group_inner_layout) self.container_layout.addWidget(self.other_group_box) # Add to attribute self.default_value_parameter_containers.append(parameter_container) def restore_population_parameters(self, global_default=True): """Setup UI for population parameter page from setting. :param global_default: If True, set to original default (from the value in definitions). :type global_default: bool """ if global_default: data = generate_default_profile() else: data = setting('population_preference', generate_default_profile()) if not isinstance(data, dict): LOGGER.debug( 'population parameter is not a dictionary. InaSAFE will use ' 'the default one.') data = generate_default_profile() try: self.profile_widget.data = data except KeyError as e: LOGGER.debug( 'Population parameter is not in correct format. InaSAFE will ' 'use the default one.') LOGGER.debug(e) data = generate_default_profile() self.profile_widget.data = data @staticmethod def age_ratios(): """Helper to get list of age ratio from the options dialog. :returns: List of age ratio. :rtype: list """ # FIXME(IS) set a correct parameter container parameter_container = None youth_ratio = parameter_container.get_parameter_by_guid( youth_ratio_field['key']).value adult_ratio = parameter_container.get_parameter_by_guid( adult_ratio_field['key']).value elderly_ratio = parameter_container.get_parameter_by_guid( elderly_ratio_field['key']).value ratios = [youth_ratio, adult_ratio, elderly_ratio] return ratios def is_good_age_ratios(self): """Method to check the sum of age ratio is 1. :returns: True if the sum is 1 or the sum less than 1 but there is None. :rtype: bool """ ratios = self.age_ratios() if None in ratios: # If there is None, just check to not exceeding 1 clean_ratios = [x for x in ratios if x is not None] ratios.remove(None) if sum(clean_ratios) > 1: return False else: if sum(ratios) != 1: return False return True def save_default_values(self): """Save InaSAFE default values.""" for parameter_container in self.default_value_parameter_containers: parameters = parameter_container.get_parameters() for parameter in parameters: set_inasafe_default_value_qsetting( self.settings, GLOBAL, parameter.guid, parameter.value ) def restore_defaults_ratio(self): """Restore InaSAFE default ratio.""" # Set the flag to true because user ask to. self.is_restore_default = True # remove current default ratio for i in reversed(list(range(self.container_layout.count()))): widget = self.container_layout.itemAt(i).widget() if widget is not None: widget.setParent(None) # reload default ratio self.restore_default_values_page() def default_field_to_parameter(self, default_field): """Obtain parameter from default field. :param default_field: A default field definition. :type default_field: dict :returns: A parameter object. :rtype: FloatParameter, IntegerParameter """ if default_field.get('type') == QVariant.Double: parameter = FloatParameter() elif default_field.get('type') in qvariant_whole_numbers: parameter = IntegerParameter() else: return default_value = default_field.get('default_value') if not default_value: message = ( 'InaSAFE default field %s does not have default value' % default_field.get('name')) LOGGER.exception(message) return parameter.guid = default_field.get('key') parameter.name = default_value.get('name') parameter.is_required = True parameter.precision = default_field.get('precision') parameter.minimum_allowed_value = default_value.get( 'min_value', 0) parameter.maximum_allowed_value = default_value.get( 'max_value', 100000000) parameter.help_text = default_value.get('help_text') parameter.description = default_value.get('description') # Check if user ask to restore to the most default value. if self.is_restore_default: parameter._value = default_value.get('default_value') else: # Current value qsetting_default_value = get_inasafe_default_value_qsetting( self.settings, GLOBAL, default_field['key']) # To avoid python error if qsetting_default_value > parameter.maximum_allowed_value: qsetting_default_value = parameter.maximum_allowed_value if qsetting_default_value < parameter.minimum_allowed_value: qsetting_default_value = parameter.minimum_allowed_value parameter.value = qsetting_default_value return parameter def save_population_parameters(self): """Helper to save population parameter to QSettings.""" population_parameter = self.profile_widget.data set_setting('population_preference', population_parameter) def set_welcome_message(self): """Create and insert welcome message.""" string = html_header() string += welcome_message().to_html() string += html_footer() self.welcome_message.setHtml(string) def show_option_dialog(self): """Helper to show usual option dialog (without welcome message tab).""" self.tabWidget.removeTab(0) def show_welcome_dialog(self): """Setup for showing welcome message dialog. This method will setup several things: - Only show welcome, organisation profile, and population parameter tab. Currently, they are the first 3 tabs. - Set the title - Move the check box for always showing welcome message. """ self.welcome_layout.addWidget(self.welcome_message_check_box) while self.tabWidget.count() > 3: self.tabWidget.removeTab(self.tabWidget.count() - 1) self.setWindowTitle(self.tr('Welcome to InaSAFE %s' % get_version())) # Hide the export import button self.export_button.hide() self.import_button.hide() def export_setting(self): """Export setting from an existing file.""" LOGGER.debug('Export button clicked') home_directory = os.path.expanduser('~') file_name = self.organisation_line_edit.text().replace(' ', '_') file_path, __ = QFileDialog.getSaveFileName( self, self.tr('Export InaSAFE settings'), os.path.join(home_directory, file_name + '.json'), self.tr('JSON File (*.json)')) if file_path: LOGGER.debug('Exporting to %s' % file_path) export_setting(file_path) def import_setting(self): """Import setting to a file.""" LOGGER.debug('Import button clicked') home_directory = os.path.expanduser('~') file_path, __ = QFileDialog.getOpenFileName( self, self.tr('Import InaSAFE settings'), home_directory, self.tr('JSON File (*.json)')) if file_path: title = tr('Import InaSAFE Settings.') question = tr( 'This action will replace your current InaSAFE settings with ' 'the setting from the file. This action is not reversible. ' 'Are you sure to import InaSAFE Setting?') answer = QMessageBox.question( self, title, question, QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: LOGGER.debug('Import from %s' % file_path) import_setting(file_path)
def treeItemChanged(self, current, previous): qgsgeom1 = None qgsgeom2 = None crs = "EPSG:4326" if not isinstance(current, FeatureItem): self.attributesTable.clear() self.attributesTable.setRowCount(0) return color = {"MODIFIED": QColor(255, 170, 0), "ADDED":Qt.green, "REMOVED":Qt.red , "NO_CHANGE":Qt.white} path = current.layername + "/" + current.featureid featurediff = self.changes[path].featurediff() self.attributesTable.clear() self.attributesTable.verticalHeader().show() self.attributesTable.horizontalHeader().show() self.attributesTable.setRowCount(len(featurediff)) self.attributesTable.setVerticalHeaderLabels([a["attributename"] for a in featurediff]) self.attributesTable.setHorizontalHeaderLabels(["Old value", "New value", "Change type"]) for i, attrib in enumerate(featurediff): try: if attrib["changetype"] == "MODIFIED": oldvalue = attrib["oldvalue"] newvalue = attrib["newvalue"] elif attrib["changetype"] == "ADDED": newvalue = attrib["newvalue"] oldvalue = "" elif attrib["changetype"] == "REMOVED": oldvalue = attrib["oldvalue"] newvalue = "" else: oldvalue = newvalue = attrib["oldvalue"] except: oldvalue = newvalue = "" self.attributesTable.setItem(i, 0, DiffItem(oldvalue)) self.attributesTable.setItem(i, 1, DiffItem(newvalue)) try: self.attributesTable.setItem(i, 2, QTableWidgetItem("")) if qgsgeom1 is None or qgsgeom2 is None: if "crs" in attrib: crs = attrib["crs"] qgsgeom1 = QgsGeometry.fromWkt(oldvalue) qgsgeom2 = QgsGeometry.fromWkt(newvalue) if qgsgeom1 is not None and qgsgeom2 is not None: widget = QWidget() btn = QPushButton() btn.setText("View detail") btn.clicked.connect(lambda: self.viewGeometryChanges(qgsgeom1, qgsgeom2, crs)) label = QLabel() label.setText(attrib["changetype"]) layout = QHBoxLayout(widget) layout.addWidget(label); layout.addWidget(btn); layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) self.attributesTable.setCellWidget(i, 2, widget) else: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) else: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) except: self.attributesTable.setItem(i, 2, QTableWidgetItem(attrib["changetype"])) for col in range(3): self.attributesTable.item(i, col).setBackgroundColor(color[attrib["changetype"]]); self.attributesTable.resizeColumnsToContents() self.attributesTable.horizontalHeader().setResizeMode(QHeaderView.Stretch)
class ModelerParametersDialog(QDialog): ENTER_NAME = '[Enter name if this is a final result]' NOT_SELECTED = '[Not selected]' USE_MIN_COVERING_EXTENT = '[Use min covering extent]' def __init__(self, alg, model, algName=None): QDialog.__init__(self) self.setModal(True) # The algorithm to define in this dialog. It is an instance of GeoAlgorithm self._alg = alg # The resulting algorithm after the user clicks on OK. it is an instance of the container Algorithm class self.alg = None # The model this algorithm is going to be added to self.model = model # The name of the algorithm in the model, in case we are editing it and not defining it for the first time self._algName = algName self.setupUi() self.params = None def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.name) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') if param.optional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name] = label wrapper = param.wrapper(self) self.wrappers[param.name] = wrapper widget = wrapper.widget self.valueItems[param.name] = widget if param.name in list(tooltips.keys()): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.name) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.txtHelp = QTextBrowser() html = None isText, algHelp = self._alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr( '<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) self.tabWidget.addTab(self.txtHelp, 'Help') self.reply = QgsNetworkAccessManager.instance().get( QNetworkRequest(algHelp)) self.reply.finished.connect(self.requestFinished) except: pass self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values())) def requestFinished(self): """Change the webview HTML content""" reply = self.sender() if reply.error() != QNetworkReply.NoError: html = self.tr( '<h2>No help available for this algorithm</h2><p>{}</p>'. format(reply.errorString())) else: html = str(reply.readAll()) reply.deleteLater() self.txtHelp.setHtml(html) def getAvailableDependencies(self): if self._algName is None: dependent = [] else: dependent = self.model.getDependentAlgorithms(self._algName) opts = [] for alg in list(self.model.algs.values()): if alg.name not in dependent: opts.append(alg) return opts def getDependenciesPanel(self): return MultipleInputPanel( [alg.algorithm.name for alg in self.getAvailableDependencies()]) def showAdvancedParametersClicked(self): self.showAdvanced = not self.showAdvanced if self.showAdvanced: self.advancedButton.setText(self.tr('Hide advanced parameters')) else: self.advancedButton.setText(self.tr('Show advanced parameters')) for param in self._alg.parameters: if param.isAdvanced: self.labels[param.name].setVisible(self.showAdvanced) self.widgets[param.name].setVisible(self.showAdvanced) def getAvailableValuesOfType(self, paramType, outType=None, dataType=None): values = [] inputs = self.model.inputs for i in list(inputs.values()): param = i.param if isinstance(param, paramType): if dataType is not None: if param.datatype in dataType: values.append(ValueFromInput(param.name)) else: values.append(ValueFromInput(param.name)) if outType is None: return values if self._algName is None: dependent = [] else: dependent = self.model.getDependentAlgorithms(self._algName) for alg in list(self.model.algs.values()): if alg.name not in dependent: for out in alg.algorithm.outputs: if isinstance(out, outType): if dataType is not None and out.datatype in dataType: values.append(ValueFromOutput(alg.name, out.name)) else: values.append(ValueFromOutput(alg.name, out.name)) return values def resolveValueDescription(self, value): if isinstance(value, ValueFromInput): return self.model.inputs[value.name].param.description else: alg = self.model.algs[value.alg] return self.tr("'%s' from algorithm '%s'") % ( alg.algorithm.getOutputFromName( value.output).description, alg.description) def setTableContent(self): params = self._alg.parameters outputs = self._alg.outputs visibleParams = [p for p in params if not p.hidden] visibleOutputs = [p for o in outputs if not o.hidden] self.tableWidget.setRowCount(len(visibleParams) + len(visibleOutputs)) for i, param in visibleParams: item = QTableWidgetItem(param.description) item.setFlags(Qt.ItemIsEnabled) self.tableWidget.setItem(i, 0, item) item = self.getWidgetFromParameter(param) self.valueItems[param.name] = item self.tableWidget.setCellWidget(i, 1, item) self.tableWidget.setRowHeight(i, 22) for i, output in visibleOutputs: item = QTableWidgetItem(output.description + '<' + output.__module__.split('.')[-1] + '>') item.setFlags(Qt.ItemIsEnabled) self.tableWidget.setItem(i, 0, item) item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.valueItems[output.name] = item self.tableWidget.setCellWidget(i, 1, item) self.tableWidget.setRowHeight(i, 22) def setPreviousValues(self): if self._algName is not None: alg = self.model.algs[self._algName] self.descriptionBox.setText(alg.description) for param in alg.algorithm.parameters: if param.hidden: continue if param.name in alg.params: value = alg.params[param.name] else: value = param.default self.wrappers[param.name].setValue(value) for name, out in list(alg.outputs.items()): self.valueItems[name].setText(out.description) selected = [] dependencies = self.getAvailableDependencies() for idx, dependency in enumerate(dependencies): if dependency.name in alg.dependencies: selected.append(idx) self.dependenciesPanel.setSelectedItems(selected) def createAlgorithm(self): alg = Algorithm(self._alg.commandLineName()) alg.setName(self.model) alg.description = self.descriptionBox.text() params = self._alg.parameters outputs = self._alg.outputs for param in params: if param.hidden: continue if not self.setParamValue(alg, param, self.wrappers[param.name]): self.bar.pushMessage( "Error", "Wrong or missing value for parameter '%s'" % param.description, level=QgsMessageBar.WARNING) return None for output in outputs: if not output.hidden: name = str(self.valueItems[output.name].text()) if name.strip( ) != '' and name != ModelerParametersDialog.ENTER_NAME: alg.outputs[output.name] = ModelerOutput(name) selectedOptions = self.dependenciesPanel.selectedoptions availableDependencies = self.getAvailableDependencies() for selected in selectedOptions: alg.dependencies.append(availableDependencies[selected].name) return alg def setParamValue(self, alg, param, wrapper): try: value = wrapper.value() alg.params[param.name] = value return True except InvalidParameterValue: return False def okPressed(self): self.alg = self.createAlgorithm() if self.alg is not None: self.close() def cancelPressed(self): self.alg = None self.close()