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")
Esempio n. 2
0
    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)
Esempio n. 3
0
    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
Esempio n. 4
0
    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)
Esempio n. 5
0
    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")
Esempio n. 7
0
    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")
Esempio n. 9
0
    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)
Esempio n. 11
0
            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)
Esempio n. 12
0
 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)
Esempio n. 13
0
    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)
Esempio n. 14
0
    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)
Esempio n. 15
0
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)
Esempio n. 16
0
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
Esempio n. 17
0
    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())
Esempio n. 18
0
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
Esempio n. 19
0
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()
Esempio n. 20
0
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
Esempio n. 21
0
    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)
Esempio n. 22
0
    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 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)
Esempio n. 24
0
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
Esempio n. 25
0
    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&nbsp;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 = []
Esempio n. 27
0
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()
Esempio n. 28
0
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()
Esempio n. 29
0
    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()))
Esempio n. 30
0
    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)
Esempio n. 31
0
    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)
Esempio n. 32
0
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)
Esempio n. 33
0
    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()))
Esempio n. 34
0
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)
Esempio n. 36
0
 def __init__(self, section_id, parent=None):
     QTabWidget.__init__(self, parent)
     self.setupUi(self)
     self.charts = []
     self.section_id = section_id
Esempio n. 37
0
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)