def initGui(self): layout = QVBoxLayout() self.tab = QTabWidget() self.table = QTableView() self.setLayout(layout) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) settings = QSettings() self.canvas.enableAntiAliasing( settings.value("/qgis/enable_anti_aliasing", False, type=bool)) self.canvas.useImageToRender( settings.value("/qgis/use_qimage_to_render", False, type=bool)) self.canvas.mapSettings().setDestinationCrs(self.crs) action = settings.value("/qgis/wheel_action", 0, type=float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type=float) self.canvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) self.panTool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.panTool) execute(self.createLayers) model = GeomDiffTableModel(self.data) self.table.setModel(model) self.table.resizeColumnsToContents() self.table.resizeRowsToContents() self.tab.addTab(self.canvas, "Map view") self.tab.addTab(self.table, "Table view") layout.addWidget(self.tab) self.resize(600, 500) self.setWindowTitle("Geometry comparison")
def setupUi(self): self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.tab = QTabWidget() self.mainLayout.addWidget(self.tab) self.param_widget = QgsPanelWidgetStack() self.widget.setDockMode(True) self.param_widget.setMainPanel(self.widget) self.tab.addTab(self.param_widget, self.tr('Properties')) self.commentLayout = QVBoxLayout() self.commentEdit = QTextEdit() self.commentEdit.setAcceptRichText(False) self.commentLayout.addWidget(self.commentEdit, 1) hl = QHBoxLayout() hl.setContentsMargins(0, 0, 0, 0) hl.addWidget(QLabel(self.tr('Color'))) self.comment_color_button = QgsColorButton() self.comment_color_button.setAllowOpacity(True) self.comment_color_button.setWindowTitle(self.tr('Comment Color')) self.comment_color_button.setShowNull(True, self.tr('Default')) hl.addWidget(self.comment_color_button) self.commentLayout.addLayout(hl) w2 = QWidget() w2.setLayout(self.commentLayout) self.tab.addTab(w2, self.tr('Comments')) self.setLayout(self.mainLayout)
def __init__(self, iface): QWidget.__init__(self) self.setWindowTitle(self.tr('Search results')) self.resize(480,320) self.setMinimumSize(320,240) self.center() # Results export button self.btn_saveTab = QAction(QIcon(':/plugins/qgeric/resources/icon_save.png'), self.tr('Save this tab\'s results'), self) self.btn_saveTab.triggered.connect(lambda : self.saveAttributes(True)) self.btn_saveAllTabs = QAction(QIcon(':/plugins/qgeric/resources/icon_saveAll.png'), self.tr('Save all results'), self) self.btn_saveAllTabs.triggered.connect(lambda : self.saveAttributes(False)) self.btn_export = QAction(QIcon(':/plugins/qgeric/resources/icon_export.png'), self.tr('Export the selection as a memory layer'), self) self.btn_export.triggered.connect(self.exportLayer) self.btn_zoom = QAction(QIcon(':/plugins/qgeric/resources/icon_Zoom.png'), self.tr('Zoom to selected attributes'), self) self.btn_zoom.triggered.connect(self.zoomToFeature) self.btn_selectGeom = QAction(QIcon(':/plugins/qgeric/resources/icon_HlG.png'), self.tr('Highlight feature\'s geometry'), self) self.btn_selectGeom.triggered.connect(self.selectGeomChanged) self.btn_rename = QAction(QIcon(':/plugins/qgeric/resources/icon_Settings.png'), self.tr('Settings'), self) self.btn_rename.triggered.connect(self.renameWindow) self.tabWidget = QTabWidget() # Tab container self.tabWidget.setTabsClosable(True) self.tabWidget.currentChanged.connect(self.highlight_features) self.tabWidget.tabCloseRequested.connect(self.closeTab) self.loadingWindow = QProgressDialog() self.loadingWindow.setWindowTitle(self.tr('Loading...')) self.loadingWindow.setRange(0,100) self.loadingWindow.setAutoClose(False) self.loadingWindow.setCancelButton(None) self.canvas = iface.mapCanvas() self.canvas.extentsChanged.connect(self.highlight_features) self.highlight = [] self.highlight_rows = [] toolbar = QToolBar() toolbar.addAction(self.btn_saveTab) toolbar.addAction(self.btn_saveAllTabs) toolbar.addAction(self.btn_export) toolbar.addSeparator() toolbar.addAction(self.btn_zoom) toolbar.addSeparator() toolbar.addAction(self.btn_selectGeom) toolbar.addAction(self.btn_rename) vbox = QVBoxLayout() vbox.setContentsMargins(0,0,0,0) vbox.addWidget(toolbar) vbox.addWidget(self.tabWidget) self.setLayout(vbox) self.mb = iface.messageBar() self.selectGeom = False # False for point, True for geometry
def uisetup(self): """ Called when the UI is fully constructed. You should connect any signals here. """ if self.formconfig['type'] == 'auto': self.AddInspectionButton = QPushButton() self.inspectiontabs = QTabWidget() self.layout().addRow(self.AddInspectionButton) self.layout().addRow(self.inspectiontabs) self.AddInspectionButton.pressed.connect(self.create_new_inspection)
def create_doc_tab_populate_combobox(self): """ Creates the supporting document component widget. """ self.doc_tab_data() self.docs_tab = QTabWidget() self.docs_tab_index = OrderedDict() for i, (id, doc) in enumerate(self.doc_types.items()): self.docs_tab_index[doc] = i # the tab widget containing the document widget layout # and the child of the tab. tab_widget = QWidget() tab_widget.setObjectName(doc) # The layout of the tab widget cont_layout = QVBoxLayout(tab_widget) cont_layout.setObjectName('widget_layout_{}'.format(doc)) # the scroll area widget inside the tab widget. scroll_area = QScrollArea(tab_widget) scroll_area.setFrameShape(QFrame.NoFrame) scroll_area.setObjectName('tab_scroll_area_{}'.format(doc)) layout_widget = QWidget() # the widget the is under the scroll area content and # the widget containing the document widget layout # This widget is hidden and shown based on the STR number layout_widget.setObjectName('widget_{}'.format(doc)) doc_widget_layout = QVBoxLayout(layout_widget) doc_widget_layout.setObjectName('doc_widget_layout_{}'.format(doc)) doc_widget = QWidget() doc_widget.setObjectName('doc_widget_{}_{}'.format( doc, self.str_number)) doc_widget_layout.addWidget(doc_widget) # the layout containing document widget. ### This is the layout that is registered to add uploaded # supporting documents widgets into. tab_layout = QVBoxLayout(doc_widget) tab_layout.setObjectName('layout_{}_{}'.format( doc, self.str_number)) scroll_area.setWidgetResizable(True) scroll_area.setWidget(layout_widget) cont_layout.addWidget(scroll_area) # Add the tab widget with the document # type name to create a tab. self.docs_tab.addTab(tab_widget, doc) self.container_box.addWidget(self.docs_tab, 1) if len(self.str_numbers) == 1: self.doc_type_cbo.addItem(doc, id)
def initGui(self): layout = QVBoxLayout() splitter = QSplitter() splitter.setOrientation(Qt.Vertical) self.history = HistoryTree(self.dialog) self.history.updateContent(self.server, self.user, self.repo, self.graph, self.layer) self.historyWithFilter = HistoryTreeWrapper(self.history) if self.simplifyLog: self.historyWithFilter.simplify(True) splitter.addWidget(self.historyWithFilter) self.tabWidget = QTabWidget() self.tabCanvas = QWidget() tabLayout = QVBoxLayout() tabLayout.setMargin(0) self.canvas = QgsMapCanvas(self.tabCanvas) self.canvas.setCanvasColor(Qt.white) self.panTool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.panTool) tabLayout.addWidget(self.canvas) self.labelNoChanges = QLabel("This commit doesn't change any geometry") self.labelNoChanges.setAlignment(Qt.AlignCenter) self.labelNoChanges.setVisible(False) tabLayout.addWidget(self.labelNoChanges) self.tabCanvas.setLayout(tabLayout) self.summaryTextBrowser = QTextBrowser() self.summaryTextBrowser.setOpenLinks(False) self.summaryTextBrowser.anchorClicked.connect(self.summaryTextBrowserAnchorClicked) self.tabWidget.addTab(self.summaryTextBrowser, "Commit Summary") self.tabWidget.addTab(self.tabCanvas, "Map") tabLayout = QVBoxLayout() tabLayout.setMargin(0) self.tabDiffViewer = QWidget() self.diffViewer = DiffViewerWidget({}) tabLayout.addWidget(self.diffViewer) self.tabDiffViewer.setLayout(tabLayout) self.tabWidget.addTab(self.tabDiffViewer, "Attributes") splitter.addWidget(self.tabWidget) self.label = QTextBrowser() self.label.setVisible(False) splitter.addWidget(self.label) self.tabWidget.setCurrentWidget(self.tabDiffViewer) layout.addWidget(splitter) self.setLayout(layout) exportDiffButton = QPushButton("Export this commit's DIFF for all layers") exportDiffButton.clicked.connect(self.exportDiffAllLayers) layout.addWidget(exportDiffButton) self.label.setMinimumHeight(self.tabWidget.height()) self.setWindowTitle("Repository history")
def setupUi(self, GHydraulicsResultDialog): GHydraulicsResultDialog.setObjectName(_fromUtf8("GHydraulicsResultDialog")) GHydraulicsResultDialog.resize(640, 480) self.buttonBox = QDialogButtonBox(GHydraulicsResultDialog) self.buttonBox.setGeometry(QtCore.QRect(10, 440, 620, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.tabWidget = QTabWidget(GHydraulicsResultDialog) self.tabWidget.setGeometry(QtCore.QRect(10, 10, 620, 390)) self.tabWidget.setObjectName(_fromUtf8("tabWidget")) self.tabOutput = QWidget() self.tabOutput.setObjectName(_fromUtf8("tabOutput")) self.textOutput = QTextBrowser(self.tabOutput) self.textOutput.setGeometry(QtCore.QRect(10, 10, 600, 340)) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.textOutput.sizePolicy().hasHeightForWidth()) self.textOutput.setSizePolicy(sizePolicy) self.textOutput.setObjectName(_fromUtf8("textOutput")) self.tabWidget.addTab(self.tabOutput, _fromUtf8("")) self.tabReport = QWidget() self.tabReport.setObjectName(_fromUtf8("tabReport")) self.textReport = QTextBrowser(self.tabReport) self.textReport.setGeometry(QtCore.QRect(10, 10, 600, 340)) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.textReport.sizePolicy().hasHeightForWidth()) self.textReport.setSizePolicy(sizePolicy) self.textReport.setObjectName(_fromUtf8("textReport")) self.tabWidget.addTab(self.tabReport, _fromUtf8("")) self.comboStep = QComboBox(GHydraulicsResultDialog) self.comboStep.setGeometry(QtCore.QRect(150, 410, 80, 27)) self.comboStep.setObjectName(_fromUtf8("comboStep")) self.labelStep = QLabel(GHydraulicsResultDialog) self.labelStep.setGeometry(QtCore.QRect(10, 415, 120, 17)) self.labelStep.setObjectName(_fromUtf8("labelStep")) self.retranslateUi(GHydraulicsResultDialog) self.tabWidget.setCurrentIndex(0) #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), GHydraulicsResultDialog.accept) self.buttonBox.accepted.connect(GHydraulicsResultDialog.accept) #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), GHydraulicsResultDialog.reject) self.buttonBox.rejected.connect(GHydraulicsResultDialog.reject) QtCore.QMetaObject.connectSlotsByName(GHydraulicsResultDialog)
def initGui(self): layout = QVBoxLayout() self.tab = QTabWidget() self.table = QTableView() self.setLayout(layout) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) settings = QSettings() self.canvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type = bool)) self.canvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type = bool)) self.canvas.mapSettings().setDestinationCrs(self.crs) action = settings.value("/qgis/wheel_action", 0, type = float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type = float) self.canvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) self.panTool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.panTool) execute(self.createLayers) model = GeomDiffTableModel(self.data) self.table.setModel(model) self.table.resizeColumnsToContents() self.table.resizeRowsToContents() self.tab.addTab(self.canvas, "Map view") self.tab.addTab(self.table, "Table view") layout.addWidget(self.tab) self.resize(600, 500) self.setWindowTitle("Geometry comparison")
def _init_gui(self): self._gl = QGridLayout(self) self._label = QLabel(self) self._label.setText(self.tr('Select document type')) self._gl.addWidget(self._label, 0, 0, 1, 1) self._cbo_doc_type = QComboBox(self) self._gl.addWidget(self._cbo_doc_type, 0, 1, 1, 1) self._btn_add_document = QPushButton(self) doc_ico = GuiUtils.get_icon('document.png') self._btn_add_document.setIcon(doc_ico) self._btn_add_document.setText(self.tr('Add document...')) self._btn_add_document.setMaximumWidth(200) self._gl.addWidget(self._btn_add_document, 0, 2, 1, 1) self._doc_tab_container = QTabWidget(self) self._gl.addWidget(self._doc_tab_container, 1, 0, 1, 3) self.setMinimumHeight(140)
def setup_ui(self, dock_widget): """ initiate main Qt building blocks of interface :param dock_widget: QDockWidget instance """ dock_widget.setObjectName("dock_widget") dock_widget.setAttribute(Qt.WA_DeleteOnClose) self.dockWidgetContent = QWidget(self) self.dockWidgetContent.setObjectName("dockWidgetContent") self.mainVLayout = QVBoxLayout(self.dockWidgetContent) self.dockWidgetContent.setLayout(self.mainVLayout) # add button to add objects to graphs self.buttonBarHLayout = QHBoxLayout(self) self.addSelectedObjectButton = QPushButton(self.dockWidgetContent) self.addSelectedObjectButton.setObjectName("addSelectedObjectButton") self.checkbox = QCheckBox("Absolute", parent=self.dockWidgetContent) self.checkbox.setChecked(False) self.checkbox.stateChanged.connect(self.on_btnstate) self.buttonBarHLayout.addWidget(self.addSelectedObjectButton) self.buttonBarHLayout.addWidget(self.checkbox) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.buttonBarHLayout.addItem(spacerItem) self.mainVLayout.addItem(self.buttonBarHLayout) # add tabWidget for graphWidgets self.graphTabWidget = QTabWidget(self.dockWidgetContent) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(6) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.graphTabWidget.sizePolicy().hasHeightForWidth()) self.graphTabWidget.setSizePolicy(sizePolicy) self.graphTabWidget.setObjectName("graphTabWidget") self.mainVLayout.addWidget(self.graphTabWidget) # add dockwidget dock_widget.setWidget(self.dockWidgetContent) self.retranslate_ui(dock_widget) QMetaObject.connectSlotsByName(dock_widget)
def createTabs(): # Tab1 lyt1 = QVBoxLayout() lytOk = QHBoxLayout() rbUpdate = QRadioButton('Update', self) lytOk.addWidget(rbUpdate) rbDownload = QRadioButton('Download(0 selected)', self) lytOk.addWidget(rbDownload) btnOk = QPushButton('OK', self) lytOk.addWidget(btnOk) lyt1.addLayout(lytOk) lytChecks = QHBoxLayout() ckVrt = QCheckBox('Create VRT tiles', self) lytChecks.addWidget(ckVrt) ckAddTiles = QCheckBox('Add tiles', self) lytChecks.addWidget(ckAddTiles) lyt1.addLayout(lytChecks) tab1 = QWidget() tab1.setLayout(lyt1) # Tab 2 lyt2 = QVBoxLayout() wgtDir = QgsFileWidget(self) lyt2.addWidget(wgtDir) btnRemoveFiles = QPushButton('', self) lyt2.addWidget(btnRemoveFiles) tab2 = QWidget() tab2.setLayout(lyt2) # tabs = QTabWidget(self) tabs.addTab(tab1, 'Update/Download') tabs.addTab(tab2, 'Download directory') return (tabs, rbUpdate, rbDownload, btnOk, ckVrt, ckAddTiles, wgtDir, btnRemoveFiles)
def createButtonsWithTabs(self, reclassificationDict): """ Specific method to create buttons with tabs reclassificationDict: dictionary used to create the buttons """ gridLayout = QGridLayout() tabWidget = QTabWidget() tabWidget.setTabPosition(QTabWidget.West) gridLayout.addWidget(tabWidget) self.scrollArea.setWidget(tabWidget) propertyDict = dict() for category in list(reclassificationDict.keys()): if category in ['version', 'uiParameterJsonDict']: continue sortedButtonNames = [] formLayout = QFormLayout() scrollArea = self.createWidgetWithTabs(formLayout) tabWidget.addTab(scrollArea, category) for edgvClass in list(reclassificationDict[category].keys()): for button in list( reclassificationDict[category][edgvClass].keys()): item = reclassificationDict[category][edgvClass][button] propertyDict[button] = dict() if isinstance(item, dict): if 'buttonProp' in list(item.keys()): propertyDict[button] = item['buttonProp'] sortedButtonNames.append(button) sortedButtonNames.sort() for button in sortedButtonNames: pushButton = self.createButton( button, propertyDict=propertyDict[button]) formLayout.addRow(pushButton)
def __init__(self, parent=None, iface=None): QTabWidget.__init__(self, parent) self.setupUi(self) self.setTabIcon(0, GuiUtils.get_icon('local.png')) self.setTabIcon(1, GuiUtils.get_icon('web.png')) self._notif_bar = None self._ol_loaded = False self._overlay_layer = None self.sel_highlight = None self.memory_layer = None self._db_session = STDMDb.instance().session self.set_iface(iface) # Web config self._web_spatial_loader = WebSpatialLoader(self.spatial_web_view, self) # Connect signals self._web_spatial_loader.loadError.connect( self.on_spatial_browser_error) self._web_spatial_loader.loadProgress.connect( self.on_spatial_browser_loading) self._web_spatial_loader.loadFinished.connect( self.on_spatial_browser_finished) self._web_spatial_loader.zoomChanged.connect( self.on_map_zoom_level_changed) self.rbGMaps.toggled.connect(self.on_load_GMaps) self.rbOSM.toggled.connect(self.on_load_OSM) self.zoomSlider.sliderReleased.connect(self.on_zoom_changed) self.btnResetMap.clicked.connect(self.on_reset_web_map) self.btnSync.clicked.connect(self.on_sync_extents) QgsProject.instance().layersWillBeRemoved.connect( self._on_overlay_to_be_removed)
def setupUi(self): self.setWindowTitle(self.tr("DB Manager")) self.setWindowIcon(QIcon(":/db_manager/icon")) self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint())) # create central tab widget and add the first 3 tabs: info, table and preview self.tabs = QTabWidget() self.info = InfoViewer(self) self.tabs.addTab(self.info, self.tr("Info")) self.table = TableViewer(self) self.tabs.addTab(self.table, self.tr("Table")) self.preview = LayerPreview(self) self.tabs.addTab(self.preview, self.tr("Preview")) self.setCentralWidget(self.tabs) # display close button for all tabs but the first 3 ones, i.e. # HACK: just hide the close button where not needed (GS) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) tabbar = self.tabs.tabBar() for i in range(3): btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide) btn.resize(0, 0) btn.hide() # Creates layout for message bar self.layout = QGridLayout(self.info) self.layout.setContentsMargins(0, 0, 0, 0) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.layout.addItem(spacerItem, 1, 0, 1, 1) # init messageBar instance self.infoBar = QgsMessageBar(self.info) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.infoBar.setSizePolicy(sizePolicy) self.layout.addWidget(self.infoBar, 0, 0, 1, 1) # create database tree self.dock = QDockWidget("Tree", self) self.dock.setObjectName("DB_Manager_DBView") self.dock.setFeatures(QDockWidget.DockWidgetMovable) self.tree = DBTree(self) self.dock.setWidget(self.tree) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock) # create status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) # create menus self.menuBar = QMenuBar(self) self.menuDb = QMenu(self.tr("&Database"), self) self.menuBar.addMenu(self.menuDb) self.menuSchema = QMenu(self.tr("&Schema"), self) actionMenuSchema = self.menuBar.addMenu(self.menuSchema) self.menuTable = QMenu(self.tr("&Table"), self) actionMenuTable = self.menuBar.addMenu(self.menuTable) self.menuHelp = None # QMenu(self.tr("&Help"), self) # actionMenuHelp = self.menuBar.addMenu(self.menuHelp) self.setMenuBar(self.menuBar) # create toolbar self.toolBar = QToolBar("Default", self) self.toolBar.setObjectName("DB_Manager_ToolBar") self.addToolBar(self.toolBar) # create menus' actions # menu DATABASE sep = self.menuDb.addSeparator() sep.setObjectName("DB_Manager_DbMenu_placeholder") sep.setVisible(False) self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"), self.refreshActionSlot, QKeySequence("F5")) self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"), self.runSqlWindow, QKeySequence("F2")) self.menuDb.addSeparator() self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q")) # menu SCHEMA sep = self.menuSchema.addSeparator() sep.setObjectName("DB_Manager_SchemaMenu_placeholder") sep.setVisible(False) actionMenuSchema.setVisible(False) # menu TABLE sep = self.menuTable.addSeparator() sep.setObjectName("DB_Manager_TableMenu_placeholder") sep.setVisible(False) self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"), self.tr("&Import layer/file"), self.importActionSlot) self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"), self.exportActionSlot) self.menuTable.addSeparator() #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables) #self.actionShowSystemTables.setCheckable(True) #self.actionShowSystemTables.setChecked(True) actionMenuTable.setVisible(False) # add actions to the toolbar self.toolBar.addAction(self.actionRefresh) self.toolBar.addAction(self.actionSqlWindow) self.toolBar.addAction(self.actionImport) self.toolBar.addAction(self.actionExport)
class DBManager(QMainWindow): def __init__(self, iface, parent=None): QMainWindow.__init__(self, parent) self.setAttribute(Qt.WA_DeleteOnClose) self.setupUi() self.iface = iface # restore the window state settings = QgsSettings() self.restoreGeometry(settings.value("/DB_Manager/mainWindow/geometry", QByteArray(), type=QByteArray)) self.restoreState(settings.value("/DB_Manager/mainWindow/windowState", QByteArray(), type=QByteArray)) self.tabs.currentChanged.connect(self.tabChanged) self.tree.selectedItemChanged.connect(self.itemChanged) self.tree.model().dataChanged.connect(self.iface.reloadConnections) self.itemChanged(None) def closeEvent(self, e): self.unregisterAllActions() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) # save the window state settings = QgsSettings() settings.setValue("/DB_Manager/mainWindow/windowState", self.saveState()) settings.setValue("/DB_Manager/mainWindow/geometry", self.saveGeometry()) QMainWindow.closeEvent(self, e) def refreshItem(self, item=None): with OverrideCursor(Qt.WaitCursor): try: if item is None: item = self.tree.currentItem() self.tree.refreshItem(item) # refresh item children in the db tree except BaseError as e: DlgDbError.showError(e, self) def itemChanged(self, item): with OverrideCursor(Qt.WaitCursor): try: self.reloadButtons() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def reloadButtons(self): db = self.tree.currentDatabase() if not hasattr(self, '_lastDb'): self._lastDb = db elif db == self._lastDb: return # remove old actions if self._lastDb is not None: self.unregisterAllActions() # add actions of the selected database self._lastDb = db if self._lastDb is not None: self._lastDb.registerAllActions(self) def tabChanged(self, index): with OverrideCursor(Qt.WaitCursor): try: self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def refreshTabs(self): index = self.tabs.currentIndex() item = self.tree.currentItem() table = self.tree.currentTable() # enable/disable tabs self.tabs.setTabEnabled(self.tabs.indexOf(self.table), table is not None) self.tabs.setTabEnabled(self.tabs.indexOf(self.preview), table is not None and table.type in [table.VectorType, table.RasterType] and table.geomColumn is not None) # show the info tab if the current tab is disabled if not self.tabs.isTabEnabled(index): self.tabs.setCurrentWidget(self.info) current_tab = self.tabs.currentWidget() if current_tab == self.info: self.info.showInfo(item) elif current_tab == self.table: self.table.loadData(item) elif current_tab == self.preview: self.preview.loadPreview(item) def refreshActionSlot(self): self.info.setDirty() self.table.setDirty() self.preview.setDirty() self.refreshItem() def importActionSlot(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), Qgis.Info, self.iface.messageTimeout()) return outUri = db.uri() schema = self.tree.currentSchema() if schema: outUri.setDataSource(schema.name, "", "", "") from .dlg_import_vector import DlgImportVector dlg = DlgImportVector(None, db, outUri, self) dlg.exec_() def exportActionSlot(self): table = self.tree.currentTable() if table is None: self.infoBar.pushMessage(self.tr("Select the table you want export to file."), Qgis.Info, self.iface.messageTimeout()) return inLayer = table.toMapLayer() if inLayer.type() != QgsMapLayer.VectorLayer: self.infoBar.pushMessage( self.tr("Select a vector or a tabular layer you want export."), Qgis.Warning, self.iface.messageTimeout()) return from .dlg_export_vector import DlgExportVector dlg = DlgExportVector(inLayer, table.database(), self) dlg.exec_() inLayer.deleteLater() def runSqlWindow(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), Qgis.Info, self.iface.messageTimeout()) # force displaying of the message, it appears on the first tab (i.e. Info) self.tabs.setCurrentIndex(0) return from .dlg_sql_window import DlgSqlWindow query = DlgSqlWindow(self.iface, db, self) dbname = db.connection().connectionName() tabname = self.tr("Query ({0})").format(dbname) index = self.tabs.addTab(query, tabname) self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) query.nameChanged.connect(functools.partial(self.update_query_tab_name, index, dbname)) def runSqlLayerWindow(self, layer): from .dlg_sql_layer_window import DlgSqlLayerWindow query = DlgSqlLayerWindow(self.iface, layer, self) lname = layer.name() tabname = self.tr("Layer ({0})").format(lname) index = self.tabs.addTab(query, tabname) # self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) def update_query_tab_name(self, index, dbname, queryname): if not queryname: queryname = self.tr("Query") tabname = u"%s (%s)" % (queryname, dbname) self.tabs.setTabText(index, tabname) def showSystemTables(self): self.tree.showSystemTables(self.actionShowSystemTables.isChecked()) def registerAction(self, action, menuName, callback=None): """ register an action to the manager's main menu """ if not hasattr(self, '_registeredDbActions'): self._registeredDbActions = {} if callback is not None: def invoke_callback(x): return self.invokeCallback(callback) if menuName is None or menuName == "": self.addAction(action) if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True # search for the menu actionMenu = None helpMenuAction = None for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue if a.menu() != self.menuHelp: helpMenuAction = a actionMenu = a break # not found, add a new menu before the help menu if actionMenu is None: menu = QMenu(menuName, self) if helpMenuAction is not None: actionMenu = self.menuBar.insertMenu(helpMenuAction, menu) else: actionMenu = self.menuBar.addMenu(menu) menu = actionMenu.menu() menuActions = menu.actions() # get the placeholder's position to insert before it pos = 0 for pos in range(len(menuActions)): if menuActions[pos].isSeparator() and menuActions[pos].objectName().endswith("_placeholder"): menuActions[pos].setVisible(True) break if pos < len(menuActions): before = menuActions[pos] menu.insertAction(before, action) else: menu.addAction(action) actionMenu.setVisible(True) # show the menu if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True def invokeCallback(self, callback, *params): """ Call a method passing the selected item in the database tree, the sender (usually a QAction), the plugin mainWindow and optionally additional parameters. This method takes care to override and restore the cursor, but also catches exceptions and displays the error dialog. """ with OverrideCursor(Qt.WaitCursor): try: callback(self.tree.currentItem(), self.sender(), self, *params) except BaseError as e: # catch database errors and display the error dialog DlgDbError.showError(e, self) def unregisterAction(self, action, menuName): if not hasattr(self, '_registeredDbActions'): return if menuName is None or menuName == "": self.removeAction(action) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) action.deleteLater() return True for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue menu = a.menu() menuActions = menu.actions() menu.removeAction(action) if menu.isEmpty(): # hide the menu a.setVisible(False) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) # hide the placeholder if there're no other registered actions if len(self._registeredDbActions[menuName]) <= 0: for i in range(len(menuActions)): if menuActions[i].isSeparator() and menuActions[i].objectName().endswith("_placeholder"): menuActions[i].setVisible(False) break action.deleteLater() return True return False def unregisterAllActions(self): if not hasattr(self, '_registeredDbActions'): return for menuName in self._registeredDbActions: for action in list(self._registeredDbActions[menuName]): self.unregisterAction(action, menuName) del self._registeredDbActions def close_tab(self, index): widget = self.tabs.widget(index) if widget not in [self.info, self.table, self.preview]: self.tabs.removeTab(index) widget.deleteLater() def setupUi(self): self.setWindowTitle(self.tr("DB Manager")) self.setWindowIcon(QIcon(":/db_manager/icon")) self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint())) # create central tab widget and add the first 3 tabs: info, table and preview self.tabs = QTabWidget() self.info = InfoViewer(self) self.tabs.addTab(self.info, self.tr("Info")) self.table = TableViewer(self) self.tabs.addTab(self.table, self.tr("Table")) self.preview = LayerPreview(self) self.tabs.addTab(self.preview, self.tr("Preview")) self.setCentralWidget(self.tabs) # display close button for all tabs but the first 3 ones, i.e. # HACK: just hide the close button where not needed (GS) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) tabbar = self.tabs.tabBar() for i in range(3): btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide) btn.resize(0, 0) btn.hide() # Creates layout for message bar self.layout = QGridLayout(self.info) self.layout.setContentsMargins(0, 0, 0, 0) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.layout.addItem(spacerItem, 1, 0, 1, 1) # init messageBar instance self.infoBar = QgsMessageBar(self.info) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.infoBar.setSizePolicy(sizePolicy) self.layout.addWidget(self.infoBar, 0, 0, 1, 1) # create database tree self.dock = QDockWidget("Tree", self) self.dock.setObjectName("DB_Manager_DBView") self.dock.setFeatures(QDockWidget.DockWidgetMovable) self.tree = DBTree(self) self.dock.setWidget(self.tree) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock) # create status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) # create menus self.menuBar = QMenuBar(self) self.menuDb = QMenu(self.tr("&Database"), self) self.menuBar.addMenu(self.menuDb) self.menuSchema = QMenu(self.tr("&Schema"), self) actionMenuSchema = self.menuBar.addMenu(self.menuSchema) self.menuTable = QMenu(self.tr("&Table"), self) actionMenuTable = self.menuBar.addMenu(self.menuTable) self.menuHelp = None # QMenu(self.tr("&Help"), self) # actionMenuHelp = self.menuBar.addMenu(self.menuHelp) self.setMenuBar(self.menuBar) # create toolbar self.toolBar = QToolBar("Default", self) self.toolBar.setObjectName("DB_Manager_ToolBar") self.addToolBar(self.toolBar) # create menus' actions # menu DATABASE sep = self.menuDb.addSeparator() sep.setObjectName("DB_Manager_DbMenu_placeholder") sep.setVisible(False) self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"), self.refreshActionSlot, QKeySequence("F5")) self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"), self.runSqlWindow, QKeySequence("F2")) self.menuDb.addSeparator() self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q")) # menu SCHEMA sep = self.menuSchema.addSeparator() sep.setObjectName("DB_Manager_SchemaMenu_placeholder") sep.setVisible(False) actionMenuSchema.setVisible(False) # menu TABLE sep = self.menuTable.addSeparator() sep.setObjectName("DB_Manager_TableMenu_placeholder") sep.setVisible(False) self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"), self.tr("&Import layer/file"), self.importActionSlot) self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"), self.exportActionSlot) self.menuTable.addSeparator() #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables) #self.actionShowSystemTables.setCheckable(True) #self.actionShowSystemTables.setChecked(True) actionMenuTable.setVisible(False) # add actions to the toolbar self.toolBar.addAction(self.actionRefresh) self.toolBar.addAction(self.actionSqlWindow) self.toolBar.addAction(self.actionImport) self.toolBar.addAction(self.actionExport)
class OutputAnalyserDialog(QDialog): def __init__(self, iface, parent, params): QDialog.__init__(self, parent) self.iface = iface self.parent = parent self.params = params self.output_reader = None self.tool = None self.element_ids_nodes = None self.element_ids_links = None self.nodes_lay = None self.links_lay = None self.setWindowTitle(Parameters.plug_in_name) # Selection changed listeners self.params.junctions_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.reservoirs_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.tanks_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.pipes_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.pumps_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.valves_vlay.selectionChanged.connect(self.feature_sel_changed) # self.setMinimumWidth(min_width) # self.setMinimumHeight(min_height) fra_main_lay = QVBoxLayout(self) self.fra_out_file = QFrame(self) fra_out_file_lay = QHBoxLayout(self.fra_out_file) self.lbl_out_file = QLabel('Simulation output file:') self.txt_out_file = QLineEdit('') self.txt_out_file.setReadOnly(True) self.btn_out_file = QToolButton() self.btn_out_file.setText('...') self.btn_out_file.clicked.connect(self.btn_out_file_clicked) fra_out_file_lay.addWidget(self.lbl_out_file) fra_out_file_lay.addWidget(self.txt_out_file) fra_out_file_lay.addWidget(self.btn_out_file) self.tab_widget = QTabWidget(self) # Graphs tab --------------------------------------------------------------------------------------------------- self.tab_graphs = QWidget() tab_graphs_lay = QHBoxLayout(self.tab_graphs) # Left frame self.fra_graphs_left = QFrame() self.fra_graphs_left.setMaximumWidth(100) fra_graphs_left_lay = QVBoxLayout(self.fra_graphs_left) self.btn_sel_element = QPushButton('Pick') self.btn_sel_element.clicked.connect(self.btn_sel_element_clicked) fra_graphs_left_lay.addWidget(self.btn_sel_element) # Nodes self.grb_nodes = QGroupBox(u'Nodes') lay_grb_nodes = QVBoxLayout(self.grb_nodes) self.chk_node_demand = QCheckBox('Demand') lay_grb_nodes.addWidget(self.chk_node_demand) self.chk_node_head = QCheckBox('Head') lay_grb_nodes.addWidget(self.chk_node_head) self.chk_node_pressure = QCheckBox('Pressure') lay_grb_nodes.addWidget(self.chk_node_pressure) self.chk_node_quality = QCheckBox('Quality') lay_grb_nodes.addWidget(self.chk_node_quality) fra_graphs_left_lay.addWidget(self.grb_nodes) # Links self.grb_links = QGroupBox(u'Links') lay_grb_links = QVBoxLayout(self.grb_links) self.chk_link_flow = QCheckBox('Flow') lay_grb_links.addWidget(self.chk_link_flow) self.chk_link_velocity = QCheckBox('Velocity') lay_grb_links.addWidget(self.chk_link_velocity) self.chk_link_headloss = QCheckBox('Headloss') lay_grb_links.addWidget(self.chk_link_headloss) self.chk_link_quality = QCheckBox('Quality') lay_grb_links.addWidget(self.chk_link_quality) fra_graphs_left_lay.addWidget(self.grb_links) self.btn_draw_graph = QPushButton('Draw') self.btn_draw_graph.clicked.connect(self.draw_graphs) fra_graphs_left_lay.addWidget(self.btn_draw_graph) self.spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) fra_graphs_left_lay.addItem(self.spacer) tab_graphs_lay.addWidget(self.fra_graphs_left) # Right frame self.fra_graphs_right = QFrame() fra_graphs_right_lay = QVBoxLayout(self.fra_graphs_right) fra_graphs_right_lay.setContentsMargins(0, 0, 0, 0) self.static_canvas = StaticMplCanvas(self.fra_graphs_right, width=5, height=4, dpi=100) fra_graphs_right_lay.addWidget(self.static_canvas) tab_graphs_lay.addWidget(self.fra_graphs_right) # lay.addWidget(self.button) self.tab_widget.addTab(self.tab_graphs, 'Graphs') # Maps tab ----------------------------------------------------------------------------------------------------- self.tab_maps = QWidget() tab_maps_lay = QHBoxLayout(self.tab_maps) # Left frame self.fra_maps_left = QFrame() self.fra_maps_left.setMaximumWidth(200) fra_maps_left_lay = QVBoxLayout(self.fra_maps_left) self.grb_maps = QGroupBox(u'Variable') grb_maps_lay = QVBoxLayout(self.grb_maps) self.rad_maps_node_demand = QRadioButton(u'Node demand') grb_maps_lay.addWidget(self.rad_maps_node_demand) self.rad_maps_node_head = QRadioButton(u'Node head') grb_maps_lay.addWidget(self.rad_maps_node_head) self.rad_maps_node_pressure = QRadioButton(u'Node pressure') grb_maps_lay.addWidget(self.rad_maps_node_pressure) self.rad_maps_node_quality = QRadioButton(u'Node quality') grb_maps_lay.addWidget(self.rad_maps_node_quality) self.rad_maps_link_flow = QRadioButton(u'Link flow') grb_maps_lay.addWidget(self.rad_maps_link_flow) self.rad_maps_link_velocity = QRadioButton(u'Link velocity') grb_maps_lay.addWidget(self.rad_maps_link_velocity) self.rad_maps_link_headloss = QRadioButton(u'Link headloss') grb_maps_lay.addWidget(self.rad_maps_link_headloss) self.rad_maps_link_quality = QRadioButton(u'Link quality') grb_maps_lay.addWidget(self.rad_maps_link_quality) fra_maps_left_lay.addWidget(self.grb_maps) fra_maps_left_lay.addItem(self.spacer) tab_maps_lay.addWidget(self.fra_maps_left) # Right maps frame self.fra_maps_right = QFrame() fra_maps_right_lay = QVBoxLayout(self.fra_maps_right) self.fra_maps_right_time = QFrame() fra_maps_right_time_lay = QFormLayout(self.fra_maps_right_time) self.lbl_map_times = QLabel(u'Period [h]:') self.cbo_map_times = QComboBox() fra_maps_right_time_lay.addRow(self.lbl_map_times, self.cbo_map_times) fra_maps_right_lay.addWidget(self.fra_maps_right_time) self.btn_draw_map = QPushButton(u'Draw map') self.btn_draw_map.clicked.connect(self.draw_maps) fra_maps_right_lay.addWidget(self.btn_draw_map) fra_maps_right_lay.addItem(self.spacer) tab_maps_lay.addWidget(self.fra_maps_right) self.tab_widget.addTab(self.tab_maps, 'Maps') # # Add to main fra_main_lay.addWidget(self.fra_out_file) fra_main_lay.addWidget(self.tab_widget) self.setup() self.initialize() # self.read_outputs() # Set size self.setMinimumWidth(self.tab_graphs.width()) self.setMinimumHeight(self.tab_graphs.height()) def setup(self): pass def btn_out_file_clicked(self): config_file = ConfigFile(Parameters.config_file_path) out_file, __ = QFileDialog.getOpenFileName( self, 'Select out file', config_file.get_last_out_file(), 'Out files (*.out)') if out_file is None or out_file == '': return config_file.set_last_out_file(out_file) self.txt_out_file.setText(out_file) self.read_outputs() if self.output_reader is None: return # Fill times combo self.cbo_map_times.clear() for period_s in self.output_reader.period_results.keys(): text = self.seconds_to_string( period_s, self.output_reader.sim_duration_secs, self.output_reader.report_time_step_secs) self.cbo_map_times.addItem(text, period_s) # Activate widgets self.btn_sel_element.setEnabled(self.output_reader is not None) self.btn_draw_graph.setEnabled(self.output_reader is not None) self.grb_maps.setEnabled(self.output_reader is not None) self.btn_draw_map.setEnabled(self.output_reader is not None) def initialize(self): # Graphs self.grb_nodes.setEnabled(False) self.grb_links.setEnabled(False) self.btn_sel_element.setEnabled(self.output_reader is not None) self.btn_draw_graph.setEnabled(self.output_reader is not None) # Maps self.grb_maps.setEnabled(self.output_reader is not None) self.rad_maps_node_demand.setChecked(True) self.btn_draw_map.setEnabled(self.output_reader is not None) def feature_sel_changed(self): is_nodes = False sel_junctions = self.params.junctions_vlay.selectedFeatureCount() sel_reservoirs = self.params.reservoirs_vlay.selectedFeatureCount() sel_tanks = self.params.tanks_vlay.selectedFeatureCount() if sel_junctions > 0 or sel_reservoirs > 0 or sel_tanks > 0: is_nodes = True self.grb_nodes.setEnabled(is_nodes) is_links = False sel_pipes = self.params.pipes_vlay.selectedFeatureCount() sel_pumps = self.params.pumps_vlay.selectedFeatureCount() sel_valves = self.params.valves_vlay.selectedFeatureCount() if sel_pipes > 0 or sel_pumps > 0 or sel_valves > 0: is_links = True self.grb_links.setEnabled(is_links) def read_outputs(self): try: QApplication.setOverrideCursor(Qt.WaitCursor) self.output_reader = BinaryOutputReader() self.output_reader.read(self.txt_out_file.text()) QApplication.restoreOverrideCursor() # Check if output compatible with loaded project compatible = True out_nodes_nr = self.output_reader.nodes_nr out_tanks_reservs_nr = self.output_reader.tanks_reservs_nr out_juncts_nr = out_nodes_nr - out_tanks_reservs_nr out_links_nr = self.output_reader.links_nr out_pumps_nr = self.output_reader.pumps_nr out_valves_nr = self.output_reader.valves_nr out_pipes_nr = out_links_nr - out_pumps_nr - out_valves_nr if out_juncts_nr != self.params.junctions_vlay.featureCount(): compatible = False if out_tanks_reservs_nr != (self.params.reservoirs_vlay.featureCount() + self.params.tanks_vlay.featureCount()): compatible = False if out_pipes_nr != self.params.pipes_vlay.featureCount(): compatible = False if out_valves_nr != self.params.valves_vlay.featureCount(): compatible = False if out_pumps_nr != self.params.pumps_vlay.featureCount(): compatible = False if not compatible: message = 'The out file appears to incompatible with the actual project layers.' QMessageBox.warning( self, Parameters.plug_in_name, message, QMessageBox.Ok) self.output_reader = None self.txt_out_file.setText('') else: # Message after reading completed message = 'Out file loaded: ' + str(out_nodes_nr) + ' nodes, ' + str(out_links_nr) + ' links found.' # Clear refs to output layer self.params.out_lay_node_demand = None self.params.out_lay_node_head = None self.params.out_lay_node_pressure = None self.params.out_lay_node_quality = None self.params.out_lay_link_flow = None self.params.out_lay_link_velocity = None self.params.out_lay_link_headloss = None self.params.out_lay_link_quality = None QMessageBox.information( self, Parameters.plug_in_name, message, QMessageBox.Ok) finally: # self.iface.messageBar().pushWarning( # Parameters.plug_in_name, # 'Error while reading output file.') # TODO: softcode # self.output_reader = None # self.txt_out_file.setText('') QApplication.restoreOverrideCursor() def btn_sel_element_clicked(self): if self.output_reader is None: self.iface.messageBar().pushMessage( Parameters.plug_in_name, 'Please select the simulation out file.', Qgis.Warning, 5) # TODO: softcode return self.tool = SelectTool(self, self.params) self.iface.mapCanvas().setMapTool(self.tool) cursor = QCursor() cursor.setShape(Qt.ArrowCursor) self.iface.mapCanvas().setCursor(cursor) def draw_graphs(self): # Get selected features self.element_ids_nodes = [] for junction_feat in self.params.junctions_vlay.selectedFeatures(): self.element_ids_nodes.append(junction_feat.attribute(Junction.field_name_eid)) for reservoir_feat in self.params.reservoirs_vlay.selectedFeatures(): self.element_ids_nodes.append(reservoir_feat.attribute(Reservoir.field_name_eid)) for tank_feat in self.params.tanks_vlay.selectedFeatures(): self.element_ids_nodes.append(tank_feat.attribute(Tank.field_name_eid)) self.element_ids_links = [] for pipe_feat in self.params.pipes_vlay.selectedFeatures(): self.element_ids_links.append(pipe_feat.attribute(Pipe.field_name_eid)) for pump_feat in self.params.pumps_vlay.selectedFeatures(): self.element_ids_links.append(pump_feat.attribute(Pump.field_name_eid)) for valve_feat in self.params.valves_vlay.selectedFeatures(): self.element_ids_links.append(valve_feat.attribute(Valve.field_name_eid)) # Build values dictionaries xs = self.output_reader.report_times ys_d_d = {} params_count = 0 # Nodes if self.grb_nodes.isEnabled(): if self.chk_node_demand.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_nodes: ys_d[element_id] = [ self.output_reader.node_demands_d[element_id], self.params.options.flow_units] ys_d_d[OutputParamCodes.NODE_DEMAND] = ys_d if self.chk_node_head.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_nodes: ys_d[element_id] = [ self.output_reader.node_heads_d[element_id], Options.units_diameter_tanks[self.params.options.units]] ys_d_d[OutputParamCodes.NODE_HEAD] = ys_d if self.chk_node_pressure.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_nodes: ys_d[element_id] = [ self.output_reader.node_pressures_d[element_id], Options.units_pressure[self.params.options.units]] ys_d_d[OutputParamCodes.NODE_PRESSURE] = ys_d if self.chk_node_quality.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_nodes: ys_d[element_id] = [ self.output_reader.node_qualities_d[element_id], Quality.quality_units_text[self.params.options.quality.mass_units]] ys_d_d[OutputParamCodes.NODE_QUALITY] = ys_d # Links if self.grb_links.isEnabled(): if self.chk_link_flow.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_links: ys_d[element_id] = [ self.output_reader.link_flows_d[element_id], self.params.options.flow_units] ys_d_d[OutputParamCodes.LINK_FLOW] = ys_d if self.chk_link_velocity.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_links: ys_d[element_id] = [ self.output_reader.link_velocities_d[element_id], Options.units_velocity[self.params.options.units]] ys_d_d[OutputParamCodes.LINK_VELOCITY] = ys_d if self.chk_link_headloss.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_links: ys_d[element_id] = [ self.output_reader.link_headlosses_d[element_id], Options.units_diameter_tanks[self.params.options.units]] ys_d_d[OutputParamCodes.LINK_HEADLOSS] = ys_d if self.chk_link_quality.isChecked(): params_count += 1 ys_d = {} for element_id in self.element_ids_links: ys_d[element_id] = [ self.output_reader.link_qualities_d[element_id], Quality.quality_units_text[self.params.options.quality.mass_units]] ys_d_d[OutputParamCodes.LINK_QUALITY] = ys_d if ys_d_d: self.static_canvas.draw_output_line(xs, ys_d_d, params_count) def draw_maps(self): """ Draws layers with all the attributes :return: """ report_time = self.cbo_map_times.itemText(self.cbo_map_times.currentIndex()) if self.rad_maps_node_demand.isChecked(): # ------------------------------------------------------------------- lay_name = u'Node demand' lay_id = self.draw_map(LayerType.NODE, self.params.out_lay_node_demand_id, lay_name, self.output_reader.node_demands_d, report_time) self.params.out_lay_node_demand_id = lay_id elif self.rad_maps_node_head.isChecked(): lay_name = u'Node head' lay_id = self.draw_map(LayerType.NODE, self.params.out_lay_node_head_id, lay_name, self.output_reader.node_heads_d, report_time) self.params.out_lay_node_head_id = lay_id elif self.rad_maps_node_pressure.isChecked(): lay_name = u'Node pressure' lay_id = self.draw_map(LayerType.NODE, self.params.out_lay_node_pressure_id, lay_name, self.output_reader.node_pressures_d, report_time) self.params.out_lay_node_pressure_id = lay_id elif self.rad_maps_node_quality.isChecked(): lay_name = u'Node quality' lay_id = self.draw_map(LayerType.NODE, self.params.out_lay_node_quality_id, lay_name, self.output_reader.node_qualities_d, report_time) self.params.out_lay_node_quality_id = lay_id elif self.rad_maps_link_flow.isChecked(): # ------------------------------------------------------------------- lay_name = u'Link flow' lay_id = self.draw_map(LayerType.LINK, self.params.out_lay_link_flow_id, lay_name, self.output_reader.link_flows_d, report_time) self.params.out_lay_link_flow_id = lay_id elif self.rad_maps_link_velocity.isChecked(): lay_name = u'Link velocity' lay_id = self.draw_map(LayerType.LINK, self.params.out_lay_link_velocity_id, lay_name, self.output_reader.link_velocities_d, report_time) self.params.out_lay_link_velocity_id = lay_id elif self.rad_maps_link_headloss.isChecked(): lay_name = u'Link headloss' lay_id = self.draw_map(LayerType.LINK, self.params.out_lay_link_headloss_id, lay_name, self.output_reader.link_headlosses_d, report_time) self.params.out_lay_link_headloss_id = lay_id elif self.rad_maps_link_quality.isChecked(): lay_name = u'Link quality' lay_id = self.draw_map(LayerType.LINK, self.params.out_lay_link_quality_id, lay_name, self.output_reader.link_qualities_d, report_time) self.params.out_lay_link_quality_id = lay_id def draw_map(self, lay_type, lay_id, lay_name, dataset, report_time): try: QApplication.setOverrideCursor(Qt.WaitCursor) lay_name += ' ' + report_time lay = LayerUtils.get_lay_from_id(lay_id) if lay is None: if lay_type == LayerType.NODE: lay = self.create_out_node_layer(lay_name, dataset) ns = NodeSymbology() lay.setRenderer(ns.make_graduated_sym_renderer(lay, report_time)) elif lay_type == LayerType.LINK: lay = self.create_out_link_layer(lay_name, dataset) ls = LinkSymbology() lay.setRenderer(ls.make_flow_sym_renderer(lay, report_time)) lay_id = lay.id() QgsProject.instance().addMapLayer(lay) self.params.out_layers.append(lay) else: lay.setLayerName(lay_name) lay.triggerRepaint() QApplication.restoreOverrideCursor() finally: QApplication.restoreOverrideCursor() return lay_id def btn_cancel_clicked(self): self.setVisible(False) def btn_ok_clicked(self): pass def create_out_node_layer(self, lay_name, values_d): return self.create_out_layer(lay_name, values_d, LayerType.NODE) def create_out_link_layer(self, lay_name, values_d): return self.create_out_layer(lay_name, values_d, LayerType.LINK) def create_out_layer(self, lay_name, values_d, lay_type): field_name_vars = [] periods = list(self.output_reader.period_results.keys()) for period_s in periods: text = self.seconds_to_string( period_s, self.output_reader.sim_duration_secs, self.output_reader.report_time_step_secs) field_name_vars.append(text) if lay_type == LayerType.NODE: new_lay = MemoryDS.create_nodes_lay(self.params, field_name_vars, lay_name, self.params.crs) elif lay_type == LayerType.LINK: new_lay = MemoryDS.create_links_lay(self.params, field_name_vars, lay_name, self.params.crs) with edit(new_lay): # Update attributes for feat in new_lay.getFeatures(): fid = feat.id() eid = feat.attribute(Node.field_name_eid) values = values_d[eid] for p in range(len(periods)): new_lay.changeAttributeValue(fid, p+1, values[p]) return new_lay def seconds_to_string(self, period_s, duration_s, interval_s): day = int(math.floor(period_s / 86400)) hour = period_s / 3600 - day * 24 minute = period_s / 60 - day * 24 * 60 - hour * 60 second = period_s - day * 86400 - hour * 3600 - minute * 60 text = '' if duration_s >= 86400: # We need days text += str(day) + 'd' if duration_s >= 3600: # We need hours text += '{:02}'.format(hour) + 'H' text += '{:02}'.format(minute) + 'm' if second > 0: text += '{:02}'.format(second) + 's' return text
def __init__(self, iface, parent, params): QDialog.__init__(self, parent) self.iface = iface self.parent = parent self.params = params self.output_reader = None self.tool = None self.element_ids_nodes = None self.element_ids_links = None self.nodes_lay = None self.links_lay = None self.setWindowTitle(Parameters.plug_in_name) # Selection changed listeners self.params.junctions_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.reservoirs_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.tanks_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.pipes_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.pumps_vlay.selectionChanged.connect(self.feature_sel_changed) self.params.valves_vlay.selectionChanged.connect(self.feature_sel_changed) # self.setMinimumWidth(min_width) # self.setMinimumHeight(min_height) fra_main_lay = QVBoxLayout(self) self.fra_out_file = QFrame(self) fra_out_file_lay = QHBoxLayout(self.fra_out_file) self.lbl_out_file = QLabel('Simulation output file:') self.txt_out_file = QLineEdit('') self.txt_out_file.setReadOnly(True) self.btn_out_file = QToolButton() self.btn_out_file.setText('...') self.btn_out_file.clicked.connect(self.btn_out_file_clicked) fra_out_file_lay.addWidget(self.lbl_out_file) fra_out_file_lay.addWidget(self.txt_out_file) fra_out_file_lay.addWidget(self.btn_out_file) self.tab_widget = QTabWidget(self) # Graphs tab --------------------------------------------------------------------------------------------------- self.tab_graphs = QWidget() tab_graphs_lay = QHBoxLayout(self.tab_graphs) # Left frame self.fra_graphs_left = QFrame() self.fra_graphs_left.setMaximumWidth(100) fra_graphs_left_lay = QVBoxLayout(self.fra_graphs_left) self.btn_sel_element = QPushButton('Pick') self.btn_sel_element.clicked.connect(self.btn_sel_element_clicked) fra_graphs_left_lay.addWidget(self.btn_sel_element) # Nodes self.grb_nodes = QGroupBox(u'Nodes') lay_grb_nodes = QVBoxLayout(self.grb_nodes) self.chk_node_demand = QCheckBox('Demand') lay_grb_nodes.addWidget(self.chk_node_demand) self.chk_node_head = QCheckBox('Head') lay_grb_nodes.addWidget(self.chk_node_head) self.chk_node_pressure = QCheckBox('Pressure') lay_grb_nodes.addWidget(self.chk_node_pressure) self.chk_node_quality = QCheckBox('Quality') lay_grb_nodes.addWidget(self.chk_node_quality) fra_graphs_left_lay.addWidget(self.grb_nodes) # Links self.grb_links = QGroupBox(u'Links') lay_grb_links = QVBoxLayout(self.grb_links) self.chk_link_flow = QCheckBox('Flow') lay_grb_links.addWidget(self.chk_link_flow) self.chk_link_velocity = QCheckBox('Velocity') lay_grb_links.addWidget(self.chk_link_velocity) self.chk_link_headloss = QCheckBox('Headloss') lay_grb_links.addWidget(self.chk_link_headloss) self.chk_link_quality = QCheckBox('Quality') lay_grb_links.addWidget(self.chk_link_quality) fra_graphs_left_lay.addWidget(self.grb_links) self.btn_draw_graph = QPushButton('Draw') self.btn_draw_graph.clicked.connect(self.draw_graphs) fra_graphs_left_lay.addWidget(self.btn_draw_graph) self.spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) fra_graphs_left_lay.addItem(self.spacer) tab_graphs_lay.addWidget(self.fra_graphs_left) # Right frame self.fra_graphs_right = QFrame() fra_graphs_right_lay = QVBoxLayout(self.fra_graphs_right) fra_graphs_right_lay.setContentsMargins(0, 0, 0, 0) self.static_canvas = StaticMplCanvas(self.fra_graphs_right, width=5, height=4, dpi=100) fra_graphs_right_lay.addWidget(self.static_canvas) tab_graphs_lay.addWidget(self.fra_graphs_right) # lay.addWidget(self.button) self.tab_widget.addTab(self.tab_graphs, 'Graphs') # Maps tab ----------------------------------------------------------------------------------------------------- self.tab_maps = QWidget() tab_maps_lay = QHBoxLayout(self.tab_maps) # Left frame self.fra_maps_left = QFrame() self.fra_maps_left.setMaximumWidth(200) fra_maps_left_lay = QVBoxLayout(self.fra_maps_left) self.grb_maps = QGroupBox(u'Variable') grb_maps_lay = QVBoxLayout(self.grb_maps) self.rad_maps_node_demand = QRadioButton(u'Node demand') grb_maps_lay.addWidget(self.rad_maps_node_demand) self.rad_maps_node_head = QRadioButton(u'Node head') grb_maps_lay.addWidget(self.rad_maps_node_head) self.rad_maps_node_pressure = QRadioButton(u'Node pressure') grb_maps_lay.addWidget(self.rad_maps_node_pressure) self.rad_maps_node_quality = QRadioButton(u'Node quality') grb_maps_lay.addWidget(self.rad_maps_node_quality) self.rad_maps_link_flow = QRadioButton(u'Link flow') grb_maps_lay.addWidget(self.rad_maps_link_flow) self.rad_maps_link_velocity = QRadioButton(u'Link velocity') grb_maps_lay.addWidget(self.rad_maps_link_velocity) self.rad_maps_link_headloss = QRadioButton(u'Link headloss') grb_maps_lay.addWidget(self.rad_maps_link_headloss) self.rad_maps_link_quality = QRadioButton(u'Link quality') grb_maps_lay.addWidget(self.rad_maps_link_quality) fra_maps_left_lay.addWidget(self.grb_maps) fra_maps_left_lay.addItem(self.spacer) tab_maps_lay.addWidget(self.fra_maps_left) # Right maps frame self.fra_maps_right = QFrame() fra_maps_right_lay = QVBoxLayout(self.fra_maps_right) self.fra_maps_right_time = QFrame() fra_maps_right_time_lay = QFormLayout(self.fra_maps_right_time) self.lbl_map_times = QLabel(u'Period [h]:') self.cbo_map_times = QComboBox() fra_maps_right_time_lay.addRow(self.lbl_map_times, self.cbo_map_times) fra_maps_right_lay.addWidget(self.fra_maps_right_time) self.btn_draw_map = QPushButton(u'Draw map') self.btn_draw_map.clicked.connect(self.draw_maps) fra_maps_right_lay.addWidget(self.btn_draw_map) fra_maps_right_lay.addItem(self.spacer) tab_maps_lay.addWidget(self.fra_maps_right) self.tab_widget.addTab(self.tab_maps, 'Maps') # # Add to main fra_main_lay.addWidget(self.fra_out_file) fra_main_lay.addWidget(self.tab_widget) self.setup() self.initialize() # self.read_outputs() # Set size self.setMinimumWidth(self.tab_graphs.width()) self.setMinimumHeight(self.tab_graphs.height())
class ModelerParametersWidget(QWidget): def __init__(self, alg, model, algName=None, configuration=None, dialog=None, context=None): super().__init__() 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 = context self.dialog = dialog self.widget = ModelerParametersPanelWidget(alg, model, algName, configuration, dialog, context) 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 def algorithm(self): return self._alg def switchToCommentTab(self): self.tab.setCurrentIndex(1) self.commentEdit.setFocus() self.commentEdit.selectAll() def setupUi(self): self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.tab = QTabWidget() self.mainLayout.addWidget(self.tab) self.param_widget = QgsPanelWidgetStack() self.widget.setDockMode(True) self.param_widget.setMainPanel(self.widget) self.tab.addTab(self.param_widget, self.tr('Properties')) self.commentLayout = QVBoxLayout() self.commentEdit = QTextEdit() self.commentEdit.setAcceptRichText(False) self.commentLayout.addWidget(self.commentEdit, 1) hl = QHBoxLayout() hl.setContentsMargins(0, 0, 0, 0) hl.addWidget(QLabel(self.tr('Color'))) self.comment_color_button = QgsColorButton() self.comment_color_button.setAllowOpacity(True) self.comment_color_button.setWindowTitle(self.tr('Comment Color')) self.comment_color_button.setShowNull(True, self.tr('Default')) hl.addWidget(self.comment_color_button) self.commentLayout.addLayout(hl) w2 = QWidget() w2.setLayout(self.commentLayout) self.tab.addTab(w2, self.tr('Comments')) self.setLayout(self.mainLayout) def setComments(self, text): self.commentEdit.setPlainText(text) def comments(self): return self.commentEdit.toPlainText() def setCommentColor(self, color): if color.isValid(): self.comment_color_button.setColor(color) else: self.comment_color_button.setToNull() def commentColor(self): return self.comment_color_button.color() if not self.comment_color_button.isNull() else QColor() def getAvailableDependencies(self): return self.widget.getAvailableDependencies() def getDependenciesPanel(self): return self.widget.getDependenciesPanel() def getAvailableValuesOfType(self, paramType, outTypes=[], dataTypes=[]): return self.widget.getAvailableValuesOfType(paramType, outTypes, dataTypes) def resolveValueDescription(self, value): return self.widget.resolveValueDescription(value) def setPreviousValues(self): self.widget.setPreviousValues() def createAlgorithm(self): alg = self.widget.createAlgorithm() if alg: alg.comment().setDescription(self.comments()) alg.comment().setColor(self.commentColor()) return alg
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.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) 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)') label = QLabel(desc) self.labels[param.name] = label widget = self.getWidgetFromParameter(param) self.valueItems[param.name] = widget if param.name in 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.setLayout(self.verticalLayout) 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.webView = QWebView() html = None url = None isText, help = self._alg.help() if help is not None: if isText: html = help else: url = QUrl(help) else: html = self.tr('<h2>Sorry, no help is available for this ' 'algorithm.</h2>') try: if html: self.webView.setHtml(html) elif url: self.webView.load(url) except: self.webView.setHtml(self.tr('<h2>Could not open help file :-( </h2>')) self.tabWidget.addTab(self.webView, 'Help') 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) def getAvailableDependencies(self): if self._algName is None: dependent = [] else: dependent = self.model.getDependentAlgorithms(self._algName) opts = [] for alg in 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): values = [] inputs = self.model.inputs for i in inputs.values(): param = i.param if isinstance(param, paramType): 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 self.model.algs.values(): if alg.name not in dependent: for out in alg.algorithm.outputs: if isinstance(out, outType): 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 getWidgetFromParameter(self, param): if isinstance(param, ParameterRaster): item = QComboBox() layers = self.getAvailableValuesOfType(ParameterRaster, OutputRaster) if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(self.resolveValueDescription(layer), layer) elif isinstance(param, ParameterVector): item = QComboBox() layers = self.getAvailableValuesOfType(ParameterVector, OutputVector) if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(self.resolveValueDescription(layer), layer) elif isinstance(param, ParameterTable): item = QComboBox() tables = self.getAvailableValuesOfType(ParameterTable, OutputTable) layers = self.getAvailableValuesOfType(ParameterVector, OutputVector) if param.optional: item.addItem(self.NOT_SELECTED, None) for table in tables: item.addItem(self.resolveValueDescription(table), table) for layer in layers: item.addItem(self.resolveValueDescription(layer), layer) elif isinstance(param, ParameterBoolean): item = QComboBox() item.addItem('Yes') item.addItem('No') bools = self.getAvailableValuesOfType(ParameterBoolean, None) for b in bools: item.addItem(self.resolveValueDescription(b), b) if param.default: item.setCurrentIndex(0) else: item.setCurrentIndex(1) elif isinstance(param, ParameterSelection): item = QComboBox() item.addItems(param.options) item.setCurrentIndex(param.default or 1) elif isinstance(param, ParameterFixedTable): item = FixedTablePanel(param) elif isinstance(param, ParameterRange): item = RangePanel(param) elif isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: options = self.getAvailableValuesOfType(ParameterVector, OutputVector) else: options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster) opts = [] for opt in options: opts.append(self.resolveValueDescription(opt)) item = MultipleInputPanel(opts) elif isinstance(param, ParameterString): strings = self.getAvailableValuesOfType(ParameterString, OutputString) options = [(self.resolveValueDescription(s), s) for s in strings] if param.multiline: item = MultilineTextPanel(options) item.setText(unicode(param.default or "")) else: item = QComboBox() item.setEditable(True) for desc, val in options: item.addItem(desc, val) item.setEditText(unicode(param.default or "")) elif isinstance(param, ParameterTableField): item = QComboBox() item.setEditable(True) fields = self.getAvailableValuesOfType(ParameterTableField, None) for f in fields: item.addItem(self.resolveValueDescription(f), f) elif isinstance(param, ParameterNumber): item = QComboBox() item.setEditable(True) numbers = self.getAvailableValuesOfType(ParameterNumber, OutputNumber) for n in numbers: item.addItem(self.resolveValueDescription(n), n) item.setEditText(unicode(param.default)) elif isinstance(param, ParameterCrs): item = CrsSelectionPanel(param.default) elif isinstance(param, ParameterExtent): item = QComboBox() item.setEditable(True) extents = self.getAvailableValuesOfType(ParameterExtent, OutputExtent) if self.canUseAutoExtent(): item.addItem(self.USE_MIN_COVERING_EXTENT, None) for ex in extents: item.addItem(self.resolveValueDescription(ex), ex) if not self.canUseAutoExtent(): item.setEditText(unicode(param.default)) elif isinstance(param, ParameterPoint): item = QComboBox() item.setEditable(True) points = self.getAvailableValuesOfType(ParameterPoint) for p in points: item.addItem(self.resolveValueDescription(p), p) item.setEditText(unicode(param.default)) elif isinstance(param, ParameterFile): item = QComboBox() item.setEditable(True) files = self.getAvailableValuesOfType(ParameterFile, OutputFile) for f in files: item.addItem(self.resolveValueDescription(f), f) elif isinstance(param, ParameterGeometryPredicate): item = GeometryPredicateSelectionPanel(param.enabledPredicates) else: item = QLineEdit() try: item.setText(unicode(param.default)) except: pass return item def canUseAutoExtent(self): for param in self._alg.parameters: if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)): return True return False 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 setComboBoxValue(self, combo, value, param): if isinstance(value, list): value = value[0] items = [combo.itemData(i) for i in range(combo.count())] try: idx = items.index(value) combo.setCurrentIndex(idx) return except ValueError: pass if combo.isEditable(): if value is not None: combo.setEditText(unicode(value)) elif isinstance(param, ParameterSelection): combo.setCurrentIndex(int(value)) elif isinstance(param, ParameterBoolean): if value: combo.setCurrentIndex(0) else: combo.setCurrentIndex(1) 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 widget = self.valueItems[param.name] if param.name in alg.params: value = alg.params[param.name] else: value = param.default if isinstance(param, ( ParameterRaster, ParameterVector, ParameterTable, ParameterTableField, ParameterSelection, ParameterNumber, ParameterBoolean, ParameterExtent, ParameterFile, ParameterPoint )): self.setComboBoxValue(widget, value, param) elif isinstance(param, ParameterString): if param.multiline: widget.setValue(value) else: self.setComboBoxValue(widget, value, param) elif isinstance(param, ParameterCrs): widget.setAuthId(value) elif isinstance(param, ParameterFixedTable): pass # TODO! elif isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: options = self.getAvailableValuesOfType(ParameterVector, OutputVector) else: options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster) selected = [] for i, opt in enumerate(options): if opt in value: selected.append(i) widget.setSelectedItems(selected) elif isinstance(param, ParameterGeometryPredicate): widget.setValue(value) for name, out in alg.outputs.iteritems(): widget = 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.valueItems[param.name]): return None for output in outputs: if not output.hidden: name = unicode(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 setParamValueLayerOrTable(self, alg, param, widget): idx = widget.currentIndex() if idx < 0: return False else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamTableFieldValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = unicode(widget.currentText()).strip() if s == '': if param.optional: alg.params[param.name] = None return True else: return False else: alg.params[param.name] = s return True else: alg.params[param.name] = widget.itemData(widget.currentIndex()) return True def setParamStringValue(self, alg, param, widget): if param.multiline: value = widget.getValue() option = widget.getOption() if option == MultilineTextPanel.USE_TEXT: if value == '': if param.optional: alg.params[param.name] = None return True else: return False else: alg.params[param.name] = value else: alg.params[param.name] = value else: idx = widget.findText(widget.currentText()) if idx < 0: value = widget.currentText().strip() if value == '': if param.optional: alg.params[param.name] = None return True else: return False else: alg.params[param.name] = value else: alg.params[param.name] = widget.itemData(widget.currentIndex()) return True def setParamFileValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: value = widget.currentText() else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamNumberValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = widget.currentText().strip() if s: try: value = float(s) except: return False elif param.optional: value = None else: return False else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamExtentValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = unicode(widget.currentText()).strip() if s: try: tokens = s.split(',') if len(tokens) != 4: return False for token in tokens: float(token) except: return False elif param.optional: s = None else: return False alg.params[param.name] = [s] else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamPointValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = unicode(widget.currentText()).strip() if s: try: tokens = s.split(',') if len(tokens) != 2: return False for token in tokens: float(token) except: return False elif param.optional: s = None else: return False alg.params[param.name] = [s] else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamValue(self, alg, param, widget): if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): return self.setParamValueLayerOrTable(alg, param, widget) elif isinstance(param, ParameterBoolean): if widget.currentIndex() < 2: value = widget.currentIndex() == 0 else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True elif isinstance(param, ParameterString): return self.setParamStringValue(alg, param, widget) elif isinstance(param, ParameterNumber): return self.setParamNumberValue(alg, param, widget) elif isinstance(param, ParameterExtent): return self.setParamExtentValue(alg, param, widget) elif isinstance(param, ParameterPoint): return self.setParamPointValue(alg, param, widget) elif isinstance(param, ParameterFile): return self.setParamFileValue(alg, param, widget) elif isinstance(param, ParameterSelection): alg.params[param.name] = widget.currentIndex() return True elif isinstance(param, ParameterRange): alg.params[param.name] = widget.getValue() return True elif isinstance(param, ParameterCrs): authid = widget.getValue() if authid is None and not param.optional: return False alg.params[param.name] = authid return True elif isinstance(param, ParameterFixedTable): table = widget.table if not bool(table) and not param.optional: return False alg.params[param.name] = ParameterFixedTable.tableToString(table) return True elif isinstance(param, ParameterTableField): return self.setParamTableFieldValue(alg, param, widget) elif isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: options = self.getAvailableValuesOfType(ParameterVector, OutputVector) else: options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster) values = [options[i] for i in widget.selectedoptions] if len(values) == 0 and not param.optional: return False alg.params[param.name] = values return True elif isinstance(param, ParameterGeometryPredicate): alg.params[param.name] = widget.value() return True else: alg.params[param.name] = unicode(widget.text()) return True def okPressed(self): self.alg = self.createAlgorithm() if self.alg is not None: self.close() else: QMessageBox.warning(self, self.tr('Unable to add algorithm'), self.tr('Wrong or missing parameter values')) def cancelPressed(self): self.alg = None self.close()
def buildfromauto(formconfig, base) -> QWidget: """ Build a auto form from the form config given. :param formconfig: The form config containing the information about the widgets to create. :param base: The base widget to create the new widgets in. :return: The base widget with the added widgets created inside the layout. """ widgetsconfig = copy.deepcopy(formconfig['widgets']) try: widgetsconfig = base.get_widgets(widgetsconfig) except AttributeError: pass newstyle = formconfig.get("newstyle", False) hassections = any(config['widget'] == "Section" for config in widgetsconfig) def make_layout(): """ Create the inner layout for the widget. For new style forms this is a vbox layout so everything is stacked on top of each other in a simple list. :return: """ if newstyle: return QVBoxLayout() else: layout = QFormLayout() layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) return layout def make_tab(tabwidget, name): """ Create a table in the given tab widget. :param tabwidget: The tab widget to create the tab in. :param name: The name of the new tab to create. :return: The new widget inside the tab and the widgets inner layout. """ widget = QWidget() widget.setLayout(make_layout()) tabwidget.addTab(widget, name) return widget, widget.layout() if hassections: outwidget = QTabWidget(base) outlayout = None base.setLayout(QVBoxLayout()) base.layout().setContentsMargins(0, 0, 0, 0) base.layout().addWidget(outwidget) else: outwidget = base outlayout = make_layout() outwidget.setLayout(outlayout) # Add the geometry editor widget of that is set in the config. # This is a hidden option so isn't exposed in config manager yet if roam.config.settings.get("form_geom_edit", False): geomwidget = GeomWidget() geomwidget.setObjectName("__geomwidget") outlayout.addRow("Geometry", geomwidget) insection = False for config in widgetsconfig: widgettype = config['widget'] # Make the first tab if one isn't defined already and we have other sections in the config if not insection and hassections and not widgettype == "Section": name = formconfig['label'] tabwidget, outlayout = make_tab(outwidget, name) insection = True if widgettype == 'Section': # Add a spacer to the last widget if outlayout: spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) outlayout.addItem(QSpacerItem(10, 500)) outlayout.addWidget(spacer) name = config['name'] tabwidget, outlayout = make_tab(outwidget, name) insection = True continue field = config['field'] name = config.get('name', field) if not field: utils.warning("Field can't be null for {}".format(name)) utils.warning("Skipping widget") continue label = QLabel(name) label.setObjectName(field + "_label") labelwidget = QWidget() labelwidget.setLayout(QBoxLayout(QBoxLayout.LeftToRight)) labelwidget.layout().addWidget(label) labelwidget.layout().setContentsMargins(0, 0, 0, 0) widget = roam.editorwidgets.core.createwidget(widgettype, parent=base) widget.setObjectName(field) layoutwidget = QWidget() layoutwidget.setLayout(QBoxLayout(QBoxLayout.LeftToRight)) layoutwidget.layout().addWidget(widget) layoutwidget.layout().setContentsMargins(0, 0, 0, 10) if config.get('rememberlastvalue', False): savebutton = QToolButton() savebutton.setObjectName('{}_save'.format(field)) if newstyle: spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) labelwidget.layout().addWidget(spacer) labelwidget.layout().addWidget(savebutton) else: layoutwidget.layout().addWidget(savebutton) if newstyle: outlayout.addWidget(labelwidget) outlayout.addWidget(layoutwidget) else: outlayout.addRow(labelwidget, layoutwidget) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) outlayout.addWidget(spacer) if not hassections: outlayout.addItem(QSpacerItem(10, 500)) return base
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False 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) 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)') label = QLabel(desc) self.labels[param.name] = label widget = self.getWidgetFromParameter(param) self.valueItems[param.name] = widget if param.name in 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.setLayout(self.verticalLayout) 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.webView = QWebView() html = None url = None isText, help = self._alg.help() if help is not None: if isText: html = help else: url = QUrl(help) else: html = self.tr('<h2>Sorry, no help is available for this ' 'algorithm.</h2>') try: if html: self.webView.setHtml(html) elif url: self.webView.load(url) except: self.webView.setHtml(self.tr('<h2>Could not open help file :-( </h2>')) self.tabWidget.addTab(self.webView, 'Help') 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)
class GeometryDiffViewerDialog(QDialog): def __init__(self, geoms, crs, parent = None): super(GeometryDiffViewerDialog, self).__init__(parent) self.geoms = geoms self.crs = crs self.initGui() def initGui(self): layout = QVBoxLayout() self.tab = QTabWidget() self.table = QTableView() self.setLayout(layout) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) settings = QSettings() self.canvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type = bool)) self.canvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type = bool)) self.canvas.mapSettings().setDestinationCrs(self.crs) action = settings.value("/qgis/wheel_action", 0, type = float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type = float) self.canvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) self.panTool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.panTool) execute(self.createLayers) model = GeomDiffTableModel(self.data) self.table.setModel(model) self.table.resizeColumnsToContents() self.table.resizeRowsToContents() self.tab.addTab(self.canvas, "Map view") self.tab.addTab(self.table, "Table view") layout.addWidget(self.tab) self.resize(600, 500) self.setWindowTitle("Geometry comparison") def createLayers(self): textGeometries = [] for geom in self.geoms: text = geom.exportToWkt() valid = " -1234567890.," text = "".join([c for c in text if c in valid]) textGeometries.append(text.split(",")) lines = difflib.Differ().compare(textGeometries[0], textGeometries[1]) self.data = [] for line in lines: if line.startswith("+"): self.data.append([None, line[2:]]) if line.startswith("-"): self.data.append([line[2:], None]) if line.startswith(" "): self.data.append([line[2:], line[2:]]) types = [("LineString", lineBeforeStyle, lineAfterStyle), ("Polygon", polygonBeforeStyle, polygonAfterStyle)] layers = [] extent = self.geoms[0].boundingBox() for i, geom in enumerate(self.geoms): geomtype = types[int(geom.type() - 1)][0] style = types[int(geom.type() - 1)][i + 1] layer = loadLayerNoCrsDialog(geomtype + "?crs=" + self.crs.authid(), "layer", "memory") pr = layer.dataProvider() feat = QgsFeature() feat.setGeometry(geom) pr.addFeatures([feat]) layer.loadNamedStyle(style) layer.updateExtents() layers.append(layer) QgsMapLayerRegistry.instance().addMapLayer(layer, False) extent.combineExtentWith(geom.boundingBox()) layer = loadLayerNoCrsDialog("Point?crs=%s&field=changetype:string" % self.crs.authid(), "points", "memory") pr = layer.dataProvider() feats = [] for coords in self.data: coord = coords[0] or coords[1] feat = QgsFeature() x, y = coord.strip().split(" ") x, y = (float(x), float(y)) pt = QgsGeometry.fromPoint(QgsPoint(x, y)) feat.setGeometry(pt) if coords[0] is None: changetype = "A" elif coords[1] is None: changetype = "R" else: changetype = "U" feat.setAttributes([changetype]) feats.append(feat) pr.addFeatures(feats) layer.loadNamedStyle(pointsStyle) QgsMapLayerRegistry.instance().addMapLayer(layer, False) layers.append(layer) self.mapLayers = [QgsMapCanvasLayer(lay) for lay in layers] self.canvas.setLayerSet(self.mapLayers) self.canvas.setExtent(extent) self.canvas.refresh() def reject(self): QDialog.reject(self)
class SupportingDocuments(ComponentUtility): onUploadDocument = pyqtSignal(list) def __init__(self, box, combobox, add_documents_btn, notification_bar, parent=None): """ Handles the supporting documents component loading. :param box: The layout holding the container widget. :type box: QVBoxLayout :param combobox: The combobox loading supporting document types. :type combobox: QComboBox :param add_documents_btn: The add supporting document button :type add_documents_btn: QPushButton :param notification_bar: The NotificationBar object that displays notification. :type notification_bar: Object :param parent: The container of the widget :type parent: QDialog or None """ ComponentUtility.__init__(self) self._parent = parent self.container_box = box self.doc_type_cbo = combobox self.notification_bar = notification_bar self.str_number = 1 self.add_documents_btn = add_documents_btn self.str_numbers = [1] self.current_party_count = None self.init_documents() def init_documents(self): """ Initializes the document type combobox by populating data. """ self.supporting_doc_manager = SourceDocumentManager( self.social_tenure.supporting_doc, self.str_doc_model, self._parent) self.create_doc_tab_populate_combobox() self.doc_type_cbo.currentIndexChanged.connect( self.match_doc_combo_to_tab) self.docs_tab.currentChanged.connect(self.match_doc_tab_to_combo) def party_count(self, count): """ A setter for current_party_count that is used to determined the number of copies for each supporting document. :param count: The number of currently added party records. :type count: Integer """ self.current_party_count = count def create_doc_tab_populate_combobox(self): """ Creates the supporting document component widget. """ self.doc_tab_data() self.docs_tab = QTabWidget() self.docs_tab_index = OrderedDict() for i, (id, doc) in enumerate(self.doc_types.items()): self.docs_tab_index[doc] = i # the tab widget containing the document widget layout # and the child of the tab. tab_widget = QWidget() tab_widget.setObjectName(doc) # The layout of the tab widget cont_layout = QVBoxLayout(tab_widget) cont_layout.setObjectName('widget_layout_{}'.format(doc)) # the scroll area widget inside the tab widget. scroll_area = QScrollArea(tab_widget) scroll_area.setFrameShape(QFrame.NoFrame) scroll_area.setObjectName('tab_scroll_area_{}'.format(doc)) layout_widget = QWidget() # the widget the is under the scroll area content and # the widget containing the document widget layout # This widget is hidden and shown based on the STR number layout_widget.setObjectName('widget_{}'.format(doc)) doc_widget_layout = QVBoxLayout(layout_widget) doc_widget_layout.setObjectName('doc_widget_layout_{}'.format(doc)) doc_widget = QWidget() doc_widget.setObjectName('doc_widget_{}_{}'.format( doc, self.str_number)) doc_widget_layout.addWidget(doc_widget) # the layout containing document widget. ### This is the layout that is registered to add uploaded # supporting documents widgets into. tab_layout = QVBoxLayout(doc_widget) tab_layout.setObjectName('layout_{}_{}'.format( doc, self.str_number)) scroll_area.setWidgetResizable(True) scroll_area.setWidget(layout_widget) cont_layout.addWidget(scroll_area) # Add the tab widget with the document # type name to create a tab. self.docs_tab.addTab(tab_widget, doc) self.container_box.addWidget(self.docs_tab, 1) if len(self.str_numbers) == 1: self.doc_type_cbo.addItem(doc, id) def doc_tab_data(self): """ Sets the document types in the social tenure entity. """ doc_entity = self.social_tenure. \ supporting_doc.document_type_entity doc_type_model = entity_model(doc_entity) docs = doc_type_model() doc_type_list = docs.queryObject().all() self.doc_types = [(doc.id, doc.value) for doc in doc_type_list] self.doc_types = OrderedDict(self.doc_types) def match_doc_combo_to_tab(self): """ Changes the active tab based on the selected value of document type combobox. """ combo_text = self.doc_type_cbo.currentText() if combo_text is not None and len(combo_text) > 0: index = self.docs_tab_index[combo_text] self.docs_tab.setCurrentIndex(index) def match_doc_tab_to_combo(self): """ Changes the document type combobox value based on the selected tab. """ doc_tab_index = self.docs_tab.currentIndex() self.doc_type_cbo.setCurrentIndex(doc_tab_index) @staticmethod def hide_doc_widgets(widget, visibility): """ Hides or shows the visibility of the supporting document container widgets. :param widget: The widget to which the visibility is set. :type widget: QWidget :param visibility: A boolean to show or hide visibility. True hides widget and False shows it. :type visibility: Boolean """ widget.setHidden(visibility) def update_container(self, str_number): """ Update the current supporting document widget container to be used. :param str_number: The STR node number :type str_number: Integer """ doc_text = self.doc_type_cbo.currentText() cbo_index = self.doc_type_cbo.currentIndex() doc_id = self.doc_type_cbo.itemData(cbo_index) scroll_area = self.docs_tab.findChild( QScrollArea, 'tab_scroll_area_{}'.format(doc_text, str_number)) doc_widget = scroll_area.findChild( QWidget, 'doc_widget_{}_{}'.format(doc_text, str_number)) # If the doc widget doesn't exist create it for new STR instance if doc_widget is None: # find the doc_widget layout that contains # all STR doc widget layouts. Single # doc_widget_layout is created for each document type. # But all doc_widgets for each STR instance and # document types will be added here. doc_widget_layout = scroll_area.findChild( QVBoxLayout, 'doc_widget_layout_{}'.format(doc_text)) doc_widget = QWidget() doc_widget.setObjectName('doc_widget_{}_{}'.format( doc_text, str_number)) self.hide_all_other_widget(doc_text, str_number) doc_widget_layout.addWidget(doc_widget) # Create the layout so that layouts are registered in # which uploaded document widgets are added. layout = QVBoxLayout(doc_widget) layout.setObjectName('layout_{}_{}'.format(doc_text, str_number)) # If the doc widget exists, get the lowest # layout so that it is registered. else: # hide all other widgets self.hide_all_other_widget(doc_text, str_number) # show the current doc widget to display # the document widgets for the current tab. self.hide_doc_widgets(doc_widget, False) layout = doc_widget.findChild( QVBoxLayout, 'layout_{}_{}'.format(doc_text, str_number)) # register layout self.supporting_doc_manager.registerContainer(layout, doc_id) def hide_all_other_widget(self, doc_text, str_number): """ Hides all other supporting document widget except the current STR node widget. :param doc_text: The current document type selected. :type doc_text: String :param str_number: The STR node number :type str_number: Integer """ expression = QRegExp('doc_widget*') # hide all existing widgets in all layouts for widget in self.docs_tab.findChildren(QWidget, expression): if widget.objectName() != 'doc_widget_{}_{}'.format( doc_text, str_number): self.hide_doc_widgets(widget, True) def on_upload_document(self): ''' Slot raised when the user clicks to upload a supporting document. ''' document_str = QApplication.translate( "SupportingDocuments", "Specify the Document File Location") documents = self.select_file_dialog(document_str) cbo_index = self.doc_type_cbo.currentIndex() doc_id = self.doc_type_cbo.itemData(cbo_index) for doc in documents: self.supporting_doc_manager.insertDocumentFromFile( doc, doc_id, self.social_tenure, self.current_party_count) # Set last path if len(documents) > 0: doc = documents[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path) model_objs = self.supporting_doc_manager.model_objects() self.onUploadDocument.emit(model_objs) def select_file_dialog(self, title): """ Displays a file dialog for a user to specify a source document :param title: The title of the file dialog :type title: String """ # Get last path for supporting documents last_path = last_document_path() if last_path is None: last_path = '/home' files, _ = QFileDialog.getOpenFileNames( iface.mainWindow(), title, last_path, "Source Documents (*.jpg *.jpeg *.png *.bmp *.tiff *.svg)") return files
def _setup_columns_content_area(self): # Only use this if entity supports documents # self.entity_tab_widget = None self.doc_widget = None self.entity_scroll_area = QScrollArea(self) self.entity_scroll_area.setFrameShape(QFrame.NoFrame) self.entity_scroll_area.setWidgetResizable(True) self.entity_scroll_area.setObjectName('scrollArea') # Grid layout for controls self.gl = QGridLayout(self.scroll_widget_contents) self.gl.setObjectName('gl_widget_contents') # Append column labels and widgets table_name = self._entity.name columns = table_column_names(table_name) # Iterate entity column and assert if they exist row_id = 0 for column_name, column_widget in self.column_widgets.items(): c = self.columns[column_name] if c.name in self.exclude_columns: continue if isinstance(c, MultipleSelectColumn): continue if c.name not in columns and not isinstance(c, VirtualColumn): continue if column_widget is not None: header = c.ui_display() self.c_label = QLabel(self.scroll_widget_contents) self.c_label.setText(header) self.gl.addWidget(self.c_label, row_id, 0, 1, 1) if c.TYPE_INFO == 'AUTO_GENERATED': column_widget.setReadOnly(False) column_widget.btn_load.hide() self.gl.addWidget(column_widget, row_id, 1, 1, 1) col_name = c.name # Add widget to MapperMixin collection self.addMapping( col_name, column_widget, c.mandatory, pseudoname=c.ui_display() ) # Bump up row_id row_id += 1 self.entity_scroll_area.setWidget(self.scroll_widget_contents) if self.entity_tab_widget is None: self.entity_tab_widget = QTabWidget(self) # Check if there are children and add foreign key browsers # Add primary tab if necessary self._add_primary_attr_widget() # self.entity_tab_widget.setTabEnabled(0, False) # enable/disable the tab # set the style sheet self.setStyleSheet( "QTabBar::tab::selected {width: 0; height: 0; margin: 0; " "padding: 0; border: none;} ") # Return the correct widget if self.entity_tab_widget is not None: return self.entity_tab_widget return self.entity_scroll_area
class HistoryDiffViewerWidget(QWidget): def __init__(self, dialog, server, user, repo, graph, layer=None, initialSimplify=False): self.graph = graph self.dialog = dialog self.server = server self.user = user self.repo = repo self.layer = layer self.afterLayer = None self.beforeLayer = None self.extraLayers = [] # layers for the "Map" tab QWidget.__init__(self, iface.mainWindow()) self.setWindowFlags(Qt.Window) self.simplifyLog = initialSimplify self.initGui() self.tabWidget.setVisible(False) self.setLabelText("Select a commit to show its content") self.label.setVisible(False) if self.graph.commits: self.history.setCurrentItem(self.history.topLevelItem(0)) self.itemChanged(self.history.topLevelItem(0), None) self.history.currentItemChanged.connect(self.itemChanged) def setShowPopup(self, show): self.history.showPopup = show def initGui(self): layout = QVBoxLayout() splitter = QSplitter() splitter.setOrientation(Qt.Vertical) self.history = HistoryTree(self.dialog) self.history.updateContent(self.server, self.user, self.repo, self.graph, self.layer) self.historyWithFilter = HistoryTreeWrapper(self.history) if self.simplifyLog: self.historyWithFilter.simplify(True) splitter.addWidget(self.historyWithFilter) self.tabWidget = QTabWidget() self.tabCanvas = QWidget() tabLayout = QVBoxLayout() tabLayout.setMargin(0) self.canvas = QgsMapCanvas(self.tabCanvas) self.canvas.setCanvasColor(Qt.white) self.panTool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.panTool) tabLayout.addWidget(self.canvas) self.labelNoChanges = QLabel("This commit doesn't change any geometry") self.labelNoChanges.setAlignment(Qt.AlignCenter) self.labelNoChanges.setVisible(False) tabLayout.addWidget(self.labelNoChanges) self.tabCanvas.setLayout(tabLayout) self.summaryTextBrowser = QTextBrowser() self.summaryTextBrowser.setOpenLinks(False) self.summaryTextBrowser.anchorClicked.connect(self.summaryTextBrowserAnchorClicked) self.tabWidget.addTab(self.summaryTextBrowser, "Commit Summary") self.tabWidget.addTab(self.tabCanvas, "Map") tabLayout = QVBoxLayout() tabLayout.setMargin(0) self.tabDiffViewer = QWidget() self.diffViewer = DiffViewerWidget({}) tabLayout.addWidget(self.diffViewer) self.tabDiffViewer.setLayout(tabLayout) self.tabWidget.addTab(self.tabDiffViewer, "Attributes") splitter.addWidget(self.tabWidget) self.label = QTextBrowser() self.label.setVisible(False) splitter.addWidget(self.label) self.tabWidget.setCurrentWidget(self.tabDiffViewer) layout.addWidget(splitter) self.setLayout(layout) exportDiffButton = QPushButton("Export this commit's DIFF for all layers") exportDiffButton.clicked.connect(self.exportDiffAllLayers) layout.addWidget(exportDiffButton) self.label.setMinimumHeight(self.tabWidget.height()) self.setWindowTitle("Repository history") def summaryTextBrowserAnchorClicked(self,url): url = url.url() #convert to string item = self.history.currentItem() if item is None: return commitid = item.commit.commitid cmd,layerName = url.split(".",1) if cmd == "addLive": execute(lambda: self.history.exportVersion(layerName,commitid,True)) elif cmd == "addGeoPKG": self.history.exportVersion(layerName,commitid,False) elif cmd == "exportDiff": execute(lambda: self.history.exportDiff(item, None,layer=layerName)) def exportDiffAllLayers(self): item = self.history.currentItem() if item is not None: self.history.exportDiff(item, None) def setLabelText(self,text): self.label.setHtml("<br><br><br><center><b>{}</b></center>".format(text)) def setContent(self, server, user, repo, graph, layer = None): self.server = server self.user = user self.repo = repo self.layer = layer self.graph = graph self.historyWithFilter.updateContent(server, user, repo, graph, layer) if self.history.graph.commits: self.history.setCurrentItem(self.history.topLevelItem(0)) def itemChanged(self, current, previous, THRESHOLD = 1500): item = self.history.currentItem() if item is not None: commit = self.graph.getById(item.ref) if commit is None: self.tabWidget.setVisible(False) self.setLabelText("Select a commit to show its content") self.label.setVisible(True) return commit2 = commit.commitid + "~1" if not item.commit.hasParents(): commit2 = "0000000000000000" total,details = self.server.diffSummary(self.user, self.repo, commit2,commit.commitid) tooLargeDiff = total > THRESHOLD if tooLargeDiff: html = "<br><br><center><b><font size=+3>Commit <font size=-0.1><tt>{}</tt></font> DIFF is too large to be shown</b></font><br>".format(commit.commitid[:8]) else: html = "<br><br><center><b><font size=+3>Commit <font size=-0.1><tt>{}</tt></font> Summary</b></font><br>".format(commit.commitid[:8]) html += "<table>" html += "<tr><Td style='padding:5px'><b>Layer Name</b></td><td style='padding:5px'><b>Additions</b></td><td style='padding:5px'><b>Deletions</b></td><td style='padding:5px'><b>Modifications</b></td><td></td><td></td><td></td></tr>" for detail in details.values(): html += "<tr><td style='padding:5px'>{}</td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'>{}</td><td style='padding:5px'>{}</td><td style='padding:5px'>{}</td></tr>".format( detail["path"], int(detail["featuresAdded"]), int(detail["featuresRemoved"]),int(detail["featuresChanged"]), "<a href='addLive.{}'>Add Live</a>".format(detail["path"]), "<a href='addGeoPKG.{}'>Add GeoPKG</a>".format(detail["path"]), "<a href='exportDiff.{}'>Export Diff</a>".format(detail["path"]) ) html += "<tr></tr>" html += "<tr><td colspan=4>There is a total of {:,} features changed</td></tr>".format(total) html += "</table>" # html += "<br><br>There is a total of {:,} features changed".format(total) self.summaryTextBrowser.setHtml(html) self.label.setVisible(False) self.tabWidget.setVisible(True) self.tabWidget.setTabEnabled(1,not tooLargeDiff) self.tabWidget.setTabEnabled(2,not tooLargeDiff) if not tooLargeDiff: self.setDiffContent(commit, commit2) else: self.tabWidget.setVisible(False) self.setLabelText("Select a commit to show its content") self.label.setVisible(True) def setDiffContent(self, commit, commit2): if self.layer is None: layers = set(self.server.layers(self.user, self.repo, commit.commitid)) layers2 = set(self.server.layers(self.user, self.repo, commit2)) layers = layers.union(layers2) else: layers = [self.layer] diffs = {layer: execute(lambda: self.server.diff(self.user, self.repo, layer, commit.commitid, commit2)) for layer in layers} diffs = {key:value for (key,value) in diffs.items() if len(value) !=0} layers = [l for l in diffs.keys()] self.diffViewer.setChanges(diffs) self.canvas.setLayers([]) self.removeMapLayers() extent = QgsRectangle() for layer in layers: if not diffs[layer]: continue beforeLayer, afterLayer = execute(lambda: self._getLayers(diffs[layer])) if afterLayer is not None: resourcesPath = os.path.join(os.path.dirname(__file__), os.pardir, "resources") oldStylePath = os.path.join(resourcesPath, "{}_before.qml".format( QgsWkbTypes.geometryDisplayString(beforeLayer.geometryType()))) newStylePath = os.path.join(resourcesPath, "{}_after.qml".format( QgsWkbTypes.geometryDisplayString(afterLayer.geometryType()))) beforeLayer.loadNamedStyle(oldStylePath) afterLayer.loadNamedStyle(newStylePath) QgsProject.instance().addMapLayer(beforeLayer, False) QgsProject.instance().addMapLayer(afterLayer, False) extent.combineExtentWith(beforeLayer.extent()) extent.combineExtentWith(afterLayer.extent()) self.extraLayers.append(beforeLayer) self.extraLayers.append(afterLayer) # make extent a bit bit (10%) bigger # this gives some margin around the dataset (not cut-off at edges) if not extent.isEmpty(): widthDelta = extent.width() * 0.05 heightDelta = extent.height() * 0.05 extent = QgsRectangle(extent.xMinimum() - widthDelta, extent.yMinimum() - heightDelta, extent.xMaximum() + widthDelta, extent.yMaximum() + heightDelta) layers = self.extraLayers hasChanges = False for layer in layers: if layer is not None and layer.featureCount() > 0: hasChanges = True break self.canvas.setLayers(layers) self.canvas.setExtent(extent) self.canvas.refresh() self.canvas.setVisible(hasChanges) self.labelNoChanges.setVisible(not hasChanges) def _getLayers(self, changes): ADDED, MODIFIED, REMOVED, = 0, 1, 2 def _feature(g, changeType): feat = QgsFeature() if g is not None: feat.setGeometry(g) feat.setAttributes([changeType]) return feat if changes: f = changes[0] new = f["new"] old = f["old"] reference = new or old geomtype = QgsWkbTypes.displayString(reference.geometry().wkbType()) oldLayer = loadLayerNoCrsDialog(geomtype + "?crs=epsg:4326&field=geogig.changeType:integer", "old", "memory") newLayer = loadLayerNoCrsDialog(geomtype + "?crs=epsg:4326&field=geogig.changeType:integer", "new", "memory") oldFeatures = [] newFeatures = [] for f in changes: new = f["new"] old = f["old"] newGeom = new.geometry() if new is not None else None oldGeom = old.geometry() if old is not None else None if oldGeom is None: feature = _feature(newGeom, ADDED) newFeatures.append(feature) elif newGeom is None: feature = _feature(oldGeom, REMOVED) oldFeatures.append(feature) elif oldGeom.asWkt() != newGeom.asWkt(): feature = _feature(oldGeom, MODIFIED) oldFeatures.append(feature) feature = _feature(newGeom, MODIFIED) newFeatures.append(feature) else: feature = _feature(newGeom, MODIFIED) newFeatures.append(feature) oldLayer.dataProvider().addFeatures(oldFeatures) newLayer.dataProvider().addFeatures(newFeatures) else: oldLayer = None newLayer = None return oldLayer, newLayer def removeMapLayers(self): for layer in self.extraLayers: if layer is not None: QgsProject.instance().removeMapLayer(layer.id()) self.extraLayers = []
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()
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.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.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 is not None: 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.displayName()) 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 = QgsScrollArea() 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): # spellok if self._algName is None: dependent = [] else: dependent = self.model.getDependentAlgorithms(self._algName) opts = [] for alg in list(self.model.algs.values()): if alg.modeler_name 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.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.modeler_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.modeler_name, out.name)) else: values.append( ValueFromOutput(alg.modeler_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("'{0}' from algorithm '{1}'").format( 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() # spellok 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.id()) 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() # spellok for selected in selectedOptions: alg.dependencies.append( availableDependencies[selected].name) # spellok 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.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 setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False 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) 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)') label = QLabel(desc) self.labels[param.name] = label widget = self.getWidgetFromParameter(param) self.valueItems[param.name] = widget if param.name in 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.setLayout(self.verticalLayout) 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.webView = QWebView() html = None url = None isText, help = self._alg.help() if help is not None: if isText: html = help else: url = QUrl(help) else: html = self.tr('<h2>Sorry, no help is available for this ' 'algorithm.</h2>') try: if html: self.webView.setHtml(html) elif url: self.webView.load(url) except: self.webView.setHtml( self.tr('<h2>Could not open help file :-( </h2>')) self.tabWidget.addTab(self.webView, 'Help') 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)
def setupUi(self): type_metadata = QgsApplication.processingRegistry().parameterType(self.param.type() if self.param else self.paramType) self.setWindowTitle(self.tr('{} Parameter Definition').format(type_metadata.name())) self.mainLayout = QVBoxLayout() self.tab = QTabWidget() self.mainLayout.addWidget(self.tab) self.setMinimumWidth(300) self.verticalLayout = QVBoxLayout() self.label = QLabel(self.tr('Parameter name')) self.verticalLayout.addWidget(self.label) self.nameTextBox = QLineEdit() self.verticalLayout.addWidget(self.nameTextBox) if isinstance(self.param, QgsProcessingParameterDefinition): self.nameTextBox.setText(self.param.description()) if self.paramType == parameters.PARAMETER_TABLE_FIELD or \ isinstance(self.param, QgsProcessingParameterField): self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() idx = 0 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition(param.parameterName()) if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentLayerParameterName() == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) # add the datatype selector self.verticalLayout.addWidget(QLabel(self.tr('Allowed data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any'), -1) self.datatypeCombo.addItem(self.tr('Number'), 0) self.datatypeCombo.addItem(self.tr('String'), 1) self.datatypeCombo.addItem(self.tr('Date/time'), 2) self.verticalLayout.addWidget(self.datatypeCombo) if self.param is not None and self.param.dataType() is not None: # QComboBoxes indexes start at 0, # self.param.datatype start with -1 that is why I need to do +1 datatypeIndex = self.param.dataType() + 1 self.datatypeCombo.setCurrentIndex(datatypeIndex) self.multipleCheck = QCheckBox() self.multipleCheck.setText(self.tr('Accept multiple fields')) self.multipleCheck.setChecked(False) if self.param is not None: self.multipleCheck.setChecked(self.param.allowMultiple()) self.verticalLayout.addWidget(self.multipleCheck) self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() self.defaultTextBox.setToolTip( self.tr('Default field name, or ; separated list of field names for multiple field parameters')) if self.param is not None: default = self.param.defaultValue() if default is not None: self.defaultTextBox.setText(str(default)) self.verticalLayout.addWidget(self.defaultTextBox) elif self.paramType == parameters.PARAMETER_BAND or \ isinstance(self.param, QgsProcessingParameterBand): self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() idx = 0 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition(param.parameterName()) if isinstance(definition, (QgsProcessingParameterRasterLayer)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentLayerParameterName() == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) elif (self.paramType in ( parameters.PARAMETER_VECTOR, parameters.PARAMETER_TABLE) or isinstance(self.param, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer))): self.verticalLayout.addWidget(QLabel(self.tr('Geometry type'))) self.shapetypeCombo = QComboBox() self.shapetypeCombo.addItem(self.tr('Geometry Not Required'), QgsProcessing.TypeVector) self.shapetypeCombo.addItem(self.tr('Point'), QgsProcessing.TypeVectorPoint) self.shapetypeCombo.addItem(self.tr('Line'), QgsProcessing.TypeVectorLine) self.shapetypeCombo.addItem(self.tr('Polygon'), QgsProcessing.TypeVectorPolygon) self.shapetypeCombo.addItem(self.tr('Any Geometry Type'), QgsProcessing.TypeVectorAnyGeometry) if self.param is not None: self.shapetypeCombo.setCurrentIndex(self.shapetypeCombo.findData(self.param.dataTypes()[0])) self.verticalLayout.addWidget(self.shapetypeCombo) elif (self.paramType == parameters.PARAMETER_MULTIPLE or isinstance(self.param, QgsProcessingParameterMultipleLayers)): self.verticalLayout.addWidget(QLabel(self.tr('Data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any Map Layer'), QgsProcessing.TypeMapLayer) self.datatypeCombo.addItem(self.tr('Vector (No Geometry Required)'), QgsProcessing.TypeVector) self.datatypeCombo.addItem(self.tr('Vector (Point)'), QgsProcessing.TypeVectorPoint) self.datatypeCombo.addItem(self.tr('Vector (Line)'), QgsProcessing.TypeVectorLine) self.datatypeCombo.addItem(self.tr('Vector (Polygon)'), QgsProcessing.TypeVectorPolygon) self.datatypeCombo.addItem(self.tr('Vector (Any Geometry Type)'), QgsProcessing.TypeVectorAnyGeometry) self.datatypeCombo.addItem(self.tr('Raster'), QgsProcessing.TypeRaster) self.datatypeCombo.addItem(self.tr('File'), QgsProcessing.TypeFile) if self.param is not None: self.datatypeCombo.setCurrentIndex(self.datatypeCombo.findData(self.param.layerType())) self.verticalLayout.addWidget(self.datatypeCombo) elif (self.paramType == parameters.PARAMETER_MAP_LAYER or isinstance(self.param, QgsProcessingParameterMapLayer)): self.verticalLayout.addWidget(QLabel(self.tr('Data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any Map Layer'), QgsProcessing.TypeMapLayer) self.datatypeCombo.addItem(self.tr('Vector (Point)'), QgsProcessing.TypeVectorPoint) self.datatypeCombo.addItem(self.tr('Vector (Line)'), QgsProcessing.TypeVectorLine) self.datatypeCombo.addItem(self.tr('Vector (Polygon)'), QgsProcessing.TypeVectorPolygon) self.datatypeCombo.addItem(self.tr('Vector (Any Geometry Type)'), QgsProcessing.TypeVectorAnyGeometry) self.datatypeCombo.addItem(self.tr('Raster'), QgsProcessing.TypeRaster) self.datatypeCombo.addItem(self.tr('Mesh'), QgsProcessing.TypeMesh) if self.param is not None: self.datatypeCombo.setCurrentIndex(self.datatypeCombo.findData(self.param.dataTypes()[0])) self.verticalLayout.addWidget(self.datatypeCombo) elif (self.paramType in (parameters.PARAMETER_NUMBER, parameters.PARAMETER_DISTANCE, parameters.PARAMETER_SCALE) or isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance, QgsProcessingParameterScale))): if (self.paramType == parameters.PARAMETER_DISTANCE or isinstance(self.param, QgsProcessingParameterDistance)): self.verticalLayout.addWidget(QLabel(self.tr('Linked input'))) self.parentCombo = QComboBox() self.parentCombo.addItem('', '') idx = 1 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition(param.parameterName()) if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMapLayer, QgsProcessingParameterCrs)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentParameterName() == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) elif (self.paramType != parameters.PARAMETER_SCALE and not isinstance(self.param, QgsProcessingParameterScale)): self.verticalLayout.addWidget(QLabel(self.tr('Number type'))) self.type_combo = QComboBox() self.type_combo.addItem(self.tr('Float'), QgsProcessingParameterNumber.Double) self.type_combo.addItem(self.tr('Integer'), QgsProcessingParameterNumber.Integer) if self.param: self.type_combo.setCurrentIndex(self.type_combo.findData(self.param.dataType())) self.verticalLayout.addWidget(self.type_combo) if (self.paramType != parameters.PARAMETER_SCALE and not isinstance(self.param, QgsProcessingParameterScale)): self.verticalLayout.addWidget(QLabel(self.tr('Min value'))) self.minTextBox = QLineEdit() self.verticalLayout.addWidget(self.minTextBox) self.verticalLayout.addWidget(QLabel(self.tr('Max value'))) self.maxTextBox = QLineEdit() self.verticalLayout.addWidget(self.maxTextBox) if self.param is not None: self.minTextBox.setText(str(self.param.minimum())) self.maxTextBox.setText(str(self.param.maximum())) self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() self.defaultTextBox.setText(self.tr('0')) if self.param is not None: default = self.param.defaultValue() if self.param.dataType() == QgsProcessingParameterNumber.Integer: default = int(math.floor(float(default))) if default: self.defaultTextBox.setText(str(default)) self.verticalLayout.addWidget(self.defaultTextBox) elif self.paramType == parameters.PARAMETER_ENUM or \ isinstance(self.param, QgsProcessingParameterEnum): self.widget = EnumModelerWidget(self) if self.param is not None: self.widget.setAllowMultiple(bool(self.param.allowMultiple())) self.widget.setOptions(self.param.options()) self.widget.setDefault(self.param.defaultValue()) self.verticalLayout.addWidget(self.widget) elif self.paramType == parameters.PARAMETER_MATRIX or \ isinstance(self.param, QgsProcessingParameterMatrix): self.widget = MatrixModelerWidget(self) if self.param is not None: self.widget.setValue(self.param.headers(), self.param.defaultValue()) self.widget.setFixedRows(self.param.hasFixedNumberRows()) self.verticalLayout.addWidget(self.widget) elif isinstance(self.param, QgsProcessingDestinationParameter): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultWidget = QgsProcessingLayerOutputDestinationWidget(self.param, defaultSelection=True) self.verticalLayout.addWidget(self.defaultWidget) self.verticalLayout.addSpacing(20) self.requiredCheck = QCheckBox() self.requiredCheck.setText(self.tr('Mandatory')) self.requiredCheck.setChecked(True) if self.param is not None: self.requiredCheck.setChecked(not self.param.flags() & QgsProcessingParameterDefinition.FlagOptional) self.verticalLayout.addWidget(self.requiredCheck) self.advancedCheck = QCheckBox() self.advancedCheck.setText(self.tr('Advanced')) self.advancedCheck.setChecked(False) if self.param is not None: self.advancedCheck.setChecked(self.param.flags() & QgsProcessingParameterDefinition.FlagAdvanced) self.verticalLayout.addWidget(self.advancedCheck) # If child algorithm output is mandatory, disable checkbox if isinstance(self.param, QgsProcessingDestinationParameter): provider_name, child_name, output_name = self.param.name().split(':') child = self.alg.childAlgorithms()['{}:{}'.format(provider_name, child_name)] model_output = child.modelOutput(output_name) param_def = child.algorithm().parameterDefinition(model_output.childOutputName()) if not (param_def.flags() & QgsProcessingParameterDefinition.FlagOptional): self.requiredCheck.setEnabled(False) self.requiredCheck.setChecked(True) self.advancedCheck.setEnabled(False) self.advancedCheck.setChecked(False) self.verticalLayout.addStretch() w = QWidget() w.setLayout(self.verticalLayout) self.tab.addTab(w, self.tr('Properties')) self.commentLayout = QVBoxLayout() self.commentEdit = QTextEdit() self.commentEdit.setAcceptRichText(False) self.commentLayout.addWidget(self.commentEdit) w2 = QWidget() w2.setLayout(self.commentLayout) self.tab.addTab(w2, self.tr('Comments')) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName('buttonBox') self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.mainLayout.addWidget(self.buttonBox) self.setLayout(self.mainLayout)
class ModelerParameterDefinitionDialog(QDialog): @staticmethod def use_legacy_dialog(param=None, paramType=None): if paramType in (parameters.PARAMETER_TABLE_FIELD, parameters.PARAMETER_BAND, parameters.PARAMETER_VECTOR, parameters.PARAMETER_TABLE, parameters.PARAMETER_MULTIPLE, parameters.PARAMETER_NUMBER, parameters.PARAMETER_DISTANCE, parameters.PARAMETER_SCALE, parameters.PARAMETER_ENUM, parameters.PARAMETER_MATRIX, parameters.PARAMETER_MAP_LAYER): return True elif isinstance(param, (QgsProcessingParameterField, QgsProcessingParameterBand, QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMultipleLayers, QgsProcessingParameterNumber, QgsProcessingParameterDistance, QgsProcessingParameterScale, QgsProcessingParameterEnum, QgsProcessingParameterMatrix, QgsProcessingParameterMapLayer, QgsProcessingDestinationParameter)): return True # yay, use new API! return False def __init__(self, alg, paramType=None, param=None): self.alg = alg self.paramType = paramType self.param = param QDialog.__init__(self) self.setModal(True) self.setupUi() settings = QgsSettings() self.restoreGeometry(settings.value("/Processing/modelParametersDefinitionDialogGeometry", QByteArray())) def closeEvent(self, event): settings = QgsSettings() settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) super(ModelerParameterDefinitionDialog, self).closeEvent(event) def switchToCommentTab(self): self.tab.setCurrentIndex(1) self.commentEdit.setFocus() self.commentEdit.selectAll() def setupUi(self): type_metadata = QgsApplication.processingRegistry().parameterType(self.param.type() if self.param else self.paramType) self.setWindowTitle(self.tr('{} Parameter Definition').format(type_metadata.name())) self.mainLayout = QVBoxLayout() self.tab = QTabWidget() self.mainLayout.addWidget(self.tab) self.setMinimumWidth(300) self.verticalLayout = QVBoxLayout() self.label = QLabel(self.tr('Parameter name')) self.verticalLayout.addWidget(self.label) self.nameTextBox = QLineEdit() self.verticalLayout.addWidget(self.nameTextBox) if isinstance(self.param, QgsProcessingParameterDefinition): self.nameTextBox.setText(self.param.description()) if self.paramType == parameters.PARAMETER_TABLE_FIELD or \ isinstance(self.param, QgsProcessingParameterField): self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() idx = 0 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition(param.parameterName()) if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentLayerParameterName() == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) # add the datatype selector self.verticalLayout.addWidget(QLabel(self.tr('Allowed data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any'), -1) self.datatypeCombo.addItem(self.tr('Number'), 0) self.datatypeCombo.addItem(self.tr('String'), 1) self.datatypeCombo.addItem(self.tr('Date/time'), 2) self.verticalLayout.addWidget(self.datatypeCombo) if self.param is not None and self.param.dataType() is not None: # QComboBoxes indexes start at 0, # self.param.datatype start with -1 that is why I need to do +1 datatypeIndex = self.param.dataType() + 1 self.datatypeCombo.setCurrentIndex(datatypeIndex) self.multipleCheck = QCheckBox() self.multipleCheck.setText(self.tr('Accept multiple fields')) self.multipleCheck.setChecked(False) if self.param is not None: self.multipleCheck.setChecked(self.param.allowMultiple()) self.verticalLayout.addWidget(self.multipleCheck) self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() self.defaultTextBox.setToolTip( self.tr('Default field name, or ; separated list of field names for multiple field parameters')) if self.param is not None: default = self.param.defaultValue() if default is not None: self.defaultTextBox.setText(str(default)) self.verticalLayout.addWidget(self.defaultTextBox) elif self.paramType == parameters.PARAMETER_BAND or \ isinstance(self.param, QgsProcessingParameterBand): self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() idx = 0 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition(param.parameterName()) if isinstance(definition, (QgsProcessingParameterRasterLayer)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentLayerParameterName() == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) elif (self.paramType in ( parameters.PARAMETER_VECTOR, parameters.PARAMETER_TABLE) or isinstance(self.param, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer))): self.verticalLayout.addWidget(QLabel(self.tr('Geometry type'))) self.shapetypeCombo = QComboBox() self.shapetypeCombo.addItem(self.tr('Geometry Not Required'), QgsProcessing.TypeVector) self.shapetypeCombo.addItem(self.tr('Point'), QgsProcessing.TypeVectorPoint) self.shapetypeCombo.addItem(self.tr('Line'), QgsProcessing.TypeVectorLine) self.shapetypeCombo.addItem(self.tr('Polygon'), QgsProcessing.TypeVectorPolygon) self.shapetypeCombo.addItem(self.tr('Any Geometry Type'), QgsProcessing.TypeVectorAnyGeometry) if self.param is not None: self.shapetypeCombo.setCurrentIndex(self.shapetypeCombo.findData(self.param.dataTypes()[0])) self.verticalLayout.addWidget(self.shapetypeCombo) elif (self.paramType == parameters.PARAMETER_MULTIPLE or isinstance(self.param, QgsProcessingParameterMultipleLayers)): self.verticalLayout.addWidget(QLabel(self.tr('Data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any Map Layer'), QgsProcessing.TypeMapLayer) self.datatypeCombo.addItem(self.tr('Vector (No Geometry Required)'), QgsProcessing.TypeVector) self.datatypeCombo.addItem(self.tr('Vector (Point)'), QgsProcessing.TypeVectorPoint) self.datatypeCombo.addItem(self.tr('Vector (Line)'), QgsProcessing.TypeVectorLine) self.datatypeCombo.addItem(self.tr('Vector (Polygon)'), QgsProcessing.TypeVectorPolygon) self.datatypeCombo.addItem(self.tr('Vector (Any Geometry Type)'), QgsProcessing.TypeVectorAnyGeometry) self.datatypeCombo.addItem(self.tr('Raster'), QgsProcessing.TypeRaster) self.datatypeCombo.addItem(self.tr('File'), QgsProcessing.TypeFile) if self.param is not None: self.datatypeCombo.setCurrentIndex(self.datatypeCombo.findData(self.param.layerType())) self.verticalLayout.addWidget(self.datatypeCombo) elif (self.paramType == parameters.PARAMETER_MAP_LAYER or isinstance(self.param, QgsProcessingParameterMapLayer)): self.verticalLayout.addWidget(QLabel(self.tr('Data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any Map Layer'), QgsProcessing.TypeMapLayer) self.datatypeCombo.addItem(self.tr('Vector (Point)'), QgsProcessing.TypeVectorPoint) self.datatypeCombo.addItem(self.tr('Vector (Line)'), QgsProcessing.TypeVectorLine) self.datatypeCombo.addItem(self.tr('Vector (Polygon)'), QgsProcessing.TypeVectorPolygon) self.datatypeCombo.addItem(self.tr('Vector (Any Geometry Type)'), QgsProcessing.TypeVectorAnyGeometry) self.datatypeCombo.addItem(self.tr('Raster'), QgsProcessing.TypeRaster) self.datatypeCombo.addItem(self.tr('Mesh'), QgsProcessing.TypeMesh) if self.param is not None: self.datatypeCombo.setCurrentIndex(self.datatypeCombo.findData(self.param.dataTypes()[0])) self.verticalLayout.addWidget(self.datatypeCombo) elif (self.paramType in (parameters.PARAMETER_NUMBER, parameters.PARAMETER_DISTANCE, parameters.PARAMETER_SCALE) or isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance, QgsProcessingParameterScale))): if (self.paramType == parameters.PARAMETER_DISTANCE or isinstance(self.param, QgsProcessingParameterDistance)): self.verticalLayout.addWidget(QLabel(self.tr('Linked input'))) self.parentCombo = QComboBox() self.parentCombo.addItem('', '') idx = 1 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition(param.parameterName()) if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer, QgsProcessingParameterMapLayer, QgsProcessingParameterCrs)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentParameterName() == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) elif (self.paramType != parameters.PARAMETER_SCALE and not isinstance(self.param, QgsProcessingParameterScale)): self.verticalLayout.addWidget(QLabel(self.tr('Number type'))) self.type_combo = QComboBox() self.type_combo.addItem(self.tr('Float'), QgsProcessingParameterNumber.Double) self.type_combo.addItem(self.tr('Integer'), QgsProcessingParameterNumber.Integer) if self.param: self.type_combo.setCurrentIndex(self.type_combo.findData(self.param.dataType())) self.verticalLayout.addWidget(self.type_combo) if (self.paramType != parameters.PARAMETER_SCALE and not isinstance(self.param, QgsProcessingParameterScale)): self.verticalLayout.addWidget(QLabel(self.tr('Min value'))) self.minTextBox = QLineEdit() self.verticalLayout.addWidget(self.minTextBox) self.verticalLayout.addWidget(QLabel(self.tr('Max value'))) self.maxTextBox = QLineEdit() self.verticalLayout.addWidget(self.maxTextBox) if self.param is not None: self.minTextBox.setText(str(self.param.minimum())) self.maxTextBox.setText(str(self.param.maximum())) self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() self.defaultTextBox.setText(self.tr('0')) if self.param is not None: default = self.param.defaultValue() if self.param.dataType() == QgsProcessingParameterNumber.Integer: default = int(math.floor(float(default))) if default: self.defaultTextBox.setText(str(default)) self.verticalLayout.addWidget(self.defaultTextBox) elif self.paramType == parameters.PARAMETER_ENUM or \ isinstance(self.param, QgsProcessingParameterEnum): self.widget = EnumModelerWidget(self) if self.param is not None: self.widget.setAllowMultiple(bool(self.param.allowMultiple())) self.widget.setOptions(self.param.options()) self.widget.setDefault(self.param.defaultValue()) self.verticalLayout.addWidget(self.widget) elif self.paramType == parameters.PARAMETER_MATRIX or \ isinstance(self.param, QgsProcessingParameterMatrix): self.widget = MatrixModelerWidget(self) if self.param is not None: self.widget.setValue(self.param.headers(), self.param.defaultValue()) self.widget.setFixedRows(self.param.hasFixedNumberRows()) self.verticalLayout.addWidget(self.widget) elif isinstance(self.param, QgsProcessingDestinationParameter): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultWidget = QgsProcessingLayerOutputDestinationWidget(self.param, defaultSelection=True) self.verticalLayout.addWidget(self.defaultWidget) self.verticalLayout.addSpacing(20) self.requiredCheck = QCheckBox() self.requiredCheck.setText(self.tr('Mandatory')) self.requiredCheck.setChecked(True) if self.param is not None: self.requiredCheck.setChecked(not self.param.flags() & QgsProcessingParameterDefinition.FlagOptional) self.verticalLayout.addWidget(self.requiredCheck) self.advancedCheck = QCheckBox() self.advancedCheck.setText(self.tr('Advanced')) self.advancedCheck.setChecked(False) if self.param is not None: self.advancedCheck.setChecked(self.param.flags() & QgsProcessingParameterDefinition.FlagAdvanced) self.verticalLayout.addWidget(self.advancedCheck) # If child algorithm output is mandatory, disable checkbox if isinstance(self.param, QgsProcessingDestinationParameter): provider_name, child_name, output_name = self.param.name().split(':') child = self.alg.childAlgorithms()['{}:{}'.format(provider_name, child_name)] model_output = child.modelOutput(output_name) param_def = child.algorithm().parameterDefinition(model_output.childOutputName()) if not (param_def.flags() & QgsProcessingParameterDefinition.FlagOptional): self.requiredCheck.setEnabled(False) self.requiredCheck.setChecked(True) self.advancedCheck.setEnabled(False) self.advancedCheck.setChecked(False) self.verticalLayout.addStretch() w = QWidget() w.setLayout(self.verticalLayout) self.tab.addTab(w, self.tr('Properties')) self.commentLayout = QVBoxLayout() self.commentEdit = QTextEdit() self.commentEdit.setAcceptRichText(False) self.commentLayout.addWidget(self.commentEdit) w2 = QWidget() w2.setLayout(self.commentLayout) self.tab.addTab(w2, self.tr('Comments')) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName('buttonBox') self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.mainLayout.addWidget(self.buttonBox) self.setLayout(self.mainLayout) def setComments(self, text): self.commentEdit.setPlainText(text) def comments(self): return self.commentEdit.toPlainText() def accept(self): description = self.nameTextBox.text() if description.strip() == '': QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Invalid parameter name')) return if self.param is None: validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeName = ''.join(c for c in description if c in validChars) name = safeName.lower() i = 2 while self.alg.parameterDefinition(name): name = safeName.lower() + str(i) i += 1 else: name = self.param.name() if (self.paramType == parameters.PARAMETER_TABLE_FIELD or isinstance(self.param, QgsProcessingParameterField)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() datatype = self.datatypeCombo.currentData() default = self.defaultTextBox.text() if not default: default = None self.param = QgsProcessingParameterField(name, description, defaultValue=default, parentLayerParameterName=parent, type=datatype, allowMultiple=self.multipleCheck.isChecked()) elif (self.paramType == parameters.PARAMETER_BAND or isinstance(self.param, QgsProcessingParameterBand)): if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() self.param = QgsProcessingParameterBand(name, description, None, parent) elif (self.paramType == parameters.PARAMETER_MAP_LAYER or isinstance(self.param, QgsProcessingParameterMapLayer)): self.param = QgsProcessingParameterMapLayer( name, description, types=[self.datatypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_RASTER or isinstance(self.param, QgsProcessingParameterRasterLayer)): self.param = QgsProcessingParameterRasterLayer( name, description) elif (self.paramType == parameters.PARAMETER_TABLE or isinstance(self.param, QgsProcessingParameterVectorLayer)): self.param = QgsProcessingParameterVectorLayer( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_VECTOR or isinstance(self.param, QgsProcessingParameterFeatureSource)): self.param = QgsProcessingParameterFeatureSource( name, description, [self.shapetypeCombo.currentData()]) elif (self.paramType == parameters.PARAMETER_MULTIPLE or isinstance(self.param, QgsProcessingParameterMultipleLayers)): self.param = QgsProcessingParameterMultipleLayers( name, description, self.datatypeCombo.currentData()) elif (self.paramType == parameters.PARAMETER_DISTANCE or isinstance(self.param, QgsProcessingParameterDistance)): self.param = QgsProcessingParameterDistance(name, description, self.defaultTextBox.text()) try: vmin = self.minTextBox.text().strip() if not vmin == '': self.param.setMinimum(float(vmin)) vmax = self.maxTextBox.text().strip() if not vmax == '': self.param.setMaximum(float(vmax)) except: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return if self.parentCombo.currentIndex() < 0: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return parent = self.parentCombo.currentData() if parent: self.param.setParentParameterName(parent) elif (self.paramType == parameters.PARAMETER_SCALE or isinstance(self.param, QgsProcessingParameterScale)): self.param = QgsProcessingParameterScale(name, description, self.defaultTextBox.text()) elif (self.paramType == parameters.PARAMETER_NUMBER or isinstance(self.param, QgsProcessingParameterNumber)): type = self.type_combo.currentData() self.param = QgsProcessingParameterNumber(name, description, type, self.defaultTextBox.text()) try: vmin = self.minTextBox.text().strip() if not vmin == '': self.param.setMinimum(float(vmin)) vmax = self.maxTextBox.text().strip() if not vmax == '': self.param.setMaximum(float(vmax)) except: QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Wrong or missing parameter values')) return elif (self.paramType == parameters.PARAMETER_EXTENT or isinstance(self.param, QgsProcessingParameterExtent)): self.param = QgsProcessingParameterExtent(name, description) elif (self.paramType == parameters.PARAMETER_ENUM or isinstance(self.param, QgsProcessingParameterEnum)): self.param = QgsProcessingParameterEnum(name, description, self.widget.options(), self.widget.allowMultiple(), self.widget.defaultOptions()) elif (self.paramType == parameters.PARAMETER_MATRIX or isinstance(self.param, QgsProcessingParameterMatrix)): self.param = QgsProcessingParameterMatrix(name, description, hasFixedNumberRows=self.widget.fixedRows(), headers=self.widget.headers(), defaultValue=self.widget.value()) # Destination parameter elif (isinstance(self.param, QgsProcessingParameterFeatureSink)): self.param = QgsProcessingParameterFeatureSink( name=name, description=self.param.description(), type=self.param.dataType(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFileDestination)): self.param = QgsProcessingParameterFileDestination( name=name, description=self.param.description(), fileFilter=self.param.fileFilter(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFolderDestination)): self.param = QgsProcessingParameterFolderDestination( name=name, description=self.param.description(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterRasterDestination)): self.param = QgsProcessingParameterRasterDestination( name=name, description=self.param.description(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterVectorDestination)): self.param = QgsProcessingParameterVectorDestination( name=name, description=self.param.description(), type=self.param.dataType(), defaultValue=self.defaultWidget.value()) else: if self.paramType: typeId = self.paramType else: typeId = self.param.type() paramTypeDef = QgsApplication.instance().processingRegistry().parameterType(typeId) if not paramTypeDef: msg = self.tr('The parameter `{}` is not registered, are you missing a required plugin?'.format(typeId)) raise UndefinedParameterException(msg) self.param = paramTypeDef.create(name) self.param.setDescription(description) self.param.setMetadata(paramTypeDef.metadata()) if not self.requiredCheck.isChecked(): self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagOptional) else: self.param.setFlags(self.param.flags() & ~QgsProcessingParameterDefinition.FlagOptional) if self.advancedCheck.isChecked(): self.param.setFlags(self.param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) else: self.param.setFlags(self.param.flags() & ~QgsProcessingParameterDefinition.FlagAdvanced) settings = QgsSettings() settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.accept(self) def reject(self): self.param = None settings = QgsSettings() settings.setValue("/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.reject(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.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.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 is not None: 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.displayName()) 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 = QgsScrollArea() 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 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.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)') label = QLabel(desc) self.labels[param.name] = label widget = self.getWidgetFromParameter(param) self.valueItems[param.name] = widget if param.name in 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.setLayout(self.verticalLayout) 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.reply = QgsNetworkAccessManager.instance().get( QNetworkRequest(algHelp)) self.reply.finished.connect(self.requestFinished) except: self.txtHelp.setHtml( self.tr('<h2>No help available for this algorithm</h2>')) self.tabWidget.addTab(self.txtHelp, 'Help') 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) 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 = unicode(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 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): values = [] inputs = self.model.inputs for i in inputs.values(): param = i.param if isinstance(param, paramType): 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 self.model.algs.values(): if alg.name not in dependent: for out in alg.algorithm.outputs: if isinstance(out, outType): 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 getWidgetFromParameter(self, param): if isinstance(param, ParameterRaster): item = QComboBox() layers = self.getAvailableValuesOfType(ParameterRaster, OutputRaster) if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(self.resolveValueDescription(layer), layer) elif isinstance(param, ParameterVector): item = QComboBox() layers = self.getAvailableValuesOfType(ParameterVector, OutputVector) if param.optional: item.addItem(self.NOT_SELECTED, None) for layer in layers: item.addItem(self.resolveValueDescription(layer), layer) elif isinstance(param, ParameterTable): item = QComboBox() tables = self.getAvailableValuesOfType(ParameterTable, OutputTable) layers = self.getAvailableValuesOfType(ParameterVector, OutputVector) if param.optional: item.addItem(self.NOT_SELECTED, None) for table in tables: item.addItem(self.resolveValueDescription(table), table) for layer in layers: item.addItem(self.resolveValueDescription(layer), layer) elif isinstance(param, ParameterBoolean): item = QComboBox() item.addItem('Yes') item.addItem('No') bools = self.getAvailableValuesOfType(ParameterBoolean, None) for b in bools: item.addItem(self.resolveValueDescription(b), b) if param.default: item.setCurrentIndex(0) else: item.setCurrentIndex(1) elif isinstance(param, ParameterSelection): item = QComboBox() item.addItems(param.options) item.setCurrentIndex(param.default or 0) elif isinstance(param, ParameterFixedTable): item = FixedTablePanel(param) elif isinstance(param, ParameterRange): item = RangePanel(param) elif isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: options = self.getAvailableValuesOfType( ParameterVector, OutputVector) else: options = self.getAvailableValuesOfType( ParameterRaster, OutputRaster) opts = [] for opt in options: opts.append(self.resolveValueDescription(opt)) item = MultipleInputPanel(opts) elif isinstance(param, ParameterString): strings = self.getAvailableValuesOfType(ParameterString, OutputString) options = [(self.resolveValueDescription(s), s) for s in strings] if param.multiline: item = MultilineTextPanel(options) item.setText(unicode(param.default or "")) else: item = QComboBox() item.setEditable(True) for desc, val in options: item.addItem(desc, val) item.setEditText(unicode(param.default or "")) elif isinstance(param, ParameterTableField): item = QComboBox() item.setEditable(True) fields = self.getAvailableValuesOfType(ParameterTableField, None) for f in fields: item.addItem(self.resolveValueDescription(f), f) elif isinstance(param, ParameterTableMultipleField): item = QComboBox() item.setEditable(True) fields = self.getAvailableValuesOfType(ParameterTableMultipleField, None) for f in fields: item.addItem(self.resolveValueDescription(f), f) elif isinstance(param, ParameterNumber): item = QComboBox() item.setEditable(True) numbers = self.getAvailableValuesOfType(ParameterNumber, OutputNumber) for n in numbers: item.addItem(self.resolveValueDescription(n), n) item.setEditText(unicode(param.default)) elif isinstance(param, ParameterCrs): item = CrsSelectionPanel(param.default) elif isinstance(param, ParameterExtent): item = QComboBox() item.setEditable(True) extents = self.getAvailableValuesOfType(ParameterExtent, OutputExtent) if self.canUseAutoExtent(): item.addItem(self.USE_MIN_COVERING_EXTENT, None) for ex in extents: item.addItem(self.resolveValueDescription(ex), ex) if not self.canUseAutoExtent(): item.setEditText(unicode(param.default)) elif isinstance(param, ParameterPoint): item = QComboBox() item.setEditable(True) points = self.getAvailableValuesOfType(ParameterPoint) for p in points: item.addItem(self.resolveValueDescription(p), p) item.setEditText(unicode(param.default)) elif isinstance(param, ParameterFile): item = QComboBox() item.setEditable(True) files = self.getAvailableValuesOfType(ParameterFile, OutputFile) for f in files: item.addItem(self.resolveValueDescription(f), f) elif isinstance(param, ParameterGeometryPredicate): item = GeometryPredicateSelectionPanel(param.enabledPredicates) else: item = QLineEdit() try: item.setText(unicode(param.default)) except: pass return item def canUseAutoExtent(self): for param in self._alg.parameters: if isinstance( param, (ParameterRaster, ParameterVector, ParameterMultipleInput)): return True return False 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 setComboBoxValue(self, combo, value, param): if isinstance(value, list): value = value[0] items = [combo.itemData(i) for i in range(combo.count())] try: idx = items.index(value) combo.setCurrentIndex(idx) return except ValueError: pass if combo.isEditable(): if value is not None: combo.setEditText(unicode(value)) elif isinstance(param, ParameterSelection): combo.setCurrentIndex(int(value)) elif isinstance(param, ParameterBoolean): if value: combo.setCurrentIndex(0) else: combo.setCurrentIndex(1) 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 widget = self.valueItems[param.name] if param.name in alg.params: value = alg.params[param.name] else: value = param.default if isinstance( param, (ParameterRaster, ParameterVector, ParameterTable, ParameterTableField, ParameterSelection, ParameterNumber, ParameterBoolean, ParameterExtent, ParameterFile, ParameterPoint)): self.setComboBoxValue(widget, value, param) elif isinstance(param, ParameterString): if param.multiline: widget.setValue(value) else: self.setComboBoxValue(widget, value, param) elif isinstance(param, ParameterCrs): widget.setAuthId(value) elif isinstance(param, ParameterFixedTable): pass # TODO! elif isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: options = self.getAvailableValuesOfType( ParameterVector, OutputVector) else: options = self.getAvailableValuesOfType( ParameterRaster, OutputRaster) selected = [] for i, opt in enumerate(options): if opt in value: selected.append(i) widget.setSelectedItems(selected) elif isinstance(param, ParameterGeometryPredicate): widget.setValue(value) for name, out in alg.outputs.iteritems(): widget = 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.valueItems[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 = unicode(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 setParamValueLayerOrTable(self, alg, param, widget): idx = widget.currentIndex() if idx < 0: return False else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamTableFieldValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = unicode(widget.currentText()).strip() if s == '': if param.optional: alg.params[param.name] = None return True else: return False else: alg.params[param.name] = s return True else: alg.params[param.name] = widget.itemData(widget.currentIndex()) return True def setParamStringValue(self, alg, param, widget): if param.multiline: value = widget.getValue() option = widget.getOption() if option == MultilineTextPanel.USE_TEXT: if value == '': if param.optional: alg.params[param.name] = None return True else: return False else: alg.params[param.name] = value else: alg.params[param.name] = value else: idx = widget.findText(widget.currentText()) if idx < 0: value = widget.currentText().strip() if value == '': if param.optional: alg.params[param.name] = None return True else: return False else: alg.params[param.name] = value else: alg.params[param.name] = widget.itemData(widget.currentIndex()) return True def setParamFileValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: value = widget.currentText() else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamNumberValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = widget.currentText().strip() if s: try: value = float(s) except: return False elif param.optional: value = None else: return False else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamExtentValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = unicode(widget.currentText()).strip() if s: try: tokens = s.split(',') if len(tokens) != 4: return False for token in tokens: float(token) except: return False elif param.optional: s = None else: return False alg.params[param.name] = [s] else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamPointValue(self, alg, param, widget): idx = widget.findText(widget.currentText()) if idx < 0: s = unicode(widget.currentText()).strip() if s: try: tokens = s.split(',') if len(tokens) != 2: return False for token in tokens: float(token) except: return False elif param.optional: s = None else: return False alg.params[param.name] = [s] else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True def setParamValue(self, alg, param, widget): if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): return self.setParamValueLayerOrTable(alg, param, widget) elif isinstance(param, ParameterBoolean): if widget.currentIndex() < 2: value = widget.currentIndex() == 0 else: value = widget.itemData(widget.currentIndex()) alg.params[param.name] = value return True elif isinstance(param, ParameterString): return self.setParamStringValue(alg, param, widget) elif isinstance(param, ParameterNumber): return self.setParamNumberValue(alg, param, widget) elif isinstance(param, ParameterExtent): return self.setParamExtentValue(alg, param, widget) elif isinstance(param, ParameterPoint): return self.setParamPointValue(alg, param, widget) elif isinstance(param, ParameterFile): return self.setParamFileValue(alg, param, widget) elif isinstance(param, ParameterSelection): alg.params[param.name] = widget.currentIndex() return True elif isinstance(param, ParameterRange): alg.params[param.name] = widget.getValue() return True elif isinstance(param, ParameterCrs): authid = widget.getValue() if authid is None and not param.optional: return False alg.params[param.name] = authid return True elif isinstance(param, ParameterFixedTable): table = widget.table if not bool(table) and not param.optional: return False alg.params[param.name] = ParameterFixedTable.tableToString(table) return True elif isinstance(param, (ParameterTableField, ParameterTableMultipleField)): return self.setParamTableFieldValue(alg, param, widget) elif isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: options = self.getAvailableValuesOfType( ParameterVector, OutputVector) else: options = self.getAvailableValuesOfType( ParameterRaster, OutputRaster) values = [options[i] for i in widget.selectedoptions] if len(values) == 0 and not param.optional: return False alg.params[param.name] = values return True elif isinstance(param, ParameterGeometryPredicate): alg.params[param.name] = widget.value() return True else: alg.params[param.name] = unicode(widget.text()) return True 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): type_metadata = QgsApplication.processingRegistry().parameterType( self.param.type() if self.param else self.paramType) self.setWindowTitle( self.tr('{} Parameter Definition').format(type_metadata.name())) self.mainLayout = QVBoxLayout() self.tab = QTabWidget() self.mainLayout.addWidget(self.tab) self.setMinimumWidth(300) self.verticalLayout = QVBoxLayout() self.label = QLabel(self.tr('Parameter name')) self.verticalLayout.addWidget(self.label) self.nameTextBox = QLineEdit() self.verticalLayout.addWidget(self.nameTextBox) if isinstance(self.param, QgsProcessingParameterDefinition): self.nameTextBox.setText(self.param.description()) if isinstance(self.param, QgsProcessingDestinationParameter): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultWidget = QgsProcessingLayerOutputDestinationWidget( self.param, defaultSelection=True) self.verticalLayout.addWidget(self.defaultWidget) self.verticalLayout.addSpacing(20) self.requiredCheck = QCheckBox() self.requiredCheck.setText(self.tr('Mandatory')) self.requiredCheck.setChecked(True) if self.param is not None: self.requiredCheck.setChecked( not self.param.flags() & QgsProcessingParameterDefinition.FlagOptional) self.verticalLayout.addWidget(self.requiredCheck) self.advancedCheck = QCheckBox() self.advancedCheck.setText(self.tr('Advanced')) self.advancedCheck.setChecked(False) if self.param is not None: self.advancedCheck.setChecked( self.param.flags() & QgsProcessingParameterDefinition.FlagAdvanced) self.verticalLayout.addWidget(self.advancedCheck) # If child algorithm output is mandatory, disable checkbox if isinstance(self.param, QgsProcessingDestinationParameter): child = self.alg.childAlgorithms()[self.param.metadata() ['_modelChildId']] model_output = child.modelOutput( self.param.metadata()['_modelChildOutputName']) param_def = child.algorithm().parameterDefinition( model_output.childOutputName()) if not (param_def.flags() & QgsProcessingParameterDefinition.FlagOptional): self.requiredCheck.setEnabled(False) self.requiredCheck.setChecked(True) self.advancedCheck.setEnabled(False) self.advancedCheck.setChecked(False) self.verticalLayout.addStretch() w = QWidget() w.setLayout(self.verticalLayout) self.tab.addTab(w, self.tr('Properties')) self.commentLayout = QVBoxLayout() self.commentEdit = QTextEdit() self.commentEdit.setAcceptRichText(False) self.commentLayout.addWidget(self.commentEdit, 1) hl = QHBoxLayout() hl.setContentsMargins(0, 0, 0, 0) hl.addWidget(QLabel(self.tr('Color'))) self.comment_color_button = QgsColorButton() self.comment_color_button.setAllowOpacity(True) self.comment_color_button.setWindowTitle(self.tr('Comment Color')) self.comment_color_button.setShowNull(True, self.tr('Default')) hl.addWidget(self.comment_color_button) self.commentLayout.addLayout(hl) w2 = QWidget() w2.setLayout(self.commentLayout) self.tab.addTab(w2, self.tr('Comments')) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName('buttonBox') self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.mainLayout.addWidget(self.buttonBox) self.setLayout(self.mainLayout)
def __init__(self, section_id, parent=None): QTabWidget.__init__(self, parent) self.setupUi(self) self.charts = [] self.section_id = section_id
class DBManager(QMainWindow): def __init__(self, iface, parent=None): QMainWindow.__init__(self, parent) self.setAttribute(Qt.WA_DeleteOnClose) self.setupUi() self.iface = iface # restore the window state settings = QgsSettings() self.restoreGeometry(settings.value("/DB_Manager/mainWindow/geometry", QByteArray(), type=QByteArray)) self.restoreState(settings.value("/DB_Manager/mainWindow/windowState", QByteArray(), type=QByteArray)) self.tabs.currentChanged.connect(self.tabChanged) self.tree.selectedItemChanged.connect(self.itemChanged) self.itemChanged(None) def closeEvent(self, e): self.unregisterAllActions() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) # save the window state settings = QgsSettings() settings.setValue("/DB_Manager/mainWindow/windowState", self.saveState()) settings.setValue("/DB_Manager/mainWindow/geometry", self.saveGeometry()) QMainWindow.closeEvent(self, e) def refreshItem(self, item=None): with OverrideCursor(Qt.WaitCursor): try: if item is None: item = self.tree.currentItem() self.tree.refreshItem(item) # refresh item children in the db tree except BaseError as e: DlgDbError.showError(e, self) def itemChanged(self, item): with OverrideCursor(Qt.WaitCursor): try: self.reloadButtons() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def reloadButtons(self): db = self.tree.currentDatabase() if not hasattr(self, '_lastDb'): self._lastDb = db elif db == self._lastDb: return # remove old actions if self._lastDb is not None: self.unregisterAllActions() # add actions of the selected database self._lastDb = db if self._lastDb is not None: self._lastDb.registerAllActions(self) def tabChanged(self, index): with OverrideCursor(Qt.WaitCursor): try: self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def refreshTabs(self): index = self.tabs.currentIndex() item = self.tree.currentItem() table = self.tree.currentTable() # enable/disable tabs self.tabs.setTabEnabled(self.tabs.indexOf(self.table), table is not None) self.tabs.setTabEnabled(self.tabs.indexOf(self.preview), table is not None and table.type in [table.VectorType, table.RasterType] and table.geomColumn is not None) # show the info tab if the current tab is disabled if not self.tabs.isTabEnabled(index): self.tabs.setCurrentWidget(self.info) current_tab = self.tabs.currentWidget() if current_tab == self.info: self.info.showInfo(item) elif current_tab == self.table: self.table.loadData(item) elif current_tab == self.preview: self.preview.loadPreview(item) def refreshActionSlot(self): self.info.setDirty() self.table.setDirty() self.preview.setDirty() self.refreshItem() def importActionSlot(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), QgsMessageBar.INFO, self.iface.messageTimeout()) return outUri = db.uri() schema = self.tree.currentSchema() if schema: outUri.setDataSource(schema.name, "", "", "") from .dlg_import_vector import DlgImportVector dlg = DlgImportVector(None, db, outUri, self) dlg.exec_() def exportActionSlot(self): table = self.tree.currentTable() if table is None: self.infoBar.pushMessage(self.tr("Select the table you want export to file."), QgsMessageBar.INFO, self.iface.messageTimeout()) return inLayer = table.toMapLayer() if inLayer.type() != QgsMapLayer.VectorLayer: self.infoBar.pushMessage( self.tr("Select a vector or a tabular layer you want export."), QgsMessageBar.WARNING, self.iface.messageTimeout()) return from .dlg_export_vector import DlgExportVector dlg = DlgExportVector(inLayer, table.database(), self) dlg.exec_() inLayer.deleteLater() def runSqlWindow(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), QgsMessageBar.INFO, self.iface.messageTimeout()) # force displaying of the message, it appears on the first tab (i.e. Info) self.tabs.setCurrentIndex(0) return from .dlg_sql_window import DlgSqlWindow query = DlgSqlWindow(self.iface, db, self) dbname = db.connection().connectionName() tabname = self.tr("Query ({0})").format(dbname) index = self.tabs.addTab(query, tabname) self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) query.nameChanged.connect(functools.partial(self.update_query_tab_name, index, dbname)) def runSqlLayerWindow(self, layer): from .dlg_sql_layer_window import DlgSqlLayerWindow query = DlgSqlLayerWindow(self.iface, layer, self) lname = layer.name() tabname = self.tr("Layer ({0})").format(lname) index = self.tabs.addTab(query, tabname) # self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) def update_query_tab_name(self, index, dbname, queryname): if not queryname: queryname = self.tr("Query") tabname = u"%s (%s)" % (queryname, dbname) self.tabs.setTabText(index, tabname) def showSystemTables(self): self.tree.showSystemTables(self.actionShowSystemTables.isChecked()) def registerAction(self, action, menuName, callback=None): """ register an action to the manager's main menu """ if not hasattr(self, '_registeredDbActions'): self._registeredDbActions = {} if callback is not None: def invoke_callback(x): return self.invokeCallback(callback) if menuName is None or menuName == "": self.addAction(action) if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True # search for the menu actionMenu = None helpMenuAction = None for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue if a.menu() != self.menuHelp: helpMenuAction = a actionMenu = a break # not found, add a new menu before the help menu if actionMenu is None: menu = QMenu(menuName, self) if helpMenuAction is not None: actionMenu = self.menuBar.insertMenu(helpMenuAction, menu) else: actionMenu = self.menuBar.addMenu(menu) menu = actionMenu.menu() menuActions = menu.actions() # get the placeholder's position to insert before it pos = 0 for pos in range(len(menuActions)): if menuActions[pos].isSeparator() and menuActions[pos].objectName().endswith("_placeholder"): menuActions[pos].setVisible(True) break if pos < len(menuActions): before = menuActions[pos] menu.insertAction(before, action) else: menu.addAction(action) actionMenu.setVisible(True) # show the menu if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True def invokeCallback(self, callback, *params): """ Call a method passing the selected item in the database tree, the sender (usually a QAction), the plugin mainWindow and optionally additional parameters. This method takes care to override and restore the cursor, but also catches exceptions and displays the error dialog. """ with OverrideCursor(Qt.WaitCursor): try: callback(self.tree.currentItem(), self.sender(), self, *params) except BaseError as e: # catch database errors and display the error dialog DlgDbError.showError(e, self) def unregisterAction(self, action, menuName): if not hasattr(self, '_registeredDbActions'): return if menuName is None or menuName == "": self.removeAction(action) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) action.deleteLater() return True for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue menu = a.menu() menuActions = menu.actions() menu.removeAction(action) if menu.isEmpty(): # hide the menu a.setVisible(False) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) # hide the placeholder if there're no other registered actions if len(self._registeredDbActions[menuName]) <= 0: for i in range(len(menuActions)): if menuActions[i].isSeparator() and menuActions[i].objectName().endswith("_placeholder"): menuActions[i].setVisible(False) break action.deleteLater() return True return False def unregisterAllActions(self): if not hasattr(self, '_registeredDbActions'): return for menuName in self._registeredDbActions: for action in list(self._registeredDbActions[menuName]): self.unregisterAction(action, menuName) del self._registeredDbActions def close_tab(self, index): widget = self.tabs.widget(index) if widget not in [self.info, self.table, self.preview]: self.tabs.removeTab(index) widget.deleteLater() def setupUi(self): self.setWindowTitle(self.tr("DB Manager")) self.setWindowIcon(QIcon(":/db_manager/icon")) self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint())) # create central tab widget and add the first 3 tabs: info, table and preview self.tabs = QTabWidget() self.info = InfoViewer(self) self.tabs.addTab(self.info, self.tr("Info")) self.table = TableViewer(self) self.tabs.addTab(self.table, self.tr("Table")) self.preview = LayerPreview(self) self.tabs.addTab(self.preview, self.tr("Preview")) self.setCentralWidget(self.tabs) # display close button for all tabs but the first 3 ones, i.e. # HACK: just hide the close button where not needed (GS) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) tabbar = self.tabs.tabBar() for i in range(3): btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide) btn.resize(0, 0) btn.hide() # Creates layout for message bar self.layout = QGridLayout(self.info) self.layout.setContentsMargins(0, 0, 0, 0) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.layout.addItem(spacerItem, 1, 0, 1, 1) # init messageBar instance self.infoBar = QgsMessageBar(self.info) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.infoBar.setSizePolicy(sizePolicy) self.layout.addWidget(self.infoBar, 0, 0, 1, 1) # create database tree self.dock = QDockWidget("Tree", self) self.dock.setObjectName("DB_Manager_DBView") self.dock.setFeatures(QDockWidget.DockWidgetMovable) self.tree = DBTree(self) self.dock.setWidget(self.tree) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock) # create status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) # create menus self.menuBar = QMenuBar(self) self.menuDb = QMenu(self.tr("&Database"), self) self.menuBar.addMenu(self.menuDb) self.menuSchema = QMenu(self.tr("&Schema"), self) actionMenuSchema = self.menuBar.addMenu(self.menuSchema) self.menuTable = QMenu(self.tr("&Table"), self) actionMenuTable = self.menuBar.addMenu(self.menuTable) self.menuHelp = None # QMenu(self.tr("&Help"), self) # actionMenuHelp = self.menuBar.addMenu(self.menuHelp) self.setMenuBar(self.menuBar) # create toolbar self.toolBar = QToolBar("Default", self) self.toolBar.setObjectName("DB_Manager_ToolBar") self.addToolBar(self.toolBar) # create menus' actions # menu DATABASE sep = self.menuDb.addSeparator() sep.setObjectName("DB_Manager_DbMenu_placeholder") sep.setVisible(False) self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"), self.refreshActionSlot, QKeySequence("F5")) self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"), self.runSqlWindow, QKeySequence("F2")) self.menuDb.addSeparator() self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q")) # menu SCHEMA sep = self.menuSchema.addSeparator() sep.setObjectName("DB_Manager_SchemaMenu_placeholder") sep.setVisible(False) actionMenuSchema.setVisible(False) # menu TABLE sep = self.menuTable.addSeparator() sep.setObjectName("DB_Manager_TableMenu_placeholder") sep.setVisible(False) self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"), self.tr("&Import layer/file"), self.importActionSlot) self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"), self.exportActionSlot) self.menuTable.addSeparator() #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables) #self.actionShowSystemTables.setCheckable(True) #self.actionShowSystemTables.setChecked(True) actionMenuTable.setVisible(False) # add actions to the toolbar self.toolBar.addAction(self.actionRefresh) self.toolBar.addAction(self.actionSqlWindow) self.toolBar.addAction(self.actionImport) self.toolBar.addAction(self.actionExport)
class ModelerParameterDefinitionDialog(QDialog): @staticmethod def use_legacy_dialog(param=None, paramType=None): if isinstance(param, QgsProcessingDestinationParameter): return True # yay, use new API! return False def __init__(self, alg, paramType=None, param=None): self.alg = alg self.paramType = paramType self.param = param QDialog.__init__(self) self.setModal(True) self.setupUi() settings = QgsSettings() self.restoreGeometry( settings.value( "/Processing/modelParametersDefinitionDialogGeometry", QByteArray())) def closeEvent(self, event): settings = QgsSettings() settings.setValue( "/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) super(ModelerParameterDefinitionDialog, self).closeEvent(event) def switchToCommentTab(self): self.tab.setCurrentIndex(1) self.commentEdit.setFocus() self.commentEdit.selectAll() def setupUi(self): type_metadata = QgsApplication.processingRegistry().parameterType( self.param.type() if self.param else self.paramType) self.setWindowTitle( self.tr('{} Parameter Definition').format(type_metadata.name())) self.mainLayout = QVBoxLayout() self.tab = QTabWidget() self.mainLayout.addWidget(self.tab) self.setMinimumWidth(300) self.verticalLayout = QVBoxLayout() self.label = QLabel(self.tr('Parameter name')) self.verticalLayout.addWidget(self.label) self.nameTextBox = QLineEdit() self.verticalLayout.addWidget(self.nameTextBox) if isinstance(self.param, QgsProcessingParameterDefinition): self.nameTextBox.setText(self.param.description()) if isinstance(self.param, QgsProcessingDestinationParameter): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultWidget = QgsProcessingLayerOutputDestinationWidget( self.param, defaultSelection=True) self.verticalLayout.addWidget(self.defaultWidget) self.verticalLayout.addSpacing(20) self.requiredCheck = QCheckBox() self.requiredCheck.setText(self.tr('Mandatory')) self.requiredCheck.setChecked(True) if self.param is not None: self.requiredCheck.setChecked( not self.param.flags() & QgsProcessingParameterDefinition.FlagOptional) self.verticalLayout.addWidget(self.requiredCheck) self.advancedCheck = QCheckBox() self.advancedCheck.setText(self.tr('Advanced')) self.advancedCheck.setChecked(False) if self.param is not None: self.advancedCheck.setChecked( self.param.flags() & QgsProcessingParameterDefinition.FlagAdvanced) self.verticalLayout.addWidget(self.advancedCheck) # If child algorithm output is mandatory, disable checkbox if isinstance(self.param, QgsProcessingDestinationParameter): child = self.alg.childAlgorithms()[self.param.metadata() ['_modelChildId']] model_output = child.modelOutput( self.param.metadata()['_modelChildOutputName']) param_def = child.algorithm().parameterDefinition( model_output.childOutputName()) if not (param_def.flags() & QgsProcessingParameterDefinition.FlagOptional): self.requiredCheck.setEnabled(False) self.requiredCheck.setChecked(True) self.advancedCheck.setEnabled(False) self.advancedCheck.setChecked(False) self.verticalLayout.addStretch() w = QWidget() w.setLayout(self.verticalLayout) self.tab.addTab(w, self.tr('Properties')) self.commentLayout = QVBoxLayout() self.commentEdit = QTextEdit() self.commentEdit.setAcceptRichText(False) self.commentLayout.addWidget(self.commentEdit, 1) hl = QHBoxLayout() hl.setContentsMargins(0, 0, 0, 0) hl.addWidget(QLabel(self.tr('Color'))) self.comment_color_button = QgsColorButton() self.comment_color_button.setAllowOpacity(True) self.comment_color_button.setWindowTitle(self.tr('Comment Color')) self.comment_color_button.setShowNull(True, self.tr('Default')) hl.addWidget(self.comment_color_button) self.commentLayout.addLayout(hl) w2 = QWidget() w2.setLayout(self.commentLayout) self.tab.addTab(w2, self.tr('Comments')) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName('buttonBox') self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.mainLayout.addWidget(self.buttonBox) self.setLayout(self.mainLayout) def setComments(self, text): self.commentEdit.setPlainText(text) def comments(self): return self.commentEdit.toPlainText() def setCommentColor(self, color): if color.isValid(): self.comment_color_button.setColor(color) else: self.comment_color_button.setToNull() def commentColor(self): return self.comment_color_button.color( ) if not self.comment_color_button.isNull() else QColor() def accept(self): description = self.nameTextBox.text() if description.strip() == '': QMessageBox.warning(self, self.tr('Unable to define parameter'), self.tr('Invalid parameter name')) return validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeName = ''.join(c for c in description if c in validChars) name = safeName.lower() # Destination parameter if (isinstance(self.param, QgsProcessingParameterFeatureSink)): self.param = QgsProcessingParameterFeatureSink( name=name, description=description, type=self.param.dataType(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFileDestination)): self.param = QgsProcessingParameterFileDestination( name=name, description=description, fileFilter=self.param.fileFilter(), defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterFolderDestination)): self.param = QgsProcessingParameterFolderDestination( name=name, description=description, defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterRasterDestination)): self.param = QgsProcessingParameterRasterDestination( name=name, description=description, defaultValue=self.defaultWidget.value()) elif (isinstance(self.param, QgsProcessingParameterVectorDestination)): self.param = QgsProcessingParameterVectorDestination( name=name, description=description, type=self.param.dataType(), defaultValue=self.defaultWidget.value()) else: if self.paramType: typeId = self.paramType else: typeId = self.param.type() paramTypeDef = QgsApplication.instance().processingRegistry( ).parameterType(typeId) if not paramTypeDef: msg = self.tr( 'The parameter `{}` is not registered, are you missing a required plugin?' .format(typeId)) raise UndefinedParameterException(msg) self.param = paramTypeDef.create(name) self.param.setDescription(description) self.param.setMetadata(paramTypeDef.metadata()) if not self.requiredCheck.isChecked(): self.param.setFlags( self.param.flags() | QgsProcessingParameterDefinition.FlagOptional) else: self.param.setFlags( self.param.flags() & ~QgsProcessingParameterDefinition.FlagOptional) if self.advancedCheck.isChecked(): self.param.setFlags( self.param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) else: self.param.setFlags( self.param.flags() & ~QgsProcessingParameterDefinition.FlagAdvanced) settings = QgsSettings() settings.setValue( "/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.accept(self) def reject(self): self.param = None settings = QgsSettings() settings.setValue( "/Processing/modelParametersDefinitionDialogGeometry", self.saveGeometry()) QDialog.reject(self)