コード例 #1
0
class ButtonLineEdit(QLineEdit):
    buttonClicked = pyqtSignal()

    def __init__(self, parent=None):
        super(ButtonLineEdit, self).__init__(parent)

        self.setPlaceholderText("Search")

        self.btnSearch = QToolButton(self)
        self.btnSearch.setIcon(QIcon(os.path.join(pluginPath, "icons", "search.svg")))
        self.btnSearch.setStyleSheet("QToolButton { padding: 0px; }")
        self.btnSearch.setCursor(Qt.ArrowCursor)
        self.btnSearch.clicked.connect(self.buttonClicked.emit)

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        buttonSize = self.btnSearch.sizeHint()

        self.setStyleSheet("QLineEdit {{padding-right: {}px; }}".format(buttonSize.width() + frameWidth + 1))
        self.setMinimumSize(max(self.minimumSizeHint().width(), buttonSize.width() + frameWidth * 2 + 2),
                            max(self.minimumSizeHint().height(), buttonSize.height() + frameWidth * 2 + 2))

    def resizeEvent(self, event):
        buttonSize = self.btnSearch.sizeHint()
        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.btnSearch.move(self.rect().right() - frameWidth - buttonSize.width(),
                            (self.rect().bottom() - buttonSize.height() + 1) / 2)

        super(ButtonLineEdit, self).resizeEvent(event)
コード例 #2
0
    def setupUi(self, PostNAS_SearchDialogBase):
        PostNAS_SearchDialogBase.setObjectName(_fromUtf8("PostNAS_SearchDialogBase"))
        PostNAS_SearchDialogBase.resize(501, 337)
        self.gridLayout = QGridLayout(PostNAS_SearchDialogBase)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.treeWidget = QTreeWidget(PostNAS_SearchDialogBase)
        self.treeWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.treeWidget.setHeaderHidden(True)
        self.treeWidget.setObjectName(_fromUtf8("treeWidget"))
        self.treeWidget.headerItem().setText(0, _fromUtf8("1"))
        self.gridLayout.addWidget(self.treeWidget, 1, 0, 1, 3)
        self.lineEdit = QLineEdit(PostNAS_SearchDialogBase)
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 3)
        self.showButton = QToolButton(PostNAS_SearchDialogBase)
        self.showButton.setEnabled(False)
        icon = QtGui.QIcon()
        icon.addPixmap(QPixmap(_fromUtf8(":/plugins/PostNAS_Search/search_16x16.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.showButton.setIcon(icon)
        self.showButton.setObjectName(_fromUtf8("showButton"))
        self.gridLayout.addWidget(self.showButton, 2, 2, 1, 1)
        self.resetButton = QToolButton(PostNAS_SearchDialogBase)
        self.resetButton.setEnabled(False)
        icon1 = QIcon()
        icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/PostNAS_Search/marker-delete.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.resetButton.setIcon(icon1)
        self.resetButton.setObjectName(_fromUtf8("resetButton"))
        self.gridLayout.addWidget(self.resetButton, 2, 1, 1, 1)

        self.retranslateUi(PostNAS_SearchDialogBase)
        QtCore.QMetaObject.connectSlotsByName(PostNAS_SearchDialogBase)
コード例 #3
0
    def createWidget(self):
        if self.dialogType == DIALOG_STANDARD:
            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            self.combo = QgsMapLayerComboBox()
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)

            widget.setLayout(layout)

            if self.param.optional:
                self.combo.setAllowEmptyLayer(True)

            self.combo.setFilters(QgsMapLayerProxyModel.VectorLayer)
            self.combo.setExcludedProviders(['grass'])

            self.combo.currentIndexChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
            self.combo.currentTextChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
            return widget

        elif self.dialogType == DIALOG_BATCH:
            return BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
        else:
            self.combo = QComboBox()
            layers = self.dialog.getAvailableValuesOfType(ParameterRaster, OutputRaster)
            self.combo.setEditable(True)
            tables = self.dialog.getAvailableValuesOfType(ParameterTable, OutputTable)
            layers = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector)
            if self.param.optional:
                self.combo.addItem(self.NOT_SELECTED, None)
            for table in tables:
                self.combo.addItem(self.dialog.resolveValueDescription(table), table)
            for layer in layers:
                self.combo.addItem(self.dialog.resolveValueDescription(layer), layer)

            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)
            widget.setLayout(layout)
            return widget
コード例 #4
0
    def initGui(self):
        hlayout = QHBoxLayout()
        layout = QVBoxLayout()
        self.searchBox = QLineEdit()
        self.searchBox.returnPressed.connect(self.search)
        self.searchBox.setPlaceholderText("[Enter search string and press enter to search for maps]")
        hlayout.addWidget(self.searchBox)

        self.button = QToolButton()
        self.button.setText("Search")
        self.button.clicked.connect(self.search)
        self.button.adjustSize()
        self.searchBox.setFixedHeight(self.button.height())
        hlayout.addWidget(self.button)
        layout.addLayout(hlayout)

        w = QFrame()
        self.browser = QWebView()
        w.setStyleSheet("QFrame{border:1px solid rgb(0, 0, 0);}")
        innerlayout = QHBoxLayout()
        innerlayout.setSpacing(0)
        innerlayout.setMargin(0)
        innerlayout.addWidget(self.browser)
        w.setLayout(innerlayout)
        layout.addWidget(w)
        self.setLayout(layout)

        self.browser.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
        self.browser.settings().setUserStyleSheetUrl(QUrl("file://" + resourceFile("search.css").replace("\\", "/")))
        self.browser.linkClicked.connect(self.linkClicked)
        self.resize(600, 500)
        self.setWindowTitle("Search stories")
コード例 #5
0
ファイル: ConfigDialog.py プロジェクト: mj10777/QGIS
class FileDirectorySelector(QWidget):

    def __init__(self, parent=None, selectFile=False):
        QWidget.__init__(self, parent)

        # create gui
        self.btnSelect = QToolButton()
        self.btnSelect.setText('…')
        self.lineEdit = QLineEdit()
        self.hbl = QHBoxLayout()
        self.hbl.setMargin(0)
        self.hbl.setSpacing(0)
        self.hbl.addWidget(self.lineEdit)
        self.hbl.addWidget(self.btnSelect)

        self.setLayout(self.hbl)

        self.canFocusOut = False
        self.selectFile = selectFile

        self.setFocusPolicy(Qt.StrongFocus)
        self.btnSelect.clicked.connect(self.select)

    def select(self):
        lastDir = ''
        if not self.selectFile:
            selectedPath = QFileDialog.getExistingDirectory(None,
                                                            self.tr('Select directory'), lastDir,
                                                            QFileDialog.ShowDirsOnly)
        else:
            selectedPath, selected_filter = QFileDialog.getOpenFileName(None,
                                                                        self.tr('Select file'), lastDir, self.tr('All files (*.*)')
                                                                        )

        if not selectedPath:
            return

        self.lineEdit.setText(selectedPath)
        self.canFocusOut = True

    def text(self):
        return self.lineEdit.text()

    def setText(self, value):
        self.lineEdit.setText(value)
コード例 #6
0
ファイル: ConfigDialog.py プロジェクト: phborba/QGIS
class MultipleDirectorySelector(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        # create gui
        self.btnSelect = QToolButton()
        self.btnSelect.setText('…')
        self.lineEdit = QLineEdit()
        self.hbl = QHBoxLayout()
        self.hbl.setMargin(0)
        self.hbl.setSpacing(0)
        self.hbl.addWidget(self.lineEdit)
        self.hbl.addWidget(self.btnSelect)

        self.setLayout(self.hbl)

        self.canFocusOut = False

        self.setFocusPolicy(Qt.StrongFocus)
        self.btnSelect.clicked.connect(self.select)

    def select(self):
        text = self.lineEdit.text()
        if text != '':
            items = text.split(';')
        else:
            items = []

        dlg = DirectorySelectorDialog(None, items)
        if dlg.exec_():
            text = dlg.value()
            self.lineEdit.setText(text)

        self.canFocusOut = True

    def text(self):
        return self.lineEdit.text()

    def setText(self, value):
        self.lineEdit.setText(value)
コード例 #7
0
ファイル: wrappers.py プロジェクト: GrokImageCompression/QGIS
    def createWidget(self):
        if self.dialogType == DIALOG_MODELER:
            self.combo = QComboBox()
            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(1)
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setIcon(QgsApplication.getThemeIcon("mActionSetProjection.svg"))
            btn.setToolTip(self.tr("Select CRS"))
            btn.clicked.connect(self.selectProjection)
            layout.addWidget(btn)

            widget.setLayout(layout)
            self.combo.setEditable(True)
            crss = self.dialog.getAvailableValuesOfType(ParameterCrs)
            for crs in crss:
                self.combo.addItem(self.dialog.resolveValueDescription(crs), crs)
            raster = self.dialog.getAvailableValuesOfType(ParameterRaster, OutputRaster)
            vector = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector)
            for r in raster:
                self.combo.addItem("Crs of layer " + self.dialog.resolveValueDescription(r), r)
            for v in vector:
                self.combo.addItem("Crs of layer " + self.dialog.resolveValueDescription(v), v)
            if not self.param.default:
                self.combo.setEditText(self.param.default)
            return widget
        else:

            widget = QgsProjectionSelectionWidget()
            if self.param.optional:
                widget.setOptionVisible(QgsProjectionSelectionWidget.CrsNotSet, True)

            if self.param.default:
                crs = QgsCoordinateReferenceSystem(self.param.default)
                widget.setCrs(crs)

            return widget
コード例 #8
0
 def __init__(self, parent, tree, providerName, param):
     QTreeWidgetItem.__init__(self, parent)
     self.providereName = providerName
     self.param = param
     self.tree = tree
     self.setText(0, param.description)
     self.paramName = settingName(providerName, param.name)
     if isinstance(param.defaultValue, bool):
         self.value = QSettings().value(self.paramName, defaultValue=param.defaultValue, type=bool)
         if self.value:
             self.setCheckState(1, Qt.Checked)
         else:
             self.setCheckState(1, Qt.Unchecked)
     elif isinstance(param.defaultValue, list):
         self.combo = QComboBox()
         for element in param.defaultValue:
             self.combo.addItem(element)
         self.tree.setItemWidget(self, 1, self.combo)
         self.value = QSettings().value(self.paramName, defaultValue=param.defaultValue[0])
         idx = self.combo.findText(self.value)
         self.combo.setCurrentIndex(idx)
     elif param.description == "Password":
         self.passwordField = QLineEdit()
         self.passwordField.setEchoMode(QLineEdit.Password);
         #self.passwordField.setStyleSheet("QLineEdit { border: none }");
         self.value = QSettings().value(self.paramName, defaultValue=param.defaultValue)
         self.passwordField.setText(str(self.value))
         self.tree.setItemWidget(self, 1, self.passwordField)
     elif param.action is not None:
         layout = QHBoxLayout()
         layout.setMargin(0)
         layout.setSpacing(0)
         self.textbox = QLineEdit()
         self.value = QSettings().value(self.paramName, defaultValue=param.defaultValue)
         self.textbox.setText(str(self.value))
         layout.addWidget(self.textbox)
         self.button = QToolButton()
         self.button.setText(param.actionText)
         self.button.clicked.connect(param.action)
         layout.addWidget(self.button)
         self.widget = QWidget()
         self.widget.setLayout(layout)
         self.tree.setItemWidget(self, 1, self.widget)
     else:
         self.textbox = QLineEdit()
         #self.textbox.setStyleSheet("QLineEdit { border: none }");
         self.tree.setItemWidget(self, 1, self.textbox)
         self.value = QSettings().value(self.paramName, defaultValue=param.defaultValue)
         self.textbox.setText(str(self.value))
コード例 #9
0
    def initGui(self):
        readTrackedLayers()

        QgsMapLayerRegistry.instance().layerWasAdded.connect(trackLayer)
        QgsMapLayerRegistry.instance().layerRemoved.connect(layerRemoved)

        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/geogig.png")
        self.explorerAction = navigatorInstance.toggleViewAction()
        self.explorerAction.setIcon(icon)
        self.explorerAction.setText("GeoGig Navigator")
        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/identify.png")
        self.toolAction = QAction(icon, "GeoGig Feature Info Tool", self.iface.mainWindow())
        self.toolAction.setCheckable(True)
        self.toolAction.triggered.connect(self.setTool)

        self.menu = QMenu(self.iface.mainWindow())
        self.menu.setTitle("GeoGig")
        self.menu.addAction(self.explorerAction)
        self.menu.addAction(self.toolAction)
        bar = self.iface.layerToolBar()
        self.toolButton = QToolButton()
        self.toolButton.setMenu(self.menu)
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButton.setDefaultAction(self.explorerAction)
        bar.addWidget(self.toolButton)
        self.iface.addPluginToMenu("&GeoGig", self.explorerAction)
        self.iface.addPluginToMenu("&GeoGig", self.toolAction)

        addSettingsMenu("GeoGig")
        addHelpMenu("GeoGig")
        addAboutMenu("GeoGig")

        self.mapTool = MapToolGeoGigInfo(self.iface.mapCanvas())

        #This crashes QGIS, so we comment it out until finding a solution
        #self.mapTool.setAction(self.toolAction)

        self.iface.addDockWidget(Qt.RightDockWidgetArea, navigatorInstance)

        try:
            from lessons import addLessonsFolder, addGroup
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            addLessonsFolder(folder, "geogig")
            group_description = os.path.join(folder, "group.md")
            addGroup("GeoGig lessons", group_description)
        except Exception as e:
            pass
コード例 #10
0
 def __init__(self, repo, ref = None):
     super(RefPanel, self).__init__(None)
     self.repo = repo
     self.ref = ref
     self.horizontalLayout = QHBoxLayout(self)
     self.horizontalLayout.setSpacing(2)
     self.horizontalLayout.setMargin(0)
     self.text = QLineEdit()
     self.text.setEnabled(False)
     if ref is not None:
         self.text.setText(ref.humantext())
     self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
     self.horizontalLayout.addWidget(self.text)
     self.pushButton = QToolButton()
     self.pushButton.setText("...")
     self.pushButton.clicked.connect(self.showSelectionDialog)
     self.pushButton.setEnabled(self.repo is not None)
     self.horizontalLayout.addWidget(self.pushButton)
     self.setLayout(self.horizontalLayout)
コード例 #11
0
ファイル: ConfigDialog.py プロジェクト: mj10777/QGIS
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        # create gui
        self.btnSelect = QToolButton()
        self.btnSelect.setText('…')
        self.lineEdit = QLineEdit()
        self.hbl = QHBoxLayout()
        self.hbl.setMargin(0)
        self.hbl.setSpacing(0)
        self.hbl.addWidget(self.lineEdit)
        self.hbl.addWidget(self.btnSelect)

        self.setLayout(self.hbl)

        self.canFocusOut = False

        self.setFocusPolicy(Qt.StrongFocus)
        self.btnSelect.clicked.connect(self.select)
コード例 #12
0
class RefPanel(QWidget):

    refChanged = pyqtSignal()

    def __init__(self, repo, ref = None):
        super(RefPanel, self).__init__(None)
        self.repo = repo
        self.ref = ref
        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setSpacing(2)
        self.horizontalLayout.setMargin(0)
        self.text = QLineEdit()
        self.text.setEnabled(False)
        if ref is not None:
            self.text.setText(ref.humantext())
        self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.horizontalLayout.addWidget(self.text)
        self.pushButton = QToolButton()
        self.pushButton.setText("...")
        self.pushButton.clicked.connect(self.showSelectionDialog)
        self.pushButton.setEnabled(self.repo is not None)
        self.horizontalLayout.addWidget(self.pushButton)
        self.setLayout(self.horizontalLayout)

    def showSelectionDialog(self):
        from geogig.gui.dialogs.historyviewer import HistoryViewerDialog
        dialog = HistoryViewerDialog(self.repo)
        dialog.exec_()
        ref = dialog.ref
        if ref:
            commit = Commit.fromref(self.repo, ref)
            self.setRef(commit)

    def setRepo(self, repo):
        self.repo = repo
        self.pushButton.setEnabled(True)
        self.setRef(Commitish(repo, repo.HEAD))

    def setRef(self, ref):
        self.ref = ref
        self.text.setText(ref.humantext())
        self.refChanged.emit()

    def getRef(self):
        return self.ref
コード例 #13
0
    def __init__(self, geoservice, image_ba, parent=None, extent_renderer=None):
        QWidget.__init__(self, parent)

        self.extent_renderer = extent_renderer

        self.layout = QHBoxLayout(self)
        self.layout.setContentsMargins(5, 10, 5, 10)
        self.setLayout(self.layout)

        self.service_icon = QLabel(self)
        self.service_icon.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.service_icon.resize(24, 24)

        qimg = QImage.fromData(image_ba)
        pixmap = QPixmap.fromImage(qimg)
        self.service_icon.setPixmap(pixmap)
        self.layout.addWidget(self.service_icon)

        self.service_desc_layout = QGridLayout(self)
        self.service_desc_layout.setSpacing(0)
        self.layout.addLayout(self.service_desc_layout)

        self.service_name = QLabel(self)
        self.service_name.setTextFormat(Qt.RichText)
        self.service_name.setWordWrap(True)
        self.service_name.setText(u"   <strong> {} </strong>".format(geoservice.get('name', u"")))
        self.service_desc_layout.addWidget(self.service_name, 0, 0, 1, 3)

        self.service_type = QLabel(self)
        self.service_type.setTextFormat(Qt.RichText)
        self.service_type.setWordWrap(True)
        self.service_type.setText(geoservice.get('type', u"").upper() + " ")
        self.service_desc_layout.addWidget(self.service_type, 1, 0)

        self.service_deteils = QLabel(self)
        self.service_deteils.setTextFormat(Qt.RichText)
        self.service_deteils.setWordWrap(True)
        self.service_deteils.setOpenExternalLinks(True)
        self.service_deteils.setText(u"<a href=\"{0}\">{1}</a>, ".format(
            Client().geoservice_info_url(geoservice.get('id', u"")),
            self.tr('details')
        ))
        self.service_desc_layout.addWidget(self.service_deteils, 1, 1)

        self.service_report = QLabel(self)
        self.service_report.setTextFormat(Qt.RichText)
        self.service_report.setWordWrap(True)
        self.service_report.setOpenExternalLinks(True)
        self.service_report.setText(u"<a href=\"{0}\">{1}</a><div/>".format(
            Client().geoservice_report_url(geoservice.get('id', u"")),
            self.tr('report a problem')
        ))
        self.service_desc_layout.addWidget(self.service_report, 1, 2)
        self.service_desc_layout.setColumnStretch(2, 1)


        self.status_label = QLabel(self)
        self.status_label.setTextFormat(Qt.RichText)
        self.status_label.setText(u'\u2022')


        status = geoservice.get('cumulative_status', u'')
        if status == 'works':
            self.status_label.setStyleSheet("color: green; font-size: 30px")
        if status == 'failed':
            self.status_label.setStyleSheet("color: red; font-size: 30px")
        if status == 'problematic':
            self.status_label.setStyleSheet("color: yellow; font-size: 30px")
        self.layout.addWidget(self.status_label)


        self.addButton = QToolButton()
        self.addButton.setText(self.tr("Add"))
        self.addButton.clicked.connect(self.addToMap)
        self.layout.addWidget(self.addButton)
        
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)

        self.geoservice = geoservice
        self.image_ba = image_ba
コード例 #14
0
class GeoGigPlugin(object):

    def __init__(self, iface):
        self.iface = iface
        config.iface = iface
        readSettings()
        config.initConfigParams()

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            trackLayer(layer)
        try:
            from qgistester.tests import addTestModule
            from geogig.tests import testplugin
            addTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        QSettings().setValue("/qgis/walForSqlite3", False)

    def unload(self):
        navigatorInstance.setVisible(False)
        try:
            QgsMapLayerRegistry.instance().layerWasAdded.disconnect(trackLayer)
            QgsMapLayerRegistry.instance().layerRemoved.disconnect(layerRemoved)
        except:
            pass

        self.menu.deleteLater()
        self.toolButton.deleteLater()

        self.iface.removePluginMenu("&GeoGig", self.explorerAction)
        self.iface.removePluginMenu("&GeoGig", self.toolAction)

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            removeLayerActions(layer)
        removeNonexistentTrackedLayers()
        removeTempFolder()

        try:
            from qgistester.tests import removeTestModule
            from geogig.tests import testplugin
            removeTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        try:
            from lessons import removeLessonsFolder
            removeLessonsFolder(folder, "geogig")
        except:
            pass

        removeHelpMenu("GeoGig")
        removeAboutMenu("GeoGig")
        removeSettingsMenu("GeoGig")

    def initGui(self):
        readTrackedLayers()

        QgsMapLayerRegistry.instance().layerWasAdded.connect(trackLayer)
        QgsMapLayerRegistry.instance().layerRemoved.connect(layerRemoved)

        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/geogig.png")
        self.explorerAction = navigatorInstance.toggleViewAction()
        self.explorerAction.setIcon(icon)
        self.explorerAction.setText("GeoGig Navigator")
        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/identify.png")
        self.toolAction = QAction(icon, "GeoGig Feature Info Tool", self.iface.mainWindow())
        self.toolAction.setCheckable(True)
        self.toolAction.triggered.connect(self.setTool)

        self.menu = QMenu(self.iface.mainWindow())
        self.menu.setTitle("GeoGig")
        self.menu.addAction(self.explorerAction)
        self.menu.addAction(self.toolAction)
        bar = self.iface.layerToolBar()
        self.toolButton = QToolButton()
        self.toolButton.setMenu(self.menu)
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButton.setDefaultAction(self.explorerAction)
        bar.addWidget(self.toolButton)
        self.iface.addPluginToMenu("&GeoGig", self.explorerAction)
        self.iface.addPluginToMenu("&GeoGig", self.toolAction)

        addSettingsMenu("GeoGig")
        addHelpMenu("GeoGig")
        addAboutMenu("GeoGig")

        self.mapTool = MapToolGeoGigInfo(self.iface.mapCanvas())

        #This crashes QGIS, so we comment it out until finding a solution
        #self.mapTool.setAction(self.toolAction)

        self.iface.addDockWidget(Qt.RightDockWidgetArea, navigatorInstance)

        try:
            from lessons import addLessonsFolder, addGroup
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            addLessonsFolder(folder, "geogig")
            group_description = os.path.join(folder, "group.md")
            addGroup("GeoGig lessons", group_description)
        except Exception as e:
            pass

    def setWarning(self, msg):
        QMessageBox.warning(None, 'Could not complete GeoGig command',
                                  msg,
                                  QMessageBox.Ok)

    def setTool(self):
        self.toolAction.setChecked(True)
        self.iface.mapCanvas().setMapTool(self.mapTool)
コード例 #15
0
ファイル: mapwidget.py プロジェクト: terry-longmacch/Roam
    def __init__(self, parent=None):
        super(MapWidget, self).__init__(parent)
        self.setupUi(self)
        self.snapping = True

        icon = roam_style.iconsize()
        self.projecttoolbar.setIconSize(QSize(icon, icon))

        self.defaultextent = None
        self.current_form = None
        self.last_form = None
        self.layerbuttons = []
        self.editfeaturestack = []
        self.lastgpsposition = None
        self.project = None
        self.gps = None
        self.gpslogging = None
        self.selectionbands = defaultdict(partial(QgsRubberBand, self.canvas))

        self.bridge = QgsLayerTreeMapCanvasBridge(
            QgsProject.instance().layerTreeRoot(), self.canvas)
        self.bridge.setAutoSetupOnFirstLayer(False)

        self.canvas.setCanvasColor(Qt.white)
        self.canvas.enableAntiAliasing(True)

        self.snappingutils = SnappingUtils(self.canvas, self)
        self.canvas.setSnappingUtils(self.snappingutils)

        threadcount = QThread.idealThreadCount()
        threadcount = 2 if threadcount > 2 else 1
        QgsApplication.setMaxThreads(threadcount)
        self.canvas.setParallelRenderingEnabled(True)

        self.canvas.setFrameStyle(QFrame.NoFrame)

        self.editgroup = QActionGroup(self)
        self.editgroup.setExclusive(True)
        self.editgroup.addAction(self.actionPan)
        self.editgroup.addAction(self.actionZoom_In)
        self.editgroup.addAction(self.actionZoom_Out)
        self.editgroup.addAction(self.actionInfo)

        self.actionGPS = GPSAction(self.canvas, self)
        self.projecttoolbar.addAction(self.actionGPS)

        if roam.config.settings.get('north_arrow', False):
            self.northarrow = NorthArrow(":/icons/north", self.canvas)
            self.northarrow.setPos(10, 10)
            self.canvas.scene().addItem(self.northarrow)

        smallmode = roam.config.settings.get("smallmode", False)
        self.projecttoolbar.setSmallMode(smallmode)

        self.projecttoolbar.setContextMenuPolicy(Qt.CustomContextMenu)

        gpsspacewidget = QWidget()
        gpsspacewidget.setMinimumWidth(30)
        gpsspacewidget.setSizePolicy(QSizePolicy.Expanding,
                                     QSizePolicy.Expanding)

        self.topspaceraction = self.projecttoolbar.insertWidget(
            self.actionGPS, gpsspacewidget)

        self.dataentryselection = QAction(self.projecttoolbar)
        self.dataentryaction = self.projecttoolbar.insertAction(
            self.topspaceraction, self.dataentryselection)
        self.dataentryselection.triggered.connect(self.select_data_entry)

        self.gpsMarker = GPSMarker(self.canvas)
        self.gpsMarker.hide()

        self.currentfeatureband = CurrentSelection(self.canvas)
        self.currentfeatureband.setIconSize(30)
        self.currentfeatureband.setWidth(10)
        self.currentfeatureband.setColor(QColor(88, 64, 173, 50))
        self.currentfeatureband.setOutlineColour(QColor(88, 64, 173))

        self.gpsband = QgsRubberBand(self.canvas)
        self.gpsband.setColor(QColor(165, 111, 212, 75))
        self.gpsband.setWidth(5)

        RoamEvents.refresh_map.connect(self.refresh_map)
        RoamEvents.editgeometry.connect(self.queue_feature_for_edit)
        RoamEvents.selectioncleared.connect(self.clear_selection)
        RoamEvents.selectionchanged.connect(self.highlight_selection)
        RoamEvents.openfeatureform.connect(self.feature_form_loaded)
        RoamEvents.sync_complete.connect(self.refresh_map)
        RoamEvents.snappingChanged.connect(self.snapping_changed)

        self.snappingbutton = QToolButton()
        self.snappingbutton.setText("Snapping: On")
        self.snappingbutton.setAutoRaise(True)
        self.snappingbutton.pressed.connect(self.toggle_snapping)

        spacer = QWidget()
        spacer2 = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        self.scalewidget = QgsScaleComboBox()

        self.scalebutton = QToolButton()
        self.scalebutton.setAutoRaise(True)
        self.scalebutton.setMaximumHeight(self.statusbar.height())
        self.scalebutton.pressed.connect(self.selectscale)
        self.scalebutton.setText("Scale")

        self.scalelist = BigList(parent=self.canvas,
                                 centeronparent=True,
                                 showsave=False)
        self.scalelist.hide()
        self.scalelist.setlabel("Map Scale")
        self.scalelist.setmodel(self.scalewidget.model())
        self.scalelist.closewidget.connect(self.scalelist.close)
        self.scalelist.itemselected.connect(self.update_scale_from_item)
        self.scalelist.itemselected.connect(self.scalelist.close)

        self.positionlabel = QLabel('')
        self.gpslabel = QLabel("GPS: Not active")
        self.gpslabelposition = QLabel("")
        self.gpslabelaveraging = QLabel('')  # averaging

        self.statusbar.addWidget(self.snappingbutton)
        self.statusbar.addWidget(spacer2)
        self.statusbar.addWidget(self.gpslabel)
        self.statusbar.addWidget(self.gpslabelposition)
        self.statusbar.addWidget(self.gpslabelaveraging)  # averaging
        self.statusbar.addPermanentWidget(self.scalebutton)

        self.canvas.extentsChanged.connect(self.update_status_label)
        self.canvas.scaleChanged.connect(self.update_status_label)

        self.connectButtons()

        scalebar_enabled = roam.config.settings.get('scale_bar', False)
        self.scalebar_enabled = False
        if scalebar_enabled:
            roam.utils.warning(
                "Unsupported feature: Scale bar support not ported to QGIS 3 API yet."
            )
            RoamEvents.raisemessage(
                "Unsupported feature",
                "Scale bar support not ported to QGIS 3 API yet",
                level=RoamEvents.CRITICAL)
            self.scalebar_enabled = False
コード例 #16
0
ファイル: console.py プロジェクト: cayetanobv/QGIS
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QgsSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        # ------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        # self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        # self.splitterObj.setSizes([0, 0])
        # self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        # self.splitterEditor.addWidget(self.widgetEditor)
        # self.splitterObj.addWidget(self.listClassMethod)
        # self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        # ----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        # ------------------Toolbar Editor-------------------------------------

        # Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open Script...")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.png"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in External Editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        # Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.png"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        # Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.png"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        # Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCut.svg"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        # Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCopy.svg"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        # Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditPaste.svg"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        # Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.png"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        # Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.png"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        # Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.png"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        # Action for Object browser
        objList = QCoreApplication.translate("PythonConsole", "Object Inspector...")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp",
                                                             False, type=bool))
        self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        # Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        # ----------------Toolbar Console-------------------------------------

        # Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show Editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        # Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear Console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.png"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        # Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Options...")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.png"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        # Action menu for class
        actionClassBt = QCoreApplication.translate("PythonConsole", "Import Class")
        self.actionClass = QAction(self)
        self.actionClass.setCheckable(False)
        self.actionClass.setEnabled(True)
        self.actionClass.setIcon(QgsApplication.getThemeIcon("console/iconClassConsole.png"))
        self.actionClass.setMenuRole(QAction.PreferencesRole)
        self.actionClass.setIconVisibleInMenu(True)
        self.actionClass.setToolTip(actionClassBt)
        self.actionClass.setText(actionClassBt)
        # Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run Command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(QgsApplication.getThemeIcon("console/iconRunConsole.png"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        # Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help...")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.png"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(QSize(16, 16))
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.actionClass)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(QSize(16, 16))
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        # Menu Import Class
        default_command = {
            (QCoreApplication.translate("PythonConsole", "Import Processing Class"),
             QgsApplication.getThemeIcon("console/iconProcessingConsole.png")):
            ["import processing"],
            (QCoreApplication.translate("PythonConsole", "Import PyQt.QtCore Class"),
             QgsApplication.getThemeIcon("console/iconQtCoreConsole.png")):
            ["from qgis.PyQt.QtCore import *"],
            (QCoreApplication.translate("PythonConsole", "Import PyQt.QtGui Class"),
             QgsApplication.getThemeIcon("console/iconQtGuiConsole.png")):
            ["from qgis.PyQt.QtGui import *", "from qgis.PyQt.QtWidgets import *"]
        }

        self.classMenu = QMenu()
        for (title, icon), commands in list(default_command.items()):
            action = self.classMenu.addAction(icon, title)
            action.triggered.connect(partial(self.shell.commandConsole, commands))

        cM = self.toolBar.widgetForAction(self.actionClass)
        cM.setMenu(self.classMenu)
        cM.setPopupMode(QToolButton.InstantPopup)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        # ------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        #  Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...")

        self.lineEditFind.setPlaceholderText(placeHolderTxt)
        self.findNextButton = QToolButton()
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.png"))
        self.findNextButton.setIconSize(QSize(24, 24))
        self.findNextButton.setAutoRaise(True)
        self.findPrevButton = QToolButton()
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.png"))
        self.findPrevButton.setIconSize(QSize(24, 24))
        self.findPrevButton.setAutoRaise(True)
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)
        self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1)
        self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1)
        self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1)
        self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1)
        self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1)
        self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1)

        # ------------ Add first Tab in Editor -------------------------------

        # self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        # ------------ Signal -------------------------------

        self.findTextButton.triggered.connect(self._toggleFind)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.listClassMethod.itemClicked.connect(self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findNext)
        self.findNextButton.clicked.connect(self._findNext)
        self.findPrevButton.clicked.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

        self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._openFind)

        self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor)
        self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findNextScut.activated.connect(self._findNext)

        self.findPreviousScut = QShortcut(QKeySequence.FindPrevious, self.widgetEditor)
        self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findPreviousScut.activated.connect(self._findPrev)

        # Escape on editor hides the find bar
        self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._closeFind)
コード例 #17
0
ファイル: wrappers.py プロジェクト: stephenson1811/QGIS
    def createWidget(self):
        if self.dialogType == DIALOG_STANDARD:
            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            self.combo = QgsMapLayerComboBox()
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)

            widget.setLayout(layout)
            if self.param.optional:
                self.combo.setAllowEmptyLayer(True)
            if ProcessingConfig.getSetting(ProcessingConfig.SHOW_CRS_DEF):
                self.combo.setShowCrs(True)

            self.combo.setFilters(QgsMapLayerProxyModel.RasterLayer)
            self.combo.setExcludedProviders(['grass'])

            self.combo.currentIndexChanged.connect(
                lambda: self.widgetValueHasChanged.emit(self))
            self.combo.currentTextChanged.connect(
                lambda: self.widgetValueHasChanged.emit(self))
            return widget
        elif self.dialogType == DIALOG_BATCH:
            return BatchInputSelectionPanel(self.param, self.row, self.col,
                                            self.dialog)
        else:
            self.combo = QComboBox()
            layers = self.dialog.getAvailableValuesOfType(
                ParameterRaster, OutputRaster)
            self.combo.setEditable(True)
            for layer in layers:
                self.combo.addItem(self.dialog.resolveValueDescription(layer),
                                   layer)
            if self.param.optional:
                self.combo.setEditText("")

            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)
            widget.setLayout(layout)
            return widget
コード例 #18
0
ファイル: AlgorithmDialogBase.py プロジェクト: nirvn/QGIS
    def __init__(self, alg):
        super(AlgorithmDialogBase, self).__init__(iface.mainWindow() if iface else None)
        self.setupUi(self)

        # don't collapse parameters panel
        self.splitter.setCollapsible(0, False)

        # add collapse button to splitter
        splitterHandle = self.splitter.handle(1)
        handleLayout = QVBoxLayout()
        handleLayout.setContentsMargins(0, 0, 0, 0)
        self.btnCollapse = QToolButton(splitterHandle)
        self.btnCollapse.setAutoRaise(True)
        self.btnCollapse.setFixedSize(12, 12)
        self.btnCollapse.setCursor(Qt.ArrowCursor)
        handleLayout.addWidget(self.btnCollapse)
        handleLayout.addStretch()
        splitterHandle.setLayout(handleLayout)

        self.settings = QgsSettings()
        self.splitter.restoreState(self.settings.value("/Processing/dialogBaseSplitter", QByteArray()))
        self.restoreGeometry(self.settings.value("/Processing/dialogBase", QByteArray()))
        self.splitterState = self.splitter.saveState()
        self.splitterChanged(0, 0)

        self.executed = False
        self.mainWidget = None
        self.alg = alg

        self.setWindowTitle(self.alg.displayName())

        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)

        # Rename OK button to Run
        self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok)
        self.btnRun.setText(self.tr('Run'))

        self.buttonCancel.setEnabled(False)

        self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)

        self.buttonBox.helpRequested.connect(self.openHelp)

        self.btnCollapse.clicked.connect(self.toggleCollapsed)
        self.splitter.splitterMoved.connect(self.splitterChanged)

        # desktop = QDesktopWidget()
        # if desktop.physicalDpiX() > 96:
        # self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96)

        algHelp = self.formatHelp(self.alg)
        if algHelp is None:
            self.textShortHelp.hide()
        else:
            self.textShortHelp.document().setDefaultStyleSheet('''.summary { margin-left: 10px; margin-right: 10px; }
                                                    h2 { color: #555555; padding-bottom: 15px; }
                                                    a { text-decoration: none; color: #3498db; font-weight: bold; }
                                                    p { color: #666666; }
                                                    b { color: #333333; }
                                                    dl dd { margin-bottom: 5px; }''')
            self.textShortHelp.setHtml(algHelp)

        def linkClicked(url):
            webbrowser.open(url.toString())

        self.textShortHelp.anchorClicked.connect(linkClicked)

        self.showDebug = ProcessingConfig.getSetting(
            ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
コード例 #19
0
    def append_menu_buttons(self):
        """
        Append menus and buttons to appropriate toolbar
        :return:
        """
        # add to QGIS menu
        if PluginSettings.move_to_layers_menu():
            self.iface.addLayerMenu().addMenu(self.menu)
        else:
            # need workaround for WebMenu
            _temp_act = QAction('temp', self.iface.mainWindow())
            self.iface.addPluginToWebMenu("_tmp", _temp_act)
            self.iface.webMenu().addMenu(self.menu)
            self.iface.removePluginWebMenu("_tmp", _temp_act)

        # add to QGIS toolbar
        toolbutton = QToolButton()
        toolbutton.setPopupMode(QToolButton.InstantPopup)
        toolbutton.setMenu(self.menu)
        toolbutton.setIcon(self.menu.icon())
        toolbutton.setText(self.menu.title())
        toolbutton.setToolTip(self.menu.title())
        # self.tb_action = toolbutton.defaultAction()
        # print "self.tb_action: ", self.tb_action
        if PluginSettings.move_to_layers_menu():
            self.tb_action = self.iface.layerToolBar().addWidget(toolbutton)
            self.iface.layerToolBar().addAction(self.qms_search_action)
        else:
            self.tb_action = self.iface.webToolBar().addWidget(toolbutton)
            self.iface.webToolBar().addAction(self.qms_search_action)
コード例 #20
0
ファイル: relation_line_edit.py プロジェクト: ollawone/stdm
class ForeignKeyLineEdit(QLineEdit):
    """
    Line edit that enables the browsing of related entities defined through
    foreign key constraint.
    """

    def __init__(self, column, parent=None, pixmap=None, host=None):
        """
        Class constructor.
        :param column: Column object containing foreign key information.
        :type column: BaseColumn
        :param parent: Parent widget for the control.
        :type parent: QWidget
        :param pixmap: Pixmap to use for the line edit button.
        :type pixmap: QPixmap
        """

        QLineEdit.__init__(self, parent)

        self.column = column
        self._entity = self.column.entity
        self.entity_dialog = host

        # Configure load button
        self.btn_load = QToolButton(parent)
        self.btn_load.setCursor(Qt.PointingHandCursor)
        self.btn_load.setFocusPolicy(Qt.NoFocus)
        px = GuiUtils.get_icon_pixmap('select_record.png')
        if not pixmap is None:
            px = pixmap
        self.btn_load.setIcon(QIcon(px))
        self.btn_load.setIconSize(px.size())
        self.btn_load.setStyleSheet('background: transparent; padding: 0px; '
                                    'border: none;')
        self.btn_load.clicked.connect(self.on_load_foreign_key_browser)

        clear_px = GuiUtils.get_icon_pixmap('clear.png')

        self.btn_clear = QToolButton(parent)
        self.btn_clear.setCursor(Qt.PointingHandCursor)
        self.btn_clear.setFocusPolicy(Qt.NoFocus)
        self.btn_clear.setIcon(QIcon(clear_px))
        self.btn_clear.setIconSize(clear_px.size())
        self.btn_clear.setStyleSheet('background: transparent; padding: 0px; '
                                     'border: none;')

        self.btn_clear.clicked.connect(self.clear_line_edit)

        frame_width = self.set_button_minimum_size(self.btn_load)
        self.set_button_minimum_size(self.btn_clear)
        # Ensure that text does not overlay button
        padding = self.btn_load.sizeHint().width() + frame_width + 1

        self.setStyleSheet('padding-right: ' + str(padding * 2) + 'px;')

        # Set layout
        self.button_layout = QHBoxLayout(self)

        self.button_layout.addWidget(self.btn_clear, 0, Qt.AlignRight)
        self.button_layout.addWidget(self.btn_load, 0, Qt.AlignRight)

        self.button_layout.setSpacing(0)
        self.button_layout.setMargin(5)

        self.btn_clear.setVisible(False)
        # Readonly as text is loaded from the related entity
        self.setReadOnly(True)

        # Current model object
        self._current_item = None

    def set_button_minimum_size(self, button):
        """
        Sets the minimum button size.
        :param button: The button to be set.
        :type button: QToolButton
        :return: Returns the frame width of the button
        :rtype: Integer
        """
        frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        msz = self.minimumSizeHint()
        self.setMinimumSize(
            max(
                msz.width(),
                button.sizeHint().height() + frame_width * 2 + 2
            ), max(
                msz.height(),
                button.sizeHint().height() + frame_width * 2 + 2
            )
        )
        return frame_width

    @property
    def current_item(self):
        return self._current_item

    @current_item.setter
    def current_item(self, value):
        # Update display every time the current item is changed.
        self._current_item = value
        self.format_display()

    @property
    def entity(self):
        """
        :return: Returns the entity object corresponding to this widget.
        :rtype: Entity
        """
        return self._entity

    def clear_line_edit(self):
        """
        Clears the text in the line edit.
        """
        self.clear()
        self.hide_clear_button()

    def hide_clear_button(self):
        """
        Hides the clear button.
        """
        self.btn_clear.setVisible(False)
        self.button_layout.setStretch(0, 0)

    def show_clear_button(self):
        """
        Shows the clear button if a text exists.
        """
        if len(self.text()) > 0:
            self.btn_clear.setVisible(True)
            self.button_layout.setStretch(0, 5)

    def on_load_foreign_key_browser(self):
        """
        Slot raised to load browser for selecting foreign key entities. To be
        implemented by subclasses.
        """
        raise NotImplementedError

    def format_display(self):
        """
        Extract object values to show in the line edit based on the specified
        display columns.
        """
        raise NotImplementedError

    def parent_entity_model(self):
        """
        :return: Returns the database model corresponding to the parent table
        of the relation defined by this column. Please note that the database
        model will not contain relationship configurations in its attributes.
        :rtype: object
        """
        entity = self.column.entity_relation.parent

        return entity_model(entity, entity_only=True)

    def load_current_item_from_id(self, id):
        """
        Loads the current item from the id corresponding to the primary
        key.
        :param id: Primary key of the referenced entity.
        :type id: int
        """
        QApplication.processEvents()
        model = self.parent_entity_model()

        if model is None:
            return

        model_obj = model()
        res = model_obj.queryObject().filter(model.id == id).first()

        if not res is None:
            self.current_item = res
コード例 #21
0
    def initWidgets(self):
        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                self.grpAdvanced.show()
                break
        # Create widgets and put them in layouts
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            if param.isDestination():
                continue
            else:
                desc = param.description()
                if isinstance(param, QgsProcessingParameterExtent):
                    desc += self.tr(' (xmin, xmax, ymin, ymax)')
                if isinstance(param, QgsProcessingParameterPoint):
                    desc += self.tr(' (x, y)')
                if param.flags(
                ) & QgsProcessingParameterDefinition.FlagOptional:
                    desc += self.tr(' [optional]')

                wrapper = WidgetWrapperFactory.create_wrapper(
                    param, self.parent)
                self.wrappers[param.name()] = wrapper
                widget = wrapper.widget

                if widget is not None:
                    if isinstance(param, QgsProcessingParameterFeatureSource):
                        layout = QHBoxLayout()
                        layout.setSpacing(6)
                        layout.setMargin(0)
                        layout.addWidget(widget)
                        button = QToolButton()
                        icon = QIcon(
                            os.path.join(pluginPath, 'images', 'iterate.png'))
                        button.setIcon(icon)
                        button.setSizePolicy(QSizePolicy.Fixed,
                                             QSizePolicy.Expanding)
                        button.setToolTip(
                            self.
                            tr('Iterate over this layer, creating a separate output for every feature in the layer'
                               ))
                        button.setCheckable(True)
                        layout.addWidget(button)
                        layout.setAlignment(button, Qt.AlignTop)
                        self.iterateButtons[param.name()] = button
                        button.toggled.connect(self.buttonToggled)
                        widget = QWidget()
                        widget.setLayout(layout)

                    widget.setToolTip(param.toolTip())

                    if isinstance(widget, QCheckBox):
                        # checkbox widget - so description is embedded in widget rather than a separate
                        # label
                        widget.setText(desc)
                    else:
                        label = QLabel(desc)
                        # label.setToolTip(tooltip)
                        self.labels[param.name()] = label

                        if param.flags(
                        ) & QgsProcessingParameterDefinition.FlagAdvanced:
                            self.layoutAdvanced.addWidget(label)
                        else:
                            self.layoutMain.insertWidget(
                                self.layoutMain.count() - 2, label)

                    if param.flags(
                    ) & QgsProcessingParameterDefinition.FlagAdvanced:
                        self.layoutAdvanced.addWidget(widget)
                    else:
                        self.layoutMain.insertWidget(
                            self.layoutMain.count() - 2, widget)

        for output in self.alg.destinationParameterDefinitions():
            if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            label = QLabel(output.description())
            widget = DestinationSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (QgsProcessingParameterRasterDestination,
                                   QgsProcessingParameterFeatureSink,
                                   QgsProcessingParameterVectorDestination)):
                check = QCheckBox()
                check.setText(
                    self.tr('Open output file after running algorithm'))
                check.setChecked(True)
                self.layoutMain.insertWidget(self.layoutMain.count() - 1,
                                             check)
                self.checkBoxes[output.name()] = check

            widget.setToolTip(param.toolTip())
            self.outputWidgets[output.name()] = widget

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
コード例 #22
0
ファイル: console.py プロジェクト: zhanggaolei001/QGIS
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(
            QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QgsSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        # ------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        # self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        # self.splitterObj.setSizes([0, 0])
        # self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole",
                                                  "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        # self.splitterEditor.addWidget(self.widgetEditor)
        # self.splitterObj.addWidget(self.listClassMethod)
        # self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        icon_size = iface.iconSize(
            dockedToolbar=True) if iface else QSize(16, 16)

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        # ----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        # ------------------Toolbar Editor-------------------------------------

        # Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole",
                                                "Open Script…")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionScriptOpen.svg"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate(
            "PythonConsole", "Open in External Editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        # Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionFileSave.svg"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        # Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As…")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionFileSaveAs.svg"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        # Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditCut.svg"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        # Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditCopy.svg"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        # Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditPaste.svg"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        # Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Run Script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionStart.svg"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        # Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole",
                                                     "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconCommentEditorConsole.svg"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        # Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconUncommentEditorConsole.svg"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        # Action for Object browser
        objList = QCoreApplication.translate("PythonConsole",
                                             "Object Inspector…")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(
            self.settings.value("pythonConsole/enableObjectInsp",
                                False,
                                type=bool))
        self.objectListButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClassBrowserConsole.svg"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        # Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSearchEditorConsole.svg"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        # ----------------Toolbar Console-------------------------------------

        # Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show Editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        # Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear Console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClearConsole.svg"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        # Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Options…")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSettingsConsole.svg"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        # Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run Command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(
            QgsApplication.getThemeIcon("console/mIconRunConsole.svg"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)

        # Help button
        self.helpConsoleAction = QAction(self)
        self.helpConsoleAction.setEnabled(True)
        self.helpConsoleAction.setText(
            QCoreApplication.translate("PythonConsole", "Python Console Help"))
        self.helpAPIAction = QAction(self)
        self.helpAPIAction.setEnabled(True)
        self.helpAPIAction.setText(
            QCoreApplication.translate("PythonConsole",
                                       "PyQGIS API Documentation"))
        self.helpCookbookAction = QAction(self)
        self.helpCookbookAction.setEnabled(True)
        self.helpCookbookAction.setText(
            QCoreApplication.translate("PythonConsole", "PyQGIS Cookbook"))

        self.helpMenu = QMenu(self)
        self.helpMenu.addAction(self.helpConsoleAction)
        self.helpMenu.addAction(self.helpAPIAction)
        self.helpMenu.addAction(self.helpCookbookAction)

        helpBt = QCoreApplication.translate("PythonConsole", "Help…")
        self.helpButton = QToolButton(self)
        self.helpButton.setPopupMode(QToolButton.InstantPopup)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(
            QgsApplication.getThemeIcon("console/iconHelpConsole.svg"))
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setMenu(self.helpMenu)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(icon_size)
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addWidget(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(icon_size)
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        # ------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        #  Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole",
                                                    "Enter text to find…")

        self.lineEditFind.setPlaceholderText(placeHolderTxt)
        self.toolBarFindText = QToolBar()
        self.toolBarFindText.setIconSize(icon_size)
        self.findNextButton = QAction(self)
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole",
                                                     "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchNextEditorConsole.svg"))
        self.findPrevButton = QAction(self)
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole",
                                                     "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchPrevEditorConsole.svg"))
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole",
                                                "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole",
                                                  "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)

        self.toolBarFindText.addWidget(self.lineEditFind)
        self.toolBarFindText.addAction(self.findPrevButton)
        self.toolBarFindText.addAction(self.findNextButton)
        self.toolBarFindText.addWidget(self.caseSensitive)
        self.toolBarFindText.addWidget(self.wholeWord)
        self.toolBarFindText.addWidget(self.wrapAround)

        self.layoutFind.addWidget(self.toolBarFindText, 0, 1, 1, 1)

        # ------------ Add first Tab in Editor -------------------------------

        # self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        # ------------ Signal -------------------------------

        self.findTextButton.triggered.connect(self._toggleFind)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpConsoleAction.triggered.connect(self.openHelpConsole)
        self.helpAPIAction.triggered.connect(self.openHelpAPI)
        self.helpCookbookAction.triggered.connect(self.openHelpCookbook)
        self.listClassMethod.itemClicked.connect(self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findNext)
        self.findNextButton.triggered.connect(self._findNext)
        self.findPrevButton.triggered.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

        self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._openFind)

        self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor)
        self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findNextScut.activated.connect(self._findNext)

        self.findPreviousScut = QShortcut(QKeySequence.FindPrevious,
                                          self.widgetEditor)
        self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findPreviousScut.activated.connect(self._findPrev)

        # Escape on editor hides the find bar
        self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._closeFind)
コード例 #23
0
ファイル: console.py プロジェクト: zhanggaolei001/QGIS
class PythonConsoleWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(
            QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QgsSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        # ------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        # self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        # self.splitterObj.setSizes([0, 0])
        # self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole",
                                                  "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        # self.splitterEditor.addWidget(self.widgetEditor)
        # self.splitterObj.addWidget(self.listClassMethod)
        # self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        icon_size = iface.iconSize(
            dockedToolbar=True) if iface else QSize(16, 16)

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        # ----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        # ------------------Toolbar Editor-------------------------------------

        # Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole",
                                                "Open Script…")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionScriptOpen.svg"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate(
            "PythonConsole", "Open in External Editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        # Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionFileSave.svg"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        # Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As…")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionFileSaveAs.svg"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        # Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditCut.svg"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        # Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditCopy.svg"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        # Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditPaste.svg"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        # Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Run Script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionStart.svg"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        # Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole",
                                                     "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconCommentEditorConsole.svg"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        # Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconUncommentEditorConsole.svg"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        # Action for Object browser
        objList = QCoreApplication.translate("PythonConsole",
                                             "Object Inspector…")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(
            self.settings.value("pythonConsole/enableObjectInsp",
                                False,
                                type=bool))
        self.objectListButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClassBrowserConsole.svg"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        # Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSearchEditorConsole.svg"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        # ----------------Toolbar Console-------------------------------------

        # Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show Editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        # Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear Console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClearConsole.svg"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        # Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Options…")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSettingsConsole.svg"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        # Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run Command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(
            QgsApplication.getThemeIcon("console/mIconRunConsole.svg"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)

        # Help button
        self.helpConsoleAction = QAction(self)
        self.helpConsoleAction.setEnabled(True)
        self.helpConsoleAction.setText(
            QCoreApplication.translate("PythonConsole", "Python Console Help"))
        self.helpAPIAction = QAction(self)
        self.helpAPIAction.setEnabled(True)
        self.helpAPIAction.setText(
            QCoreApplication.translate("PythonConsole",
                                       "PyQGIS API Documentation"))
        self.helpCookbookAction = QAction(self)
        self.helpCookbookAction.setEnabled(True)
        self.helpCookbookAction.setText(
            QCoreApplication.translate("PythonConsole", "PyQGIS Cookbook"))

        self.helpMenu = QMenu(self)
        self.helpMenu.addAction(self.helpConsoleAction)
        self.helpMenu.addAction(self.helpAPIAction)
        self.helpMenu.addAction(self.helpCookbookAction)

        helpBt = QCoreApplication.translate("PythonConsole", "Help…")
        self.helpButton = QToolButton(self)
        self.helpButton.setPopupMode(QToolButton.InstantPopup)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(
            QgsApplication.getThemeIcon("console/iconHelpConsole.svg"))
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setMenu(self.helpMenu)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(icon_size)
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addWidget(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(icon_size)
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        # ------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        #  Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole",
                                                    "Enter text to find…")

        self.lineEditFind.setPlaceholderText(placeHolderTxt)
        self.toolBarFindText = QToolBar()
        self.toolBarFindText.setIconSize(icon_size)
        self.findNextButton = QAction(self)
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole",
                                                     "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchNextEditorConsole.svg"))
        self.findPrevButton = QAction(self)
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole",
                                                     "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchPrevEditorConsole.svg"))
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole",
                                                "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole",
                                                  "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)

        self.toolBarFindText.addWidget(self.lineEditFind)
        self.toolBarFindText.addAction(self.findPrevButton)
        self.toolBarFindText.addAction(self.findNextButton)
        self.toolBarFindText.addWidget(self.caseSensitive)
        self.toolBarFindText.addWidget(self.wholeWord)
        self.toolBarFindText.addWidget(self.wrapAround)

        self.layoutFind.addWidget(self.toolBarFindText, 0, 1, 1, 1)

        # ------------ Add first Tab in Editor -------------------------------

        # self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        # ------------ Signal -------------------------------

        self.findTextButton.triggered.connect(self._toggleFind)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpConsoleAction.triggered.connect(self.openHelpConsole)
        self.helpAPIAction.triggered.connect(self.openHelpAPI)
        self.helpCookbookAction.triggered.connect(self.openHelpCookbook)
        self.listClassMethod.itemClicked.connect(self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findNext)
        self.findNextButton.triggered.connect(self._findNext)
        self.findPrevButton.triggered.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

        self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._openFind)

        self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor)
        self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findNextScut.activated.connect(self._findNext)

        self.findPreviousScut = QShortcut(QKeySequence.FindPrevious,
                                          self.widgetEditor)
        self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findPreviousScut.activated.connect(self._findPrev)

        # Escape on editor hides the find bar
        self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._closeFind)

    def _toggleFind(self):
        self.tabEditorWidget.currentWidget().newEditor.toggleFindWidget()

    def _openFind(self):
        self.tabEditorWidget.currentWidget().newEditor.openFindWidget()

    def _closeFind(self):
        self.tabEditorWidget.currentWidget().newEditor.closeFindWidget()

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
            self.tabEditorWidget.currentWidget().newEditor.findText(
                True, showMessage=False, findFirst=True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(str.encode(objName), linenr)

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFileExtEditor(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        path = tabWidget.path
        import subprocess
        try:
            subprocess.Popen([os.environ['EDITOR'], path])
        except KeyError:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath",
                                          QDir.homePath())
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList, selected_filter = QFileDialog.getOpenFileNames(
            self, openFileTr, lastDirPath, "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError) as error:
            msgText = QCoreApplication.translate(
                'PythonConsole',
                'The file <b>{0}</b> could not be saved. Error: {1}').format(
                    tabWidget.path, error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)

    def saveAsScriptFile(self, index=None):
        tabWidget = self.tabEditorWidget.currentWidget()
        if not index:
            index = self.tabEditorWidget.currentIndex()
        if not tabWidget.path:
            fileName = self.tabEditorWidget.tabText(index) + '.py'
            folder = self.settings.value("pythonConsole/lastDirPath",
                                         QDir.homePath())
            pathFileName = os.path.join(folder, fileName)
            fileNone = True
        else:
            pathFileName = tabWidget.path
            fileNone = False
        saveAsFileTr = QCoreApplication.translate("PythonConsole",
                                                  "Save File As")
        filename, filter = QFileDialog.getSaveFileName(self, saveAsFileTr,
                                                       pathFileName,
                                                       "Script file (*.py)")
        if filename:
            try:
                tabWidget.save(filename)
            except (IOError, OSError) as error:
                msgText = QCoreApplication.translate(
                    'PythonConsole',
                    'The file <b>{0}</b> could not be saved. Error: {1}'
                ).format(tabWidget.path, error.strerror)
                self.callWidgetMessageBarEditor(msgText, 2, False)
                if fileNone:
                    tabWidget.path = None
                else:
                    tabWidget.path = pathFileName
                return

            if not fileNone:
                self.updateTabListScript(pathFileName, action='remove')

    def openHelpConsole(self):
        QgsHelp.openHelp("plugins/python_console.html")

    def openHelpAPI(self):
        m = re.search(r'^([0-9]+)\.([0-9]+)\.', Qgis.QGIS_VERSION)
        if m:
            QDesktopServices.openUrl(
                QUrl('https://qgis.org/pyqgis/{}.{}/'.format(
                    m.group(1), m.group(2))))

    def openHelpCookbook(self):
        m = re.search(r'^([0-9]+)\.([0-9]+)\.', Qgis.QGIS_VERSION)
        if m:
            QDesktopServices.openUrl(
                QUrl(
                    'https://docs.qgis.org/{}.{}/en/docs/pyqgis_developer_cookbook/index.html'
                    .format(m.group(1), m.group(2))))

    def openSettings(self):
        if optionsDialog(self).exec_():
            self.shell.refreshSettingsShell()
            self.shellOut.refreshSettingsOutput()
            self.tabEditorWidget.refreshSettingsEditor()

    def callWidgetMessageBar(self, text):
        self.shellOut.widgetMessageBar(iface, text)

    def callWidgetMessageBarEditor(self, text, level, timed):
        self.tabEditorWidget.widgetMessageBar(iface, text, level, timed)

    def updateTabListScript(self, script, action=None):
        if action == 'remove':
            self.tabListScript.remove(script)
        elif action == 'append':
            if not self.tabListScript:
                self.tabListScript = []
            if script not in self.tabListScript:
                self.tabListScript.append(script)
        else:
            self.tabListScript = []
        self.settings.setValue("pythonConsole/tabScripts", self.tabListScript)

    def saveSettingsConsole(self):
        self.settings.setValue("pythonConsole/splitterConsole",
                               self.splitter.saveState())
        self.settings.setValue("pythonConsole/splitterObj",
                               self.splitterObj.saveState())
        self.settings.setValue("pythonConsole/splitterEditor",
                               self.splitterEditor.saveState())

        self.shell.writeHistoryFile(True)

    def restoreSettingsConsole(self):
        storedTabScripts = self.settings.value("pythonConsole/tabScripts", [])
        self.tabListScript = storedTabScripts
        self.splitter.restoreState(
            self.settings.value("pythonConsole/splitterConsole", QByteArray()))
        self.splitterEditor.restoreState(
            self.settings.value("pythonConsole/splitterEditor", QByteArray()))
        self.splitterObj.restoreState(
            self.settings.value("pythonConsole/splitterObj", QByteArray()))
コード例 #24
0
class WaysCalc:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'WaysCalc_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&WaysCalc')
        # TODO: We are going to let the user set this up in a future iteration
        # self.toolbar = self.iface.addToolBar(u'WaysCalc')
        # self.toolbar.setObjectName(u'WaysCalc')

        #print "** INITIALIZING WaysCalc"

        self.pluginIsActive = False
        self.dockwidget_inters_ways = None
        self.dockwidget_inters_allways = None
        # self.settings = None

        self.IW = None #IntersectionWays
        self.IAW = None #IntersectionAllWays


    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('WaysCalc', message)


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        # выпадающая кнопка для пересекающихся маршрутов
        self.toolButton = QToolButton()
        self.toolButton.setMenu(QMenu())
        # setPopupMode: DelayedPopup, MenuButtonPopup, InstantPopup
        self.toolButton.setPopupMode(QToolButton.InstantPopup)
        self.toolButton.setAutoRaise(True)
        self.toolButton_action = self.iface.addToolBarWidget(self.toolButton)

        self.action_intersection = QAction(
                QIcon(":/plugins/_Ways_calc/icon.png"),
                u'Поиск пересечений для линейного объекта',
                self.iface.mainWindow())
        self.action_initLayerWays = QAction(
                u"Выбор слоя для поиска пересечений",
                self.iface.mainWindow())
        self.action_allintersection = QAction(
                QIcon(":/plugins/_Ways_calc/icon.png"),
                u'Поиск пересечений всех линейных объектов',
                self.iface.mainWindow())

        self.iface.addPluginToMenu(u"WaysCalc", self.action_intersection)
        self.iface.addPluginToMenu(u"WaysCalc", self.action_initLayerWays)
        self.iface.addPluginToMenu(u"WaysCalc", self.action_allintersection)
        # self.iface.addToolBarIcon(self.action_intersection)
        m = self.toolButton.menu()
        m.addAction(self.action_intersection)
        m.addAction(self.action_initLayerWays)
        m.addSeparator()
        m.addAction(self.action_allintersection)
        self.toolButton.setDefaultAction(self.action_intersection)

        self.action_intersection.triggered.connect(self.run_intersection) # пересекающиеся маршруты
        self.action_allintersection.triggered.connect(self.run_allintersection) # пересекающиеся все маршруты
        self.action_initLayerWays.triggered.connect(self.run_initLayerWays) # выбор слоя сравнения

        self.pointEmitterIntersection = QgsMapToolEmitPoint(self.iface.mapCanvas())
        self.pointEmitterIntersection.setAction(self.action_intersection)
        self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked)
        self.iface.mapCanvas().currentLayerChanged.connect(self.onCurrentLayerChanged)

    #--------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        # disconnects
        try:
            self.dockwidget_inters_ways.closingPlugin.disconnect(self.onClosePlugin)
        except:
            pass
        try:
            self.dockwidget_inters_allways.closingPlugin.disconnect(self.onClosePlugin)
        except:
            pass
        self.pluginIsActive = False


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        self.iface.removePluginMenu(u"WaysCalc", self.action_intersection)
        self.iface.removePluginMenu(u"WaysCalc", self.action_allintersection)
        self.iface.removePluginMenu(u"WaysCalc", self.action_initLayerWays)
        self.iface.removeToolBarIcon(self.action_intersection)
        self.iface.removeToolBarIcon(self.action_intersection)
        self.iface.removeToolBarIcon(self.toolButton_action)

        self.action_intersection.triggered.disconnect(self.run_intersection) # пересекающиеся маршруты
        self.action_allintersection.triggered.disconnect(self.run_allintersection) # пересекающиеся все маршруты
        self.action_initLayerWays.triggered.disconnect(self.run_initLayerWays) # выбор слоя сравнения
        self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked)
        self.iface.mapCanvas().currentLayerChanged.disconnect(self.onCurrentLayerChanged)

        if self.IW is not None:
            self.IW.onUnLoadModule()


    def init_dock_inters_ways(self, dock):
        """Run method that loads and starts the plugin"""

        # if not self.pluginIsActive:
        self.pluginIsActive = True
        if self.dockwidget_inters_ways == None:
            self.dockwidget_inters_ways = WaysCalcDockWidget()
            self.dockwidget_inters_ways.closingPlugin.connect(self.onClosePlugin)

            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_ways)
            self.dockwidget_inters_ways.hide()
            self.dockwidget_inters_ways.setWindowTitle(u'WaysCalc: Поиск пересечений для линейного объекта')


    def init_dock_inters_allways(self, dock):
        """Run method that loads and starts the plugin"""

        # if not self.pluginIsActive:
        self.pluginIsActive = True
        if self.dockwidget_inters_allways == None:
            self.dockwidget_inters_allways = WaysCalcDockWidget()
            self.dockwidget_inters_allways.closingPlugin.connect(self.onClosePlugin)

            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_allways)
            self.dockwidget_inters_allways.hide()
            self.dockwidget_inters_allways.setWindowTitle(u'WaysCalc: Поиск пересечений всех линейных объектов')



    def onCurrentLayerChanged(self):
        self.iface.mapCanvas().unsetMapTool(self.pointEmitterIntersection)


    #--------------------------------------------------------------------------

    # def loadSettings(self):
    #     with open(os.path.join(self.plugin_dir, "settings.json"), "r") as read_file:
    #         self.settings = json.load(read_file)


    #--------INTERSECTION WAYS-------------------------------------------------
    def run_initLayerWays(self):
        if self.IW is None:
            self.init_IW()
        self.IW.initLayerWays()     

    def run_intersection(self):
        self.toolButton.setDefaultAction(self.action_intersection)
        self.init_dock_inters_ways(self.dockwidget_inters_ways)
        if self.IW is None:
            self.init_IW()
        if self.IW.checkLayers():    
            self.iface.mapCanvas().setMapTool(self.pointEmitterIntersection)


    def pointEmitterIntersectioncanvasClicked(self, point, button):
        self.IW.insersection_take_way(point)


    def init_IW(self):
        self.IW = IntersectionWays(self.iface, self.dockwidget_inters_ways)

    #-------- END INTERSECTION WAYS---------------------------------------------


    def init_IAW(self):
        self.IAW = IntersectionAllWays(self.iface, self.dockwidget_inters_allways)

    def run_allintersection(self):
        self.init_dock_inters_allways(self.dockwidget_inters_allways)
        if self.IAW is None:
            self.init_IAW()
        self.IAW.showClickedFeaturesList()
コード例 #25
0
    def initGui(self):
        self.azDigitizerTool = AzDigitizerTool(self.iface)
        self.lineDigitizerTool = LineDigitizerTool(self.iface)

        # Initialize the create shape menu items
        menu = QMenu()
        # Initialize Create Arc Wedge tool
        icon = QIcon(self.plugin_dir + '/images/arc.png')
        self.createArcAction = menu.addAction(icon, tr('Create arc wedge'),
                                              self.createArc)
        self.createArcAction.setObjectName('stCreateArcWedge')
        icon = QIcon(self.plugin_dir + '/images/donut.png')
        self.createDonutAction = menu.addAction(icon, tr('Create donut'),
                                                self.createDonut)
        self.createDonutAction.setObjectName('stCreateDonut')
        icon = QIcon(self.plugin_dir + '/images/ellipse.png')
        self.createEllipseAction = menu.addAction(icon, tr('Create ellipse'),
                                                  self.createEllipse)
        self.createEllipseAction.setObjectName('stCreateEllipse')
        icon = QIcon(self.plugin_dir + '/images/rose.png')
        self.createEllipseRoseAction = menu.addAction(
            icon, tr('Create ellipse rose'), self.createEllipseRose)
        self.createEllipseRoseAction.setObjectName('stCreateEllipseRose')
        icon = QIcon(self.plugin_dir + '/images/epicycloid.png')
        self.createEpicycloidAction = menu.addAction(icon,
                                                     tr('Create epicycloid'),
                                                     self.createEpicycloid)
        self.createEpicycloidAction.setObjectName('stCreateEpicycloid')
        icon = QIcon(self.plugin_dir + '/images/heart.png')
        self.createHeartAction = menu.addAction(icon, tr('Create heart'),
                                                self.createHeart)
        self.createHeartAction.setObjectName('stCreateHeart')
        icon = QIcon(self.plugin_dir + '/images/hypocycloid.png')
        self.createHypocycloidAction = menu.addAction(icon,
                                                      tr('Create hypocycloid'),
                                                      self.createHypocycloid)
        self.createHypocycloidAction.setObjectName('stCreateHypocycloid')
        icon = QIcon(self.plugin_dir + '/images/line.png')
        self.createLOBAction = menu.addAction(icon,
                                              tr('Create line of bearing'),
                                              self.createLOB)
        self.createLOBAction.setObjectName('stCreateLineOfBearing')
        icon = QIcon(self.plugin_dir + '/images/pie.png')
        self.createPieAction = menu.addAction(icon, tr('Create pie wedge'),
                                              self.createPie)
        self.createPieAction.setObjectName('stCreatePie')
        icon = QIcon(self.plugin_dir + '/images/polyfoil.png')
        self.createPolyfoilAction = menu.addAction(icon, tr('Create polyfoil'),
                                                   self.createPolyfoil)
        self.createPolyfoilAction.setObjectName('stCreatePolyfoil')
        icon = QIcon(self.plugin_dir + '/images/polygon.png')
        self.createPolygonAction = menu.addAction(icon, tr('Create polygon'),
                                                  self.createPolygon)
        self.createPolygonAction.setObjectName('stCreatePolygon')
        icon = QIcon(self.plugin_dir + '/images/star.png')
        self.createStarAction = menu.addAction(icon, tr('Create star'),
                                               self.createStar)
        self.createStarAction.setObjectName('stCreateStar')
        # Add the shape creation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/shapes.png')
        self.createShapesAction = QAction(icon, tr('Create shapes'),
                                          self.iface.mainWindow())
        self.createShapesAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.createShapesAction)
        # Add the shape creation tools to the toolbar
        self.createShapeButton = QToolButton()
        self.createShapeButton.setMenu(menu)
        self.createShapeButton.setDefaultAction(self.createDonutAction)
        self.createShapeButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.createShapeButton.triggered.connect(self.createShapeTriggered)
        self.createShapeToolbar = self.toolbar.addWidget(
            self.createShapeButton)

        # Initialize the XY to Line menu item
        icon = QIcon(self.plugin_dir + '/images/xyline.png')
        self.xyLineAction = QAction(icon, tr('XY to line'),
                                    self.iface.mainWindow())
        self.xyLineAction.setObjectName('stXYtoLine')
        self.xyLineAction.triggered.connect(self.xyLineTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.xyLineAction)
        self.toolbar.addAction(self.xyLineAction)

        # Initialize the Geodesic Densifier menu item
        icon = QIcon(self.plugin_dir + '/images/geodesicDensifier.png')
        self.geodesicDensifyAction = QAction(icon,
                                             tr('Geodesic shape densifier'),
                                             self.iface.mainWindow())
        self.geodesicDensifyAction.setObjectName('stGeodesicDensifier')
        self.geodesicDensifyAction.triggered.connect(self.geodesicDensifyTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicDensifyAction)
        self.toolbar.addAction(self.geodesicDensifyAction)

        # Initialize the Geodesic decimation menu items
        menu = QMenu()
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.png')
        self.lineDecimateAction = menu.addAction(icon,
                                                 tr('Geodesic line decimate'),
                                                 self.lineDecimateTool)
        self.lineDecimateAction.setObjectName('stGeodesicLineDecimate')
        icon = QIcon(self.plugin_dir + '/images/geodesicPointDecimate.png')
        self.pointDecimateAction = menu.addAction(
            icon, tr('Geodesic point decimate'), self.pointDecimateTool)
        self.pointDecimateAction.setObjectName('stGeodesicPointDecimate')
        # Add the decimation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.png')
        self.simplifyGeomAction = QAction(
            icon, tr('Geodesic geometry simplification'),
            self.iface.mainWindow())
        self.simplifyGeomAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.simplifyGeomAction)
        # Add the shape creation tools to the toolbar
        self.simplifyButton = QToolButton()
        self.simplifyButton.setMenu(menu)
        self.simplifyButton.setDefaultAction(self.lineDecimateAction)
        self.simplifyButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.simplifyButton.triggered.connect(self.simplifyTriggered)
        self.simplifyToolbar = self.toolbar.addWidget(self.simplifyButton)

        # Initialize the Geodesic line break menu item
        icon = QIcon(self.plugin_dir + '/images/idlbreak.png')
        self.geodesicLineBreakAction = QAction(
            icon, tr('Geodesic line break at -180,180'),
            self.iface.mainWindow())
        self.geodesicLineBreakAction.setObjectName('stGeodesicLineBreak')
        self.geodesicLineBreakAction.triggered.connect(
            self.geodesicLineBreakTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicLineBreakAction)
        self.toolbar.addAction(self.geodesicLineBreakAction)

        # Initialize Geodesic Measure Tool
        self.geodesicMeasureTool = GeodesicMeasureTool(self.iface,
                                                       self.iface.mainWindow())
        icon = QIcon(self.plugin_dir + '/images/measure.png')
        self.measureAction = QAction(icon, tr('Geodesic measure tool'),
                                     self.iface.mainWindow())
        self.measureAction.setObjectName('stGeodesicMeasureTool')
        self.measureAction.triggered.connect(self.measureTool)
        self.measureAction.setCheckable(True)
        self.iface.addPluginToVectorMenu('Shape Tools', self.measureAction)
        self.toolbar.addAction(self.measureAction)

        # Initialize Geodesic Measurement layer
        icon = QIcon(self.plugin_dir + '/images/measureLine.png')
        self.measureLayerAction = QAction(icon,
                                          tr('Geodesic measurement layer'),
                                          self.iface.mainWindow())
        self.measureLayerAction.setObjectName('stGeodesicLineBreak')
        self.measureLayerAction.triggered.connect(self.measureLayerTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.measureLayerAction)
        self.toolbar.addAction(self.measureLayerAction)

        menu = QMenu()
        # Initialize Geodesic transformation tool
        icon = QIcon(self.plugin_dir + '/images/transformShape.png')
        self.transformationsAction = menu.addAction(
            icon, tr('Geodesic transformations'), self.transformTool)
        self.transformationsAction.setObjectName('stGeodesicTransformations')

        icon = QIcon(self.plugin_dir + '/images/flip.png')
        self.flipRotateAction = menu.addAction(icon,
                                               tr('Geodesic flip and rotate'),
                                               self.flipRotateTool)
        self.flipRotateAction.setObjectName('stGeodesicFlipRotate')

        icon = QIcon(self.plugin_dir + '/images/flipHorizontal.png')
        self.flipHorizontalAction = menu.addAction(icon, tr('Flip horizontal'),
                                                   self.flipHorizontalTool)
        self.flipHorizontalAction.setObjectName('stGeodesicFlipHorizontal')
        self.flipHorizontalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/flipVertical.png')
        self.flipVerticalAction = menu.addAction(icon, tr('Flip vertical'),
                                                 self.flipVerticalTool)
        self.flipVerticalAction.setObjectName('stGeodesicFlipVertical')
        self.flipVerticalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotate180.png')
        self.rotate180Action = menu.addAction(icon, tr('Rotate 180\xb0'),
                                              self.rotate180Tool)
        self.rotate180Action.setObjectName('stGeodesicRotate180')
        self.rotate180Action.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotatecw.png')
        self.rotate90CWAction = menu.addAction(icon, tr('Rotate 90\xb0 CW'),
                                               self.rotate90CWTool)
        self.rotate90CWAction.setObjectName('stGeodesicRotate90CW')
        self.rotate90CWAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotateccw.png')
        self.rotate90CCWAction = menu.addAction(icon, tr('Rotate 90\xb0 CCW'),
                                                self.rotate90CCWTool)
        self.rotate90CCWAction.setObjectName('stGeodesicRotate90CCW')
        self.rotate90CCWAction.setEnabled(False)
        self.transformsAction = QAction(icon, tr('Geodesic transforms'),
                                        self.iface.mainWindow())
        self.transformsAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools', self.transformsAction)

        self.transformationButton = QToolButton()
        self.transformationButton.setMenu(menu)
        self.transformationButton.setDefaultAction(self.transformationsAction)
        self.transformationButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.transformationButton.triggered.connect(self.toolButtonTriggered)
        self.tranformToolbar = self.toolbar.addWidget(
            self.transformationButton)

        # Initialize the Azimuth Distance Digitize function
        icon = QIcon(self.plugin_dir + '/images/dazdigitize.png')
        self.digitizeAction = QAction(icon, tr('Azimuth distance digitizer'),
                                      self.iface.mainWindow())
        self.digitizeAction.setObjectName('stAzDistanceDigitizer')
        self.digitizeAction.triggered.connect(self.setShowAzDigitizerTool)
        self.digitizeAction.setCheckable(True)
        self.digitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools', self.digitizeAction)
        self.toolbar.addAction(self.digitizeAction)

        # Initialize the multi point azimuth Digitize function
        icon = QIcon(self.plugin_dir + '/images/linedigitize.png')
        self.lineDigitizeAction = QAction(
            icon, tr('Azimuth distance sequence digitizer'),
            self.iface.mainWindow())
        self.lineDigitizeAction.setObjectName('stLineDigitizer')
        self.lineDigitizeAction.triggered.connect(self.setShowLineDigitizeTool)
        self.lineDigitizeAction.setCheckable(True)
        self.lineDigitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools',
                                         self.lineDigitizeAction)
        self.toolbar.addAction(self.lineDigitizeAction)

        # Settings
        icon = QIcon(self.plugin_dir + '/images/settings.png')
        self.settingsAction = QAction(icon, tr('Settings'),
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('shapeToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToVectorMenu('Shape Tools', self.settingsAction)

        # Help
        icon = QIcon(self.plugin_dir + '/images/help.png')
        self.helpAction = QAction(icon, tr('Shape Tools help'),
                                  self.iface.mainWindow())
        self.helpAction.setObjectName('shapeToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToVectorMenu('Shape Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableTools()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)
コード例 #26
0
class SearchDialog(QDialog):

    def __init__(self):
        super(SearchDialog, self).__init__(iface.mainWindow())
        self.initGui()
        self.mapstory = None

    def initGui(self):
        hlayout = QHBoxLayout()
        layout = QVBoxLayout()
        self.searchBox = QLineEdit()
        self.searchBox.returnPressed.connect(self.search)
        self.searchBox.setPlaceholderText("[Enter search string and press enter to search for maps]")
        hlayout.addWidget(self.searchBox)

        self.button = QToolButton()
        self.button.setText("Search")
        self.button.clicked.connect(self.search)
        self.button.adjustSize()
        self.searchBox.setFixedHeight(self.button.height())
        hlayout.addWidget(self.button)
        layout.addLayout(hlayout)

        w = QFrame()
        self.browser = QWebView()
        w.setStyleSheet("QFrame{border:1px solid rgb(0, 0, 0);}")
        innerlayout = QHBoxLayout()
        innerlayout.setSpacing(0)
        innerlayout.setMargin(0)
        innerlayout.addWidget(self.browser)
        w.setLayout(innerlayout)
        layout.addWidget(w)
        self.setLayout(layout)

        self.browser.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
        self.browser.settings().setUserStyleSheetUrl(QUrl("file://" + resourceFile("search.css").replace("\\", "/")))
        self.browser.linkClicked.connect(self.linkClicked)
        self.resize(600, 500)
        self.setWindowTitle("Search stories")

    def linkClicked(self, url):
        self.mapstory = url.path()
        self.close()

    def search(self):
        text = self.searchBox.text().strip()
        if text:
            try:
                r = execute(lambda: requests.get("http://mapstory.org/api/base/search", params={"type__in":"map", "limit":50, "q": text}))
                r.raise_for_status()
                mapstories = r.json()["objects"]
                if mapstories:
                    s = "<div><ul>"
                    for mapstory in mapstories:
                        link = "<a href='%s' class='button'>Open</a>" % (mapstory["id"])
                        s += "<li>%s <h3>%s</h3> %s <br> </li>" % (link, mapstory["title"], mapstory["abstract"])
                    s += "</ul></div>"
                else:
                    s = "<h2>No maps matching your search criteria were found.</h2>"
                self.browser.setHtml(s)
            except RequestException as e:
                    QMessageBox.warning(self, "Search",
                        u"There has been a problem performing the search:\n" + str(e.args[0]),
                        QMessageBox.Ok)
コード例 #27
0
    def initGui(self):
        """startup"""

        parent = self.iface.mainWindow()

        ######## action, button

        icon = QIcon("%s/%s" % (config.PLUGIN_DIR, "images/xyz.png"))
        icon_bbox = QIcon("%s/%s" % (config.PLUGIN_DIR, "images/bbox.svg"))
        self.action_connect = QAction(icon, "New XYZ Hub Connection", parent)
        self.action_connect.setWhatsThis(
            QCoreApplication.translate(PLUGIN_NAME, "WhatsThis message"))
        self.action_connect.setStatusTip(
            QCoreApplication.translate(PLUGIN_NAME, "status tip message"))

        self.action_clear_cache = QAction("Clear cache", parent)
        self.action_upload = QAction("Upload to New XYZ Geospace", parent)
        self.action_basemap = QAction("Add HERE Map Tile", parent)

        self.action_magic_sync = QAction("Magic Sync (EXPERIMENTAL)", parent)
        self.action_manage = QAction("Manage XYZ Geospace (EXPERIMENTAL)",
                                     parent)
        self.action_edit = QAction("Edit/Delete XYZ Geospace (EXPERIMENTAL)",
                                   parent)

        if self.iface.activeLayer() is None:
            # self.action_upload.setEnabled(False)
            self.action_edit.setEnabled(False)
            self.action_magic_sync.setEnabled(False)

        # self.action_magic_sync.setVisible(False) # disable magic sync

        ######## CONNECT action, button

        self.action_connect.triggered.connect(self.open_connection_dialog)
        self.action_manage.triggered.connect(self.open_manage_dialog)
        self.action_edit.triggered.connect(self.open_edit_dialog)
        self.action_upload.triggered.connect(self.open_upload_dialog)
        self.action_magic_sync.triggered.connect(self.open_magic_sync_dialog)
        self.action_clear_cache.triggered.connect(self.open_clear_cache_dialog)
        self.action_basemap.triggered.connect(self.open_basemap_dialog)

        ######## Add the toolbar + button
        self.toolbar = self.iface.addToolBar(PLUGIN_NAME)
        self.toolbar.setObjectName("XYZ Hub Connector")

        tool_btn = QToolButton(self.toolbar)

        self.actions = [
            self.action_connect, self.action_upload, self.action_basemap,
            self.action_clear_cache
        ]  # , self.action_magic_sync, self.action_manage, self.action_edit
        for a in self.actions:
            tool_btn.addAction(a)
            self.iface.addPluginToWebMenu(self.web_menu, a)

        tool_btn.setDefaultAction(self.action_connect)
        tool_btn.setPopupMode(tool_btn.MenuButtonPopup)

        self.xyz_widget_action = self.toolbar.addWidget(tool_btn)

        self.action_help = None

        self.action_reload = QAction(icon_bbox, "Reload BBox", parent)
        self.action_reload.triggered.connect(self.layer_reload_bbox)
        self.action_reload.setVisible(False)  # disable
        self.toolbar.addAction(self.action_reload)

        progress = QProgressBar()
        progress.setMinimum(0)
        progress.setMaximum(0)
        progress.reset()
        progress.hide()
        # progress = self.iface.statusBarIface().children()[2] # will be hidden by qgis
        self.iface.statusBarIface().addPermanentWidget(progress)
        self.pb = progress
コード例 #28
0
ファイル: relation_line_edit.py プロジェクト: ollawone/stdm
    def __init__(self, column, parent=None, pixmap=None, host=None):
        """
        Class constructor.
        :param column: Column object containing foreign key information.
        :type column: BaseColumn
        :param parent: Parent widget for the control.
        :type parent: QWidget
        :param pixmap: Pixmap to use for the line edit button.
        :type pixmap: QPixmap
        """

        QLineEdit.__init__(self, parent)

        self.column = column
        self._entity = self.column.entity
        self.entity_dialog = host

        # Configure load button
        self.btn_load = QToolButton(parent)
        self.btn_load.setCursor(Qt.PointingHandCursor)
        self.btn_load.setFocusPolicy(Qt.NoFocus)
        px = GuiUtils.get_icon_pixmap('select_record.png')
        if not pixmap is None:
            px = pixmap
        self.btn_load.setIcon(QIcon(px))
        self.btn_load.setIconSize(px.size())
        self.btn_load.setStyleSheet('background: transparent; padding: 0px; '
                                    'border: none;')
        self.btn_load.clicked.connect(self.on_load_foreign_key_browser)

        clear_px = GuiUtils.get_icon_pixmap('clear.png')

        self.btn_clear = QToolButton(parent)
        self.btn_clear.setCursor(Qt.PointingHandCursor)
        self.btn_clear.setFocusPolicy(Qt.NoFocus)
        self.btn_clear.setIcon(QIcon(clear_px))
        self.btn_clear.setIconSize(clear_px.size())
        self.btn_clear.setStyleSheet('background: transparent; padding: 0px; '
                                     'border: none;')

        self.btn_clear.clicked.connect(self.clear_line_edit)

        frame_width = self.set_button_minimum_size(self.btn_load)
        self.set_button_minimum_size(self.btn_clear)
        # Ensure that text does not overlay button
        padding = self.btn_load.sizeHint().width() + frame_width + 1

        self.setStyleSheet('padding-right: ' + str(padding * 2) + 'px;')

        # Set layout
        self.button_layout = QHBoxLayout(self)

        self.button_layout.addWidget(self.btn_clear, 0, Qt.AlignRight)
        self.button_layout.addWidget(self.btn_load, 0, Qt.AlignRight)

        self.button_layout.setSpacing(0)
        self.button_layout.setMargin(5)

        self.btn_clear.setVisible(False)
        # Readonly as text is loaded from the related entity
        self.setReadOnly(True)

        # Current model object
        self._current_item = None
コード例 #29
0
ファイル: aerogen.py プロジェクト: juhele/qgis-aerogen-plugin
class AeroGen:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'AeroGen_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr('&AeroGen')

        # add plugin icon into plugin toolbar
        self.toolButton = QToolButton()

        #print "** INITIALIZING AeroGen"

        self.pluginIsActive = False
        self.dockwidget = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('AeroGen', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolButton.setDefaultAction(action)
            self.iface.addToolBarWidget(self.toolButton)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/AeroGen/icon.png'
        self.add_action(icon_path,
                        text=self.tr('AeroGen'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

    #--------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""

        #print "** CLOSING AeroGen"

        # disconnects
        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)

        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        # Commented next statement since it causes QGIS crashe
        # when closing the docked window:
        # self.dockwidget = None

        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        #print "** UNLOAD AeroGen"

        for action in self.actions:
            self.iface.removePluginMenu(self.tr('&AeroGen'), action)
            self.iface.removeToolBarIcon(action)

    #--------------------------------------------------------------------------

    def run(self):
        """Run method that loads and starts the plugin"""

        if not self.pluginIsActive:
            self.pluginIsActive = True

            #print "** STARTING AeroGen"

            # dockwidget may not exist if:
            #    first run of plugin
            #    removed on close (see self.onClosePlugin method)
            if self.dockwidget == None:
                # Create the dockwidget (after translation) and keep reference
                self.dockwidget = AeroGenDockWidget()

            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
コード例 #30
0
ファイル: relation_line_edit.py プロジェクト: ollawone/stdm
class ExpressionLineEdit(QLineEdit):
    def __init__(self, column, host=None, parent=None):
        # Use a different pixmap

        self._current_profile = current_profile()

        QLineEdit.__init__(self, parent)

        self.column = column
        self._entity = self.column.entity

        self.layer = self.create_layer()
        self.host = host
        # Configure load button
        self.btn_load = QToolButton(parent)
        self.btn_load.setCursor(Qt.PointingHandCursor)
        self.btn_load.setFocusPolicy(Qt.NoFocus)
        px = GuiUtils.get_icon_pixmap('expression.png')

        self.btn_load.setIcon(QIcon(px))
        self.btn_load.setIconSize(px.size())
        self.btn_load.setStyleSheet('background: transparent; padding: 0px; '
                                    'border: none;')

        frame_width = self.set_button_minimum_size(self.btn_load)

        # Ensure that text does not overlay button
        padding = self.btn_load.sizeHint().width() + frame_width + 1

        self.setStyleSheet('padding-right: ' + str(padding * 2) + 'px;')

        # Set layout
        self.button_layout = QHBoxLayout(self)

        self.button_layout.addWidget(self.btn_load, 0, Qt.AlignRight)

        self.button_layout.setSpacing(0)
        self.button_layout.setMargin(5)

        # Readonly as text generated automatically
        self.setReadOnly(True)

        # Current model object
        self._current_item = None

    def create_layer(self):
        srid = None
        column = ''
        if self.entity.has_geometry_column():
            geom_cols = [col.name for col in self.entity.columns.values()
                         if col.TYPE_INFO == 'GEOMETRY']
            column = geom_cols[0]
            geom_col_obj = self.entity.columns[column]

            if geom_col_obj.srid >= 100000:
                srid = geom_col_obj.srid
        layer = vector_layer(self.entity.name, geom_column=column,
                             proj_wkt=srid)
        return layer

    def get_feature_value(self, model=None):
        self.layer.startEditing()
        feature = None

        request = QgsFeatureRequest()
        if model is None:
            model = self.host.model()
        request.setFilterFid(model.id)
        feature_itr = self.layer.getFeatures(request)
        for feat in feature_itr:
            feature = feat
            break

        exp = QgsExpression(self.column.expression)

        if exp.hasParserError():
            raise Exception(exp.parserErrorString())

        exp.prepare(self.layer.fields())
        if feature is not None:
            value = exp.evaluate(feature)

            return value
        else:
            return None

    def set_button_minimum_size(self, button):
        """
        Sets the minimum button size.
        :param button: The button to be set.
        :type button: QToolButton
        :return: Returns the frame width of the button
        :rtype: Integer
        """
        frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        msz = self.minimumSizeHint()
        self.setMinimumSize(
            max(
                msz.width(),
                button.sizeHint().height() + frame_width * 2 + 2
            ), max(
                msz.height(),
                button.sizeHint().height() + frame_width * 2 + 2
            )
        )
        return frame_width

    @property
    def entity(self):
        """
        :return: Returns the entity object corresponding to this widget.
        :rtype: Entity
        """
        return self._entity

    def clear_line_edit(self):
        """
        Clears the text in the line edit.
        """
        self.clear()

    def on_expression_triggered(self, model=None):
        """
        Slot raised to load browser for selecting foreign key entities. To be
        implemented by subclasses.
        """
        self.format_display(self.get_feature_value(model))
        return self.get_feature_value()

    def format_display(self, value):
        """
        Extract object values to show in the line edit based on the specified
        display columns.
        """
        if value is not None:
            self.setText(str(value))
コード例 #31
0
ファイル: ModelerDialog.py プロジェクト: dwsilk/QGIS
class ModelerDialog(BASE, WIDGET):
    ALG_ITEM = 'ALG_ITEM'
    PROVIDER_ITEM = 'PROVIDER_ITEM'
    GROUP_ITEM = 'GROUP_ITEM'

    NAME_ROLE = Qt.UserRole
    TAG_ROLE = Qt.UserRole + 1
    TYPE_ROLE = Qt.UserRole + 2

    CANVAS_SIZE = 4000

    update_model = pyqtSignal()

    def __init__(self, model=None):
        super().__init__(None)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.setupUi(self)

        self._variables_scope = None

        # LOTS of bug reports when we include the dock creation in the UI file
        # see e.g. #16428, #19068
        # So just roll it all by hand......!
        self.propertiesDock = QgsDockWidget(self)
        self.propertiesDock.setFeatures(
            QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.propertiesDock.setObjectName("propertiesDock")
        propertiesDockContents = QWidget()
        self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents)
        self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0)
        self.verticalDockLayout_1.setSpacing(0)
        self.scrollArea_1 = QgsScrollArea(propertiesDockContents)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.scrollArea_1.sizePolicy().hasHeightForWidth())
        self.scrollArea_1.setSizePolicy(sizePolicy)
        self.scrollArea_1.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_1.setFrameShape(QFrame.NoFrame)
        self.scrollArea_1.setFrameShadow(QFrame.Plain)
        self.scrollArea_1.setWidgetResizable(True)
        self.scrollAreaWidgetContents_1 = QWidget()
        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1)
        self.gridLayout.setContentsMargins(6, 6, 6, 6)
        self.gridLayout.setSpacing(4)
        self.label_1 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
        self.textName = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textName, 0, 1, 1, 1)
        self.label_2 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1)
        self.label_1.setText(self.tr("Name"))
        self.textName.setToolTip(self.tr("Enter model name here"))
        self.label_2.setText(self.tr("Group"))
        self.textGroup.setToolTip(self.tr("Enter group name here"))
        self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1)
        self.verticalDockLayout_1.addWidget(self.scrollArea_1)
        self.propertiesDock.setWidget(propertiesDockContents)
        self.propertiesDock.setWindowTitle(self.tr("Model Properties"))

        self.inputsDock = QgsDockWidget(self)
        self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.inputsDock.setObjectName("inputsDock")
        self.inputsDockContents = QWidget()
        self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_2 = QgsScrollArea(self.inputsDockContents)
        sizePolicy.setHeightForWidth(self.scrollArea_2.sizePolicy().hasHeightForWidth())
        self.scrollArea_2.setSizePolicy(sizePolicy)
        self.scrollArea_2.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_2.setFrameShape(QFrame.NoFrame)
        self.scrollArea_2.setFrameShadow(QFrame.Plain)
        self.scrollArea_2.setWidgetResizable(True)
        self.scrollAreaWidgetContents_2 = QWidget()
        self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.inputsTree = QTreeWidget(self.scrollAreaWidgetContents_2)
        self.inputsTree.setAlternatingRowColors(True)
        self.inputsTree.header().setVisible(False)
        self.verticalLayout.addWidget(self.inputsTree)
        self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
        self.verticalLayout_3.addWidget(self.scrollArea_2)
        self.inputsDock.setWidget(self.inputsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock)
        self.inputsDock.setWindowTitle(self.tr("Inputs"))

        self.algorithmsDock = QgsDockWidget(self)
        self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.algorithmsDock.setObjectName("algorithmsDock")
        self.algorithmsDockContents = QWidget()
        self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents)
        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents)
        sizePolicy.setHeightForWidth(self.scrollArea_3.sizePolicy().hasHeightForWidth())
        self.scrollArea_3.setSizePolicy(sizePolicy)
        self.scrollArea_3.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_3.setFrameShape(QFrame.NoFrame)
        self.scrollArea_3.setFrameShadow(QFrame.Plain)
        self.scrollArea_3.setWidgetResizable(True)
        self.scrollAreaWidgetContents_3 = QWidget()
        self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setSpacing(4)
        self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.addWidget(self.searchBox)
        self.algorithmTree = QgsProcessingToolboxTreeView(None,
                                                          QgsApplication.processingRegistry())
        self.algorithmTree.setAlternatingRowColors(True)
        self.algorithmTree.header().setVisible(False)
        self.verticalLayout_2.addWidget(self.algorithmTree)
        self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
        self.verticalLayout_4.addWidget(self.scrollArea_3)
        self.algorithmsDock.setWidget(self.algorithmsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock)
        self.algorithmsDock.setWindowTitle(self.tr("Algorithms"))
        self.searchBox.setToolTip(self.tr("Enter algorithm name to filter list"))
        self.searchBox.setShowSearchIcon(True)

        self.variables_dock = QgsDockWidget(self)
        self.variables_dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.variables_dock.setObjectName("variablesDock")
        self.variables_dock_contents = QWidget()
        vl_v = QVBoxLayout()
        vl_v.setContentsMargins(0, 0, 0, 0)
        self.variables_editor = QgsVariableEditorWidget()
        vl_v.addWidget(self.variables_editor)
        self.variables_dock_contents.setLayout(vl_v)
        self.variables_dock.setWidget(self.variables_dock_contents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.variables_dock)
        self.variables_dock.setWindowTitle(self.tr("Variables"))
        self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock)
        self.tabifyDockWidget(self.propertiesDock, self.variables_dock)
        self.variables_editor.scopeChanged.connect(self.variables_changed)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.centralWidget().layout().insertWidget(0, self.bar)

        try:
            self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging)
        except:
            pass

        if iface is not None:
            self.mToolbar.setIconSize(iface.iconSize())
            self.setStyleSheet(iface.mainWindow().styleSheet())

        self.toolbutton_export_to_script = QToolButton()
        self.toolbutton_export_to_script.setPopupMode(QToolButton.InstantPopup)
        self.export_to_script_algorithm_action = QAction(QCoreApplication.translate('ModelerDialog', 'Export as Script Algorithm…'))
        self.toolbutton_export_to_script.addActions([self.export_to_script_algorithm_action])
        self.mToolbar.insertWidget(self.mActionExportImage, self.toolbutton_export_to_script)
        self.export_to_script_algorithm_action.triggered.connect(self.export_as_script_algorithm)

        self.mActionOpen.setIcon(
            QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
        self.mActionSave.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSave.svg'))
        self.mActionSaveAs.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSaveAs.svg'))
        self.mActionSaveInProject.setIcon(
            QgsApplication.getThemeIcon('/mAddToProject.svg'))
        self.mActionZoomActual.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomActual.svg'))
        self.mActionZoomIn.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomIn.svg'))
        self.mActionZoomOut.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomOut.svg'))
        self.mActionExportImage.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg'))
        self.mActionZoomToItems.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg'))
        self.mActionExportPdf.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg'))
        self.mActionExportSvg.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg'))
        self.toolbutton_export_to_script.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPython.svg'))
        self.mActionEditHelp.setIcon(
            QgsApplication.getThemeIcon('/mActionEditHelpContent.svg'))
        self.mActionRun.setIcon(
            QgsApplication.getThemeIcon('/mActionStart.svg'))

        self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock)
        self.tabifyDockWidget(self.inputsDock, self.algorithmsDock)
        self.inputsDock.raise_()

        self.setWindowFlags(Qt.WindowMinimizeButtonHint |
                            Qt.WindowMaximizeButtonHint |
                            Qt.WindowCloseButtonHint)

        settings = QgsSettings()
        self.restoreState(settings.value("/Processing/stateModeler", QByteArray()))
        self.restoreGeometry(settings.value("/Processing/geometryModeler", QByteArray()))

        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))

        self.view.setScene(self.scene)
        self.view.setAcceptDrops(True)
        self.view.ensureVisible(0, 0, 10, 10)
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96, QgsApplication.desktop().logicalDpiX() / 96)

        def _dragEnterEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'):
                event.acceptProposedAction()
            else:
                event.ignore()

        def _dropEvent(event):
            def alg_dropped(algorithm_id, pos):
                alg = QgsApplication.processingRegistry().createAlgorithmById(algorithm_id)
                if alg is not None:
                    self._addAlgorithm(alg, pos)
                else:
                    assert False, algorithm_id

            def input_dropped(id, pos):
                if id in [param.id() for param in QgsApplication.instance().processingRegistry().parameterTypes()]:
                    self.addInputOfType(itemId, pos)

            if event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'):
                data = event.mimeData().data('application/x-vnd.qgis.qgis.algorithmid')
                stream = QDataStream(data, QIODevice.ReadOnly)
                algorithm_id = stream.readQString()
                QTimer.singleShot(0, lambda id=algorithm_id, pos=self.view.mapToScene(event.pos()): alg_dropped(id, pos))
                event.accept()
            elif event.mimeData().hasText():
                itemId = event.mimeData().text()
                QTimer.singleShot(0, lambda id=itemId, pos=self.view.mapToScene(event.pos()): input_dropped(id, pos))
                event.accept()
            else:
                event.ignore()

        def _dragMoveEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'):
                event.accept()
            else:
                event.ignore()

        def _wheelEvent(event):
            self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

            settings = QgsSettings()
            factor = settings.value('/qgis/zoom_favor', 2.0)

            # "Normal" mouse has an angle delta of 120, precision mouses provide data
            # faster, in smaller steps
            factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y())

            if (event.modifiers() == Qt.ControlModifier):
                factor = 1.0 + (factor - 1.0) / 20.0

            if event.angleDelta().y() < 0:
                factor = 1 / factor

            self.view.scale(factor, factor)

        def _enterEvent(e):
            QGraphicsView.enterEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mouseReleaseEvent(e):
            QGraphicsView.mouseReleaseEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mousePressEvent(e):
            if e.button() == Qt.MidButton:
                self.previousMousePos = e.pos()
            else:
                QGraphicsView.mousePressEvent(self.view, e)

        def _mouseMoveEvent(e):
            if e.buttons() == Qt.MidButton:
                offset = self.previousMousePos - e.pos()
                self.previousMousePos = e.pos()

                self.view.verticalScrollBar().setValue(self.view.verticalScrollBar().value() + offset.y())
                self.view.horizontalScrollBar().setValue(self.view.horizontalScrollBar().value() + offset.x())
            else:
                QGraphicsView.mouseMoveEvent(self.view, e)

        self.view.setDragMode(QGraphicsView.ScrollHandDrag)
        self.view.dragEnterEvent = _dragEnterEvent
        self.view.dropEvent = _dropEvent
        self.view.dragMoveEvent = _dragMoveEvent
        self.view.wheelEvent = _wheelEvent
        self.view.enterEvent = _enterEvent
        self.view.mousePressEvent = _mousePressEvent
        self.view.mouseMoveEvent = _mouseMoveEvent

        def _mimeDataInput(items):
            mimeData = QMimeData()
            text = items[0].data(0, Qt.UserRole)
            mimeData.setText(text)
            return mimeData

        self.inputsTree.mimeData = _mimeDataInput

        self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
        self.inputsTree.setDropIndicatorShown(True)

        self.algorithms_model = ModelerToolboxModel(self, QgsApplication.processingRegistry())
        self.algorithmTree.setToolboxProxyModel(self.algorithms_model)
        self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly)
        self.algorithmTree.setDropIndicatorShown(True)

        filters = QgsProcessingToolboxProxyModel.Filters(QgsProcessingToolboxProxyModel.FilterModeler)
        if ProcessingConfig.getSetting(ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES):
            filters |= QgsProcessingToolboxProxyModel.FilterShowKnownIssues
        self.algorithmTree.setFilters(filters)

        if hasattr(self.searchBox, 'setPlaceholderText'):
            self.searchBox.setPlaceholderText(QCoreApplication.translate('ModelerDialog', 'Search…'))
        if hasattr(self.textName, 'setPlaceholderText'):
            self.textName.setPlaceholderText(self.tr('Enter model name here'))
        if hasattr(self.textGroup, 'setPlaceholderText'):
            self.textGroup.setPlaceholderText(self.tr('Enter group name here'))

        # Connect signals and slots
        self.inputsTree.doubleClicked.connect(self.addInput)
        self.searchBox.textChanged.connect(self.algorithmTree.setFilterString)
        self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

        # Ctrl+= should also trigger a zoom in action
        ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self)
        ctrlEquals.activated.connect(self.zoomIn)

        self.mActionOpen.triggered.connect(self.openModel)
        self.mActionSave.triggered.connect(self.save)
        self.mActionSaveAs.triggered.connect(self.saveAs)
        self.mActionSaveInProject.triggered.connect(self.saveInProject)
        self.mActionZoomIn.triggered.connect(self.zoomIn)
        self.mActionZoomOut.triggered.connect(self.zoomOut)
        self.mActionZoomActual.triggered.connect(self.zoomActual)
        self.mActionZoomToItems.triggered.connect(self.zoomToItems)
        self.mActionExportImage.triggered.connect(self.exportAsImage)
        self.mActionExportPdf.triggered.connect(self.exportAsPdf)
        self.mActionExportSvg.triggered.connect(self.exportAsSvg)
        #self.mActionExportPython.triggered.connect(self.exportAsPython)
        self.mActionEditHelp.triggered.connect(self.editHelp)
        self.mActionRun.triggered.connect(self.runModel)

        if model is not None:
            self.model = model.create()
            self.model.setSourceFilePath(model.sourceFilePath())
            self.textGroup.setText(self.model.group())
            self.textName.setText(self.model.displayName())
            self.repaintModel()

        else:
            self.model = QgsProcessingModelAlgorithm()
            self.model.setProvider(QgsApplication.processingRegistry().providerById('model'))
        self.update_variables_gui()

        self.fillInputsTree()

        self.view.centerOn(0, 0)
        self.help = None

        self.hasChanged = False

    def closeEvent(self, evt):
        settings = QgsSettings()
        settings.setValue("/Processing/stateModeler", self.saveState())
        settings.setValue("/Processing/geometryModeler", self.saveGeometry())

        if self.hasChanged:
            ret = QMessageBox.question(
                self, self.tr('Save Model?'),
                self.tr('There are unsaved changes in this model. Do you want to keep those?'),
                QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard, QMessageBox.Cancel)

            if ret == QMessageBox.Save:
                self.saveModel(False)
                evt.accept()
            elif ret == QMessageBox.Discard:
                evt.accept()
            else:
                evt.ignore()
        else:
            evt.accept()

    def editHelp(self):
        alg = self.model
        dlg = HelpEditionDialog(alg)
        dlg.exec_()
        if dlg.descriptions:
            self.model.setHelpContent(dlg.descriptions)
            self.hasChanged = True

    def update_variables_gui(self):
        variables_scope = QgsExpressionContextScope(self.tr('Model Variables'))
        for k, v in self.model.variables().items():
            variables_scope.setVariable(k, v)
        variables_context = QgsExpressionContext()
        variables_context.appendScope(variables_scope)
        self.variables_editor.setContext(variables_context)
        self.variables_editor.setEditableScopeIndex(0)

    def variables_changed(self):
        self.model.setVariables(self.variables_editor.variablesInActiveScope())

    def runModel(self):
        if len(self.model.childAlgorithms()) == 0:
            self.bar.pushMessage("", self.tr("Model doesn't contain any algorithm and/or parameter and can't be executed"), level=Qgis.Warning, duration=5)
            return

        dlg = AlgorithmDialog(self.model.create(), parent=iface.mainWindow())
        dlg.exec_()

    def save(self):
        self.saveModel(False)

    def saveAs(self):
        self.saveModel(True)

    def saveInProject(self):
        if not self.can_save():
            return

        self.model.setName(str(self.textName.text()))
        self.model.setGroup(str(self.textGroup.text()))
        self.model.setSourceFilePath(None)

        project_provider = QgsApplication.processingRegistry().providerById(PROJECT_PROVIDER_ID)
        project_provider.add_model(self.model)

        self.update_model.emit()
        self.bar.pushMessage("", self.tr("Model was saved inside current project"), level=Qgis.Success, duration=5)

        self.hasChanged = False
        QgsProject.instance().setDirty(True)

    def zoomIn(self):
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))

        settings = QgsSettings()
        factor = settings.value('/qgis/zoom_favor', 2.0)

        self.view.scale(factor, factor)
        self.view.centerOn(point)
        self.repaintModel()

    def zoomOut(self):
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))

        settings = QgsSettings()
        factor = settings.value('/qgis/zoom_favor', 2.0)
        factor = 1 / factor

        self.view.scale(factor, factor)
        self.view.centerOn(point)
        self.repaintModel()

    def zoomActual(self):
        point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))
        self.view.resetTransform()
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96, QgsApplication.desktop().logicalDpiX() / 96)
        self.view.centerOn(point)

    def zoomToItems(self):
        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        self.view.fitInView(totalRect, Qt.KeepAspectRatio)

    def exportAsImage(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As Image'), '',
                                                           self.tr('PNG files (*.png *.PNG)'))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        imgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, imgRect, totalRect)
        painter.end()

        img.save(filename)

        self.bar.pushMessage("", self.tr("Successfully exported model as image to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)

    def exportAsPdf(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As PDF'), '',
                                                           self.tr('PDF files (*.pdf *.PDF)'))
        if not filename:
            return

        if not filename.lower().endswith('.pdf'):
            filename += '.pdf'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(filename)
        printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel)
        printer.setFullPage(True)

        painter = QPainter(printer)
        self.scene.render(painter, printerRect, totalRect)
        painter.end()

        self.bar.pushMessage("", self.tr("Successfully exported model as PDF to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)

    def exportAsSvg(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As SVG'), '',
                                                           self.tr('SVG files (*.svg *.SVG)'))
        if not filename:
            return

        if not filename.lower().endswith('.svg'):
            filename += '.svg'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        svgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        svg = QSvgGenerator()
        svg.setFileName(filename)
        svg.setSize(QSize(totalRect.width(), totalRect.height()))
        svg.setViewBox(svgRect)
        svg.setTitle(self.model.displayName())

        painter = QPainter(svg)
        self.scene.render(painter, svgRect, totalRect)
        painter.end()

        self.bar.pushMessage("", self.tr("Successfully exported model as SVG to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)

    def exportAsPython(self):
        filename, filter = QFileDialog.getSaveFileName(self,
                                                       self.tr('Save Model As Python Script'), '',
                                                       self.tr('Processing scripts (*.py *.PY)'))
        if not filename:
            return

        if not filename.lower().endswith('.py'):
            filename += '.py'

        text = self.model.asPythonCode()
        with codecs.open(filename, 'w', encoding='utf-8') as fout:
            fout.write(text)

        self.bar.pushMessage("", self.tr("Successfully exported model as python script to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)

    def can_save(self):
        """
        Tests whether a model can be saved, or if it is not yet valid
        :return: bool
        """
        if str(self.textName.text()).strip() == '':
            self.bar.pushWarning(
                "", self.tr('Please a enter model name before saving')
            )
            return False

        return True

    def saveModel(self, saveAs):
        if not self.can_save():
            return
        self.model.setName(str(self.textName.text()))
        self.model.setGroup(str(self.textGroup.text()))
        if self.model.sourceFilePath() and not saveAs:
            filename = self.model.sourceFilePath()
        else:
            filename, filter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model'),
                                                           ModelerUtils.modelsFolders()[0],
                                                           self.tr('Processing models (*.model3 *.MODEL3)'))
            if filename:
                if not filename.endswith('.model3'):
                    filename += '.model3'
                self.model.setSourceFilePath(filename)
        if filename:
            if not self.model.toFile(filename):
                if saveAs:
                    QMessageBox.warning(self, self.tr('I/O error'),
                                        self.tr('Unable to save edits. Reason:\n {0}').format(str(sys.exc_info()[1])))
                else:
                    QMessageBox.warning(self, self.tr("Can't save model"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', (
                        "This model can't be saved in its original location (probably you do not "
                        "have permission to do it). Please, use the 'Save as…' option."))
                    )
                return
            self.update_model.emit()
            if saveAs:
                self.bar.pushMessage("", self.tr("Model was correctly saved to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
            else:
                self.bar.pushMessage("", self.tr("Model was correctly saved"), level=Qgis.Success, duration=5)

            self.hasChanged = False

    def openModel(self):
        filename, selected_filter = QFileDialog.getOpenFileName(self,
                                                                self.tr('Open Model'),
                                                                ModelerUtils.modelsFolders()[0],
                                                                self.tr('Processing models (*.model3 *.MODEL3)'))
        if filename:
            self.loadModel(filename)

    def loadModel(self, filename):
        alg = QgsProcessingModelAlgorithm()
        if alg.fromFile(filename):
            self.model = alg
            self.model.setProvider(QgsApplication.processingRegistry().providerById('model'))
            self.textGroup.setText(alg.group())
            self.textName.setText(alg.name())
            self.repaintModel()

            self.update_variables_gui()

            self.view.centerOn(0, 0)
            self.hasChanged = False
        else:
            QgsMessageLog.logMessage(self.tr('Could not load model {0}').format(filename),
                                     self.tr('Processing'),
                                     Qgis.Critical)
            QMessageBox.critical(self, self.tr('Open Model'),
                                 self.tr('The selected model could not be loaded.\n'
                                         'See the log for more information.'))

    def repaintModel(self, controls=True):
        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE,
                                       self.CANVAS_SIZE))
        self.scene.paintModel(self.model, controls)
        self.view.setScene(self.scene)

    def addInput(self):
        item = self.inputsTree.currentItem()
        param = item.data(0, Qt.UserRole)
        self.addInputOfType(param)

    def addInputOfType(self, paramType, pos=None):
        dlg = ModelerParameterDefinitionDialog(self.model, paramType)
        dlg.exec_()
        if dlg.param is not None:
            if pos is None:
                pos = self.getPositionForParameterItem()
            if isinstance(pos, QPoint):
                pos = QPointF(pos)
            component = QgsProcessingModelParameter(dlg.param.name())
            component.setDescription(dlg.param.name())
            component.setPosition(pos)
            self.model.addModelParameter(dlg.param, component)
            self.repaintModel()
            # self.view.ensureVisible(self.scene.getLastParameterItem())
            self.hasChanged = True

    def getPositionForParameterItem(self):
        MARGIN = 20
        BOX_WIDTH = 200
        BOX_HEIGHT = 80
        if len(self.model.parameterComponents()) > 0:
            maxX = max([i.position().x() for i in list(self.model.parameterComponents().values())])
            newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
        else:
            newX = MARGIN + BOX_WIDTH / 2
        return QPointF(newX, MARGIN + BOX_HEIGHT / 2)

    def fillInputsTree(self):
        icon = QIcon(os.path.join(pluginPath, 'images', 'input.svg'))
        parametersItem = QTreeWidgetItem()
        parametersItem.setText(0, self.tr('Parameters'))
        sortedParams = sorted(QgsApplication.instance().processingRegistry().parameterTypes(), key=lambda pt: pt.name())
        for param in sortedParams:
            if param.flags() & QgsProcessingParameterType.ExposeToModeler:
                paramItem = QTreeWidgetItem()
                paramItem.setText(0, param.name())
                paramItem.setData(0, Qt.UserRole, param.id())
                paramItem.setIcon(0, icon)
                paramItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled)
                paramItem.setToolTip(0, param.description())
                parametersItem.addChild(paramItem)
        self.inputsTree.addTopLevelItem(parametersItem)
        parametersItem.setExpanded(True)

    def addAlgorithm(self):
        algorithm = self.algorithmTree.selectedAlgorithm()
        if algorithm is not None:
            alg = QgsApplication.processingRegistry().createAlgorithmById(algorithm.id())
            self._addAlgorithm(alg)

    def _addAlgorithm(self, alg, pos=None):
        dlg = ModelerParametersDialog(alg, self.model)
        if dlg.exec_():
            alg = dlg.createAlgorithm()
            if pos is None:
                alg.setPosition(self.getPositionForAlgorithmItem())
            else:
                alg.setPosition(pos)
            from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
            for i, out in enumerate(alg.modelOutputs()):
                alg.modelOutput(out).setPosition(alg.position() + QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
                                                                          ModelerGraphicItem.BOX_HEIGHT))
            self.model.addChildAlgorithm(alg)
            self.repaintModel()
            self.hasChanged = True

    def getPositionForAlgorithmItem(self):
        MARGIN = 20
        BOX_WIDTH = 200
        BOX_HEIGHT = 80
        if self.model.childAlgorithms():
            maxX = max([alg.position().x() for alg in list(self.model.childAlgorithms().values())])
            maxY = max([alg.position().y() for alg in list(self.model.childAlgorithms().values())])
            newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
            newY = min(MARGIN + BOX_HEIGHT + maxY, self.CANVAS_SIZE -
                       BOX_HEIGHT)
        else:
            newX = MARGIN + BOX_WIDTH / 2
            newY = MARGIN * 2 + BOX_HEIGHT + BOX_HEIGHT / 2
        return QPointF(newX, newY)

    def export_as_script_algorithm(self):
        dlg = ScriptEditorDialog(None)

        dlg.editor.setText('\n'.join(self.model.asPythonCode(QgsProcessing.PythonQgsProcessingAlgorithmSubclass, 4)))
        dlg.show()
コード例 #32
0
    def initGui(self):

        settings = QgsSettings()
        icon_paius = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'hfflogo.png'))
        self.action = QAction(QIcon(icon_paius), "HFF Main Panel",
                              self.iface.mainWindow())
        self.action.triggered.connect(self.showHideDockWidget)

        # dock widget
        self.dockWidget = HffPluginDialog(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget)

        # TOOLBAR
        self.toolBar = self.iface.addToolBar("HFF")
        self.toolBar.setObjectName("HFF")
        self.toolBar.addAction(self.action)

        self.dataToolButton = QToolButton(self.toolBar)
        self.dataToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        ######  Section dedicated to the basic data entry
        # add Actions data
        self.siteToolButton = QToolButton(self.toolBar)
        self.siteToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        icon_site = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconSite.png'))
        self.actionSite = QAction(QIcon(icon_site), "Site",
                                  self.iface.mainWindow())
        self.actionSite.setWhatsThis("Site")
        self.actionSite.triggered.connect(self.runSite)

        icon_eamena = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'eamena.jpg'))
        self.actionEamena = QAction(QIcon(icon_eamena), "Eamena",
                                    self.iface.mainWindow())
        self.actionEamena.setWhatsThis("Eamena")
        self.actionEamena.triggered.connect(self.runEamena)

        icon_eamena_archaeology = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'eamena.jpg'))

        self.siteToolButton.addActions([self.actionSite, self.actionEamena])
        self.siteToolButton.setDefaultAction(self.actionSite)

        self.toolBar.addWidget(self.siteToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the UnderWater data entry
        # add Actions data
        icon_UW = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'snorkel.png'))
        self.actionUW = QAction(QIcon(icon_UW), "Divelog Form",
                                self.iface.mainWindow())
        self.actionUW.setWhatsThis("Divelog")
        self.actionUW.triggered.connect(self.runUW)

        icon_ANC = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconANC.png'))
        self.actionANC = QAction(QIcon(icon_ANC), "Anchor",
                                 self.iface.mainWindow())
        self.actionANC.setWhatsThis("Anchor")
        self.actionANC.triggered.connect(self.runANC)

        icon_ART = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'radar.png'))
        self.actionART = QAction(QIcon(icon_ART), "Artefact",
                                 self.iface.mainWindow())
        self.actionART.setWhatsThis("Artefact")
        self.actionART.triggered.connect(self.runART)

        icon_Pottery = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'pottery.png'))
        self.actionPottery = QAction(QIcon(icon_Pottery), "Pottery",
                                     self.iface.mainWindow())
        self.actionPottery.setWhatsThis("Pottery")
        self.actionPottery.triggered.connect(self.runPottery)

        self.dataToolButton.addActions([
            self.actionUW, self.actionART, self.actionANC, self.actionPottery
        ])
        self.dataToolButton.setDefaultAction(self.actionUW)

        self.toolBar.addWidget(self.dataToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the shipwreck
        # add Actions documentation
        self.ShipwreckToolButton = QToolButton(self.toolBar)
        icon_shipwreck = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'Shipwreck.png'))
        self.actionShipwreck = QAction(QIcon(icon_shipwreck), "Shipwreck",
                                       self.iface.mainWindow())
        self.actionShipwreck.setWhatsThis("Shipwreck")
        self.actionShipwreck.triggered.connect(self.runShipwreck)

        self.ShipwreckToolButton.addActions([self.actionShipwreck])
        self.ShipwreckToolButton.setDefaultAction(self.actionShipwreck)

        self.toolBar.addWidget(self.ShipwreckToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the documentation
        # add Actions documentation
        self.docToolButton = QToolButton(self.toolBar)
        self.docToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_imageViewer = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'photo.png'))
        self.actionimageViewer = QAction(QIcon(icon_imageViewer),
                                         "Media manager",
                                         self.iface.mainWindow())
        self.actionimageViewer.setWhatsThis("Media manager")
        self.actionimageViewer.triggered.connect(self.runImageViewer)

        icon_Directory_export = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'directoryExp.png'))
        self.actionImages_Directory_export = QAction(
            QIcon(icon_Directory_export), "Download image",
            self.iface.mainWindow())
        self.actionImages_Directory_export.setWhatsThis("Download image")
        self.actionImages_Directory_export.triggered.connect(
            self.runImages_directory_export)

        icon_excel_exp = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'excel-export.png'))
        self.actionexcelExp = QAction(QIcon(icon_excel_exp), "Download EXCEL",
                                      self.iface.mainWindow())
        self.actionexcelExp.setWhatsThis("Download EXCEL")
        self.actionexcelExp.triggered.connect(self.runPdfexp)

        self.docToolButton.addActions([
            self.actionexcelExp, self.actionimageViewer, self.actionexcelExp,
            self.actionImages_Directory_export
        ])

        self.docToolButton.setDefaultAction(self.actionimageViewer)

        #if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
        self.actionImages_Directory_export.setCheckable(True)
        self.actionexcelExp.setCheckable(True)
        self.actionimageViewer.setCheckable(True)

        self.toolBar.addWidget(self.docToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the plugin management

        self.manageToolButton = QToolButton(self.toolBar)
        self.manageToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_Con = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconConn.png'))
        self.actionConf = QAction(QIcon(icon_Con), "Config plugin",
                                  self.iface.mainWindow())
        self.actionConf.setWhatsThis("Config plugin")
        self.actionConf.triggered.connect(self.runConf)

        icon_Dbmanagment = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'backup.png'))
        self.actionDbmanagment = QAction(QIcon(icon_Dbmanagment),
                                         "Database manager",
                                         self.iface.mainWindow())
        self.actionDbmanagment.setWhatsThis("Database manager")
        self.actionDbmanagment.triggered.connect(self.runDbmanagment)

        icon_Info = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconInfo.png'))
        self.actionInfo = QAction(QIcon(icon_Info), "Plugin info",
                                  self.iface.mainWindow())
        self.actionInfo.setWhatsThis("Plugin info")
        self.actionInfo.triggered.connect(self.runInfo)

        self.manageToolButton.addActions(
            [self.actionConf, self.actionDbmanagment, self.actionInfo])
        self.manageToolButton.setDefaultAction(self.actionConf)

        self.toolBar.addWidget(self.manageToolButton)

        self.toolBar.addSeparator()

        # menu
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionUW)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionANC)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionART)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionPottery)

        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionShipwreck)

        self.iface.addPluginToMenu(
            "HFF - Survey Terrestrial Archaeological GIS Tools",
            self.actionSite)
        self.iface.addPluginToMenu(
            "HFF - Survey Terrestrial Archaeological GIS Tools",
            self.actionEamena)

        self.iface.addPluginToMenu("HFF - Media manager GIS Tools",
                                   self.actionimageViewer)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools",
                                   self.actionexcelExp)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools",
                                   self.actionImages_Directory_export)

        self.iface.addPluginToMenu("HFF - Config GIS Tools", self.actionConf)

        self.iface.addPluginToMenu("HFF - Config GIS Tools",
                                   self.actionDbmanagment)
        self.iface.addPluginToMenu("HFF - Info GIS Tools", self.actionInfo)

        # MENU
        self.menu = QMenu("HFF")
        self.menu.addActions([self.actionSite, self.actionEamena])

        self.menu.addSeparator()
        self.menu.addActions([self.actionShipwreck])
        self.menu.addSeparator()
        self.menu.addActions([
            self.actionUW, self.actionART, self.actionANC, self.actionPottery
        ])

        self.menu.addActions([
            self.actionimageViewer, self.actionexcelExp,
            self.actionImages_Directory_export
        ])
        self.menu.addSeparator()

        self.menu.addActions(
            [self.actionConf, self.actionDbmanagment, self.actionInfo])
        menuBar = self.iface.mainWindow().menuBar()
        menuBar.addMenu(self.menu)
コード例 #33
0
class ShapeTools(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.settingsDialog = None
        self.xyLineDialog = None
        self.geodesicDensifyDialog = None
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        self.previousLayer = None
        self.toolbar = self.iface.addToolBar('Shape Tools Toolbar')
        self.toolbar.setObjectName('ShapeToolsToolbar')
        self.provider = ShapeToolsProvider()
        # Initialize the plugin path directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        try:
            locale = QSettings().value("locale/userLocale", "en",
                                       type=str)[0:2]
        except Exception:
            locale = "en"
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'shapeTools_{}.qm'.format(locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        self.azDigitizerTool = AzDigitizerTool(self.iface)
        self.lineDigitizerTool = LineDigitizerTool(self.iface)

        # Initialize the create shape menu items
        menu = QMenu()
        # Initialize Create Arc Wedge tool
        icon = QIcon(self.plugin_dir + '/images/arc.png')
        self.createArcAction = menu.addAction(icon, tr('Create arc wedge'),
                                              self.createArc)
        self.createArcAction.setObjectName('stCreateArcWedge')
        icon = QIcon(self.plugin_dir + '/images/donut.png')
        self.createDonutAction = menu.addAction(icon, tr('Create donut'),
                                                self.createDonut)
        self.createDonutAction.setObjectName('stCreateDonut')
        icon = QIcon(self.plugin_dir + '/images/ellipse.png')
        self.createEllipseAction = menu.addAction(icon, tr('Create ellipse'),
                                                  self.createEllipse)
        self.createEllipseAction.setObjectName('stCreateEllipse')
        icon = QIcon(self.plugin_dir + '/images/rose.png')
        self.createEllipseRoseAction = menu.addAction(
            icon, tr('Create ellipse rose'), self.createEllipseRose)
        self.createEllipseRoseAction.setObjectName('stCreateEllipseRose')
        icon = QIcon(self.plugin_dir + '/images/epicycloid.png')
        self.createEpicycloidAction = menu.addAction(icon,
                                                     tr('Create epicycloid'),
                                                     self.createEpicycloid)
        self.createEpicycloidAction.setObjectName('stCreateEpicycloid')
        icon = QIcon(self.plugin_dir + '/images/heart.png')
        self.createHeartAction = menu.addAction(icon, tr('Create heart'),
                                                self.createHeart)
        self.createHeartAction.setObjectName('stCreateHeart')
        icon = QIcon(self.plugin_dir + '/images/hypocycloid.png')
        self.createHypocycloidAction = menu.addAction(icon,
                                                      tr('Create hypocycloid'),
                                                      self.createHypocycloid)
        self.createHypocycloidAction.setObjectName('stCreateHypocycloid')
        icon = QIcon(self.plugin_dir + '/images/line.png')
        self.createLOBAction = menu.addAction(icon,
                                              tr('Create line of bearing'),
                                              self.createLOB)
        self.createLOBAction.setObjectName('stCreateLineOfBearing')
        icon = QIcon(self.plugin_dir + '/images/pie.png')
        self.createPieAction = menu.addAction(icon, tr('Create pie wedge'),
                                              self.createPie)
        self.createPieAction.setObjectName('stCreatePie')
        icon = QIcon(self.plugin_dir + '/images/polyfoil.png')
        self.createPolyfoilAction = menu.addAction(icon, tr('Create polyfoil'),
                                                   self.createPolyfoil)
        self.createPolyfoilAction.setObjectName('stCreatePolyfoil')
        icon = QIcon(self.plugin_dir + '/images/polygon.png')
        self.createPolygonAction = menu.addAction(icon, tr('Create polygon'),
                                                  self.createPolygon)
        self.createPolygonAction.setObjectName('stCreatePolygon')
        icon = QIcon(self.plugin_dir + '/images/star.png')
        self.createStarAction = menu.addAction(icon, tr('Create star'),
                                               self.createStar)
        self.createStarAction.setObjectName('stCreateStar')
        # Add the shape creation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/shapes.png')
        self.createShapesAction = QAction(icon, tr('Create shapes'),
                                          self.iface.mainWindow())
        self.createShapesAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.createShapesAction)
        # Add the shape creation tools to the toolbar
        self.createShapeButton = QToolButton()
        self.createShapeButton.setMenu(menu)
        self.createShapeButton.setDefaultAction(self.createDonutAction)
        self.createShapeButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.createShapeButton.triggered.connect(self.createShapeTriggered)
        self.createShapeToolbar = self.toolbar.addWidget(
            self.createShapeButton)

        # Initialize the XY to Line menu item
        icon = QIcon(self.plugin_dir + '/images/xyline.png')
        self.xyLineAction = QAction(icon, tr('XY to line'),
                                    self.iface.mainWindow())
        self.xyLineAction.setObjectName('stXYtoLine')
        self.xyLineAction.triggered.connect(self.xyLineTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.xyLineAction)
        self.toolbar.addAction(self.xyLineAction)

        # Initialize the Geodesic Densifier menu item
        icon = QIcon(self.plugin_dir + '/images/geodesicDensifier.png')
        self.geodesicDensifyAction = QAction(icon,
                                             tr('Geodesic shape densifier'),
                                             self.iface.mainWindow())
        self.geodesicDensifyAction.setObjectName('stGeodesicDensifier')
        self.geodesicDensifyAction.triggered.connect(self.geodesicDensifyTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicDensifyAction)
        self.toolbar.addAction(self.geodesicDensifyAction)

        # Initialize the Geodesic decimation menu items
        menu = QMenu()
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.png')
        self.lineDecimateAction = menu.addAction(icon,
                                                 tr('Geodesic line decimate'),
                                                 self.lineDecimateTool)
        self.lineDecimateAction.setObjectName('stGeodesicLineDecimate')
        icon = QIcon(self.plugin_dir + '/images/geodesicPointDecimate.png')
        self.pointDecimateAction = menu.addAction(
            icon, tr('Geodesic point decimate'), self.pointDecimateTool)
        self.pointDecimateAction.setObjectName('stGeodesicPointDecimate')
        # Add the decimation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.png')
        self.simplifyGeomAction = QAction(
            icon, tr('Geodesic geometry simplification'),
            self.iface.mainWindow())
        self.simplifyGeomAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.simplifyGeomAction)
        # Add the shape creation tools to the toolbar
        self.simplifyButton = QToolButton()
        self.simplifyButton.setMenu(menu)
        self.simplifyButton.setDefaultAction(self.lineDecimateAction)
        self.simplifyButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.simplifyButton.triggered.connect(self.simplifyTriggered)
        self.simplifyToolbar = self.toolbar.addWidget(self.simplifyButton)

        # Initialize the Geodesic line break menu item
        icon = QIcon(self.plugin_dir + '/images/idlbreak.png')
        self.geodesicLineBreakAction = QAction(
            icon, tr('Geodesic line break at -180,180'),
            self.iface.mainWindow())
        self.geodesicLineBreakAction.setObjectName('stGeodesicLineBreak')
        self.geodesicLineBreakAction.triggered.connect(
            self.geodesicLineBreakTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicLineBreakAction)
        self.toolbar.addAction(self.geodesicLineBreakAction)

        # Initialize Geodesic Measure Tool
        self.geodesicMeasureTool = GeodesicMeasureTool(self.iface,
                                                       self.iface.mainWindow())
        icon = QIcon(self.plugin_dir + '/images/measure.png')
        self.measureAction = QAction(icon, tr('Geodesic measure tool'),
                                     self.iface.mainWindow())
        self.measureAction.setObjectName('stGeodesicMeasureTool')
        self.measureAction.triggered.connect(self.measureTool)
        self.measureAction.setCheckable(True)
        self.iface.addPluginToVectorMenu('Shape Tools', self.measureAction)
        self.toolbar.addAction(self.measureAction)

        # Initialize Geodesic Measurement layer
        icon = QIcon(self.plugin_dir + '/images/measureLine.png')
        self.measureLayerAction = QAction(icon,
                                          tr('Geodesic measurement layer'),
                                          self.iface.mainWindow())
        self.measureLayerAction.setObjectName('stGeodesicLineBreak')
        self.measureLayerAction.triggered.connect(self.measureLayerTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.measureLayerAction)
        self.toolbar.addAction(self.measureLayerAction)

        menu = QMenu()
        # Initialize Geodesic transformation tool
        icon = QIcon(self.plugin_dir + '/images/transformShape.png')
        self.transformationsAction = menu.addAction(
            icon, tr('Geodesic transformations'), self.transformTool)
        self.transformationsAction.setObjectName('stGeodesicTransformations')

        icon = QIcon(self.plugin_dir + '/images/flip.png')
        self.flipRotateAction = menu.addAction(icon,
                                               tr('Geodesic flip and rotate'),
                                               self.flipRotateTool)
        self.flipRotateAction.setObjectName('stGeodesicFlipRotate')

        icon = QIcon(self.plugin_dir + '/images/flipHorizontal.png')
        self.flipHorizontalAction = menu.addAction(icon, tr('Flip horizontal'),
                                                   self.flipHorizontalTool)
        self.flipHorizontalAction.setObjectName('stGeodesicFlipHorizontal')
        self.flipHorizontalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/flipVertical.png')
        self.flipVerticalAction = menu.addAction(icon, tr('Flip vertical'),
                                                 self.flipVerticalTool)
        self.flipVerticalAction.setObjectName('stGeodesicFlipVertical')
        self.flipVerticalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotate180.png')
        self.rotate180Action = menu.addAction(icon, tr('Rotate 180\xb0'),
                                              self.rotate180Tool)
        self.rotate180Action.setObjectName('stGeodesicRotate180')
        self.rotate180Action.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotatecw.png')
        self.rotate90CWAction = menu.addAction(icon, tr('Rotate 90\xb0 CW'),
                                               self.rotate90CWTool)
        self.rotate90CWAction.setObjectName('stGeodesicRotate90CW')
        self.rotate90CWAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotateccw.png')
        self.rotate90CCWAction = menu.addAction(icon, tr('Rotate 90\xb0 CCW'),
                                                self.rotate90CCWTool)
        self.rotate90CCWAction.setObjectName('stGeodesicRotate90CCW')
        self.rotate90CCWAction.setEnabled(False)
        self.transformsAction = QAction(icon, tr('Geodesic transforms'),
                                        self.iface.mainWindow())
        self.transformsAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools', self.transformsAction)

        self.transformationButton = QToolButton()
        self.transformationButton.setMenu(menu)
        self.transformationButton.setDefaultAction(self.transformationsAction)
        self.transformationButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.transformationButton.triggered.connect(self.toolButtonTriggered)
        self.tranformToolbar = self.toolbar.addWidget(
            self.transformationButton)

        # Initialize the Azimuth Distance Digitize function
        icon = QIcon(self.plugin_dir + '/images/dazdigitize.png')
        self.digitizeAction = QAction(icon, tr('Azimuth distance digitizer'),
                                      self.iface.mainWindow())
        self.digitizeAction.setObjectName('stAzDistanceDigitizer')
        self.digitizeAction.triggered.connect(self.setShowAzDigitizerTool)
        self.digitizeAction.setCheckable(True)
        self.digitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools', self.digitizeAction)
        self.toolbar.addAction(self.digitizeAction)

        # Initialize the multi point azimuth Digitize function
        icon = QIcon(self.plugin_dir + '/images/linedigitize.png')
        self.lineDigitizeAction = QAction(
            icon, tr('Azimuth distance sequence digitizer'),
            self.iface.mainWindow())
        self.lineDigitizeAction.setObjectName('stLineDigitizer')
        self.lineDigitizeAction.triggered.connect(self.setShowLineDigitizeTool)
        self.lineDigitizeAction.setCheckable(True)
        self.lineDigitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools',
                                         self.lineDigitizeAction)
        self.toolbar.addAction(self.lineDigitizeAction)

        # Settings
        icon = QIcon(self.plugin_dir + '/images/settings.png')
        self.settingsAction = QAction(icon, tr('Settings'),
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('shapeToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToVectorMenu('Shape Tools', self.settingsAction)

        # Help
        icon = QIcon(self.plugin_dir + '/images/help.png')
        self.helpAction = QAction(icon, tr('Shape Tools help'),
                                  self.iface.mainWindow())
        self.helpAction.setObjectName('shapeToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToVectorMenu('Shape Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableTools()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)

    def unsetTool(self, tool):
        try:
            if not isinstance(tool, GeodesicMeasureTool):
                self.measureAction.setChecked(False)
                self.geodesicMeasureTool.endInteractiveLine()
            if not isinstance(tool, AzDigitizerTool):
                self.digitizeAction.setChecked(False)
            if not isinstance(tool, LineDigitizerTool):
                self.lineDigitizeAction.setChecked(False)
        except Exception:
            pass

    def unload(self):
        self.canvas.unsetMapTool(self.azDigitizerTool)
        self.canvas.unsetMapTool(self.lineDigitizerTool)

        # remove from menu
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.createShapesAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.xyLineAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicDensifyAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.simplifyGeomAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicLineBreakAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.measureAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.measureLayerAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.transformsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.digitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.lineDigitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.settingsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.helpAction)
        # Remove from toolbar
        self.iface.removeToolBarIcon(self.createShapeToolbar)
        self.iface.removeToolBarIcon(self.xyLineAction)
        self.iface.removeToolBarIcon(self.geodesicDensifyAction)
        self.iface.removeToolBarIcon(self.simplifyToolbar)
        self.iface.removeToolBarIcon(self.geodesicLineBreakAction)
        self.iface.removeToolBarIcon(self.measureAction)
        self.iface.removeToolBarIcon(self.measureLayerAction)
        self.iface.removeToolBarIcon(self.transformationsAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        self.iface.removeToolBarIcon(self.lineDigitizeAction)
        self.iface.removeToolBarIcon(self.tranformToolbar)
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        # remove the toolbar
        del self.toolbar

        QgsApplication.processingRegistry().removeProvider(self.provider)

    def toolButtonTriggered(self, action):
        self.transformationButton.setDefaultAction(action)

    def createShapeTriggered(self, action):
        self.createShapeButton.setDefaultAction(action)

    def simplifyTriggered(self, action):
        self.simplifyButton.setDefaultAction(action)

    def setShowAzDigitizerTool(self):
        self.digitizeAction.setChecked(True)
        self.canvas.setMapTool(self.azDigitizerTool)

    def setShowLineDigitizeTool(self):
        self.lineDigitizeAction.setChecked(True)
        self.canvas.setMapTool(self.lineDigitizerTool)

    def xyLineTool(self):
        processing.execAlgorithmDialog('shapetools:xy2line', {})

    def geodesicDensifyTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicdensifier', {})

    def pointDecimateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicpointdecimate', {})

    def lineDecimateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesiclinedecimate', {})

    def geodesicLineBreakTool(self):
        processing.execAlgorithmDialog('shapetools:linebreak', {})

    def measureTool(self):
        self.measureAction.setChecked(True)
        self.canvas.setMapTool(self.geodesicMeasureTool)

    def createArc(sefl):
        processing.execAlgorithmDialog('shapetools:createarc', {})

    def createDonut(sefl):
        processing.execAlgorithmDialog('shapetools:createdonut', {})

    def createEllipse(sefl):
        processing.execAlgorithmDialog('shapetools:createellipse', {})

    def createEllipseRose(sefl):
        processing.execAlgorithmDialog('shapetools:createrose', {})

    def createEpicycloid(sefl):
        processing.execAlgorithmDialog('shapetools:createepicycloid', {})

    def createHeart(sefl):
        processing.execAlgorithmDialog('shapetools:createheart', {})

    def createHypocycloid(sefl):
        processing.execAlgorithmDialog('shapetools:createhypocycloid', {})

    def createLOB(sefl):
        processing.execAlgorithmDialog('shapetools:createlob', {})

    def createPie(sefl):
        processing.execAlgorithmDialog('shapetools:createpie', {})

    def createPolyfoil(sefl):
        processing.execAlgorithmDialog('shapetools:createpolyfoil', {})

    def createPolygon(sefl):
        processing.execAlgorithmDialog('shapetools:createpolygon', {})

    def createStar(sefl):
        processing.execAlgorithmDialog('shapetools:createstar', {})

    def measureLayerTool(self):
        processing.execAlgorithmDialog('shapetools:measurelayer', {})

    def transformTool(self):
        processing.execAlgorithmDialog('shapetools:geodesictransformations',
                                       {})

    def flipRotateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicflip', {})

    def flipHorizontalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 0)

    def flipVerticalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 1)

    def rotate180Tool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 2)

    def rotate90CWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 3)

    def rotate90CCWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 4)

    def settings(self):
        if self.settingsDialog is None:
            self.settingsDialog = SettingsWidget(self.iface,
                                                 self.iface.mainWindow())
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(self.plugin_dir + '/index.html').toString()
        webbrowser.open(url, new=2)

    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if self.previousLayer is not None:
            try:
                self.previousLayer.editingStarted.disconnect(
                    self.layerEditingChanged)
            except Exception:
                pass
            try:
                self.previousLayer.editingStopped.disconnect(
                    self.layerEditingChanged)
            except Exception:
                pass
        self.previousLayer = None
        if layer is not None:
            if isinstance(layer, QgsVectorLayer):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)
                self.previousLayer = layer
        self.enableTools()

    def layerEditingChanged(self):
        self.enableTools()

    def enableTools(self):
        self.digitizeAction.setEnabled(False)
        self.lineDigitizeAction.setEnabled(False)
        self.flipHorizontalAction.setEnabled(False)
        self.flipVerticalAction.setEnabled(False)
        self.rotate180Action.setEnabled(False)
        self.rotate90CWAction.setEnabled(False)
        self.rotate90CCWAction.setEnabled(False)
        layer = self.iface.activeLayer()

        if not layer or not layer.isValid() or (
                layer.type() !=
                QgsMapLayer.VectorLayer) or not layer.isEditable():
            return
        wkbtype = layer.wkbType()
        geomtype = QgsWkbTypes.geometryType(wkbtype)
        self.lineDigitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.PointGeometry or geomtype == QgsWkbTypes.LineGeometry:
            self.digitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.LineGeometry or geomtype == QgsWkbTypes.PolygonGeometry:
            self.flipHorizontalAction.setEnabled(True)
            self.flipVerticalAction.setEnabled(True)
            self.rotate180Action.setEnabled(True)
            self.rotate90CWAction.setEnabled(True)
            self.rotate90CCWAction.setEnabled(True)
コード例 #34
0
class HffPlugin_s(object):
    HOME = os.environ['HFF_HOME']

    PARAMS_DICT = {
        'SERVER': '',
        'HOST': '',
        'DATABASE': '',
        'PASSWORD': '',
        'PORT': '',
        'USER': '',
        'THUMB_PATH': '',
        'THUMB_RESIZE': '',
        'EXPERIMENTAL': ''
    }

    path_rel = os.path.join(os.sep, HOME, 'HFF_DB_folder', 'config.cfg')
    conf = open(path_rel, "rb+")
    data = conf.read()
    text = (b'THUMB_RESIZE')

    if text in data:
        pass
    else:
        conf.seek(-3, 2)
        conf.read(1)
        conf.write(b"','THUMB_RESIZE' : 'insert path for the image resized'}")

    conf.close()
    PARAMS_DICT = eval(data)

    def __init__(self, iface):
        self.iface = iface
        userPluginPath = os.path.dirname(__file__)
        systemPluginPath = QgsApplication.prefixPath() + "/python/plugins/HFF"

        # overrideLocale = QgsSettings().value("locale/overrideFlag", QVariant)  # .toBool()
        # if not overrideLocale:
        # localeFullName = QLocale.system().name()
        # else:
        # localeFullName = QgsSettings().value("locale/userLocale", QVariant)  # .toString()

        # if QFileInfo(userPluginPath).exists():
        # translationPath = userPluginPath + "/i18n/hff_system__plugin_" + localeFullName + ".qm"
        # else:
        # translationPath = systemPluginPath + "/i18n/hff_system__plugin_" + localeFullName + ".qm"

        # self.localePath = translationPath
        # if QFileInfo(self.localePath).exists():
        # self.translator = QTranslator()
        # self.translator.load(self.localePath)
        # QCoreApplication.installTranslator(self.translator)

    def initGui(self):

        settings = QgsSettings()
        icon_paius = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'hfflogo.png'))
        self.action = QAction(QIcon(icon_paius), "HFF Main Panel",
                              self.iface.mainWindow())
        self.action.triggered.connect(self.showHideDockWidget)

        # dock widget
        self.dockWidget = HffPluginDialog(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget)

        # TOOLBAR
        self.toolBar = self.iface.addToolBar("HFF")
        self.toolBar.setObjectName("HFF")
        self.toolBar.addAction(self.action)

        self.dataToolButton = QToolButton(self.toolBar)
        self.dataToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        ######  Section dedicated to the basic data entry
        # add Actions data
        self.siteToolButton = QToolButton(self.toolBar)
        self.siteToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        icon_site = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconSite.png'))
        self.actionSite = QAction(QIcon(icon_site), "Site",
                                  self.iface.mainWindow())
        self.actionSite.setWhatsThis("Site")
        self.actionSite.triggered.connect(self.runSite)

        icon_eamena = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'eamena.jpg'))
        self.actionEamena = QAction(QIcon(icon_eamena), "Eamena",
                                    self.iface.mainWindow())
        self.actionEamena.setWhatsThis("Eamena")
        self.actionEamena.triggered.connect(self.runEamena)

        icon_eamena_archaeology = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'eamena.jpg'))

        self.siteToolButton.addActions([self.actionSite, self.actionEamena])
        self.siteToolButton.setDefaultAction(self.actionSite)

        self.toolBar.addWidget(self.siteToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the UnderWater data entry
        # add Actions data
        icon_UW = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'snorkel.png'))
        self.actionUW = QAction(QIcon(icon_UW), "Divelog Form",
                                self.iface.mainWindow())
        self.actionUW.setWhatsThis("Divelog")
        self.actionUW.triggered.connect(self.runUW)

        icon_ANC = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconANC.png'))
        self.actionANC = QAction(QIcon(icon_ANC), "Anchor",
                                 self.iface.mainWindow())
        self.actionANC.setWhatsThis("Anchor")
        self.actionANC.triggered.connect(self.runANC)

        icon_ART = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'radar.png'))
        self.actionART = QAction(QIcon(icon_ART), "Artefact",
                                 self.iface.mainWindow())
        self.actionART.setWhatsThis("Artefact")
        self.actionART.triggered.connect(self.runART)

        icon_Pottery = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'pottery.png'))
        self.actionPottery = QAction(QIcon(icon_Pottery), "Pottery",
                                     self.iface.mainWindow())
        self.actionPottery.setWhatsThis("Pottery")
        self.actionPottery.triggered.connect(self.runPottery)

        self.dataToolButton.addActions([
            self.actionUW, self.actionART, self.actionANC, self.actionPottery
        ])
        self.dataToolButton.setDefaultAction(self.actionUW)

        self.toolBar.addWidget(self.dataToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the shipwreck
        # add Actions documentation
        self.ShipwreckToolButton = QToolButton(self.toolBar)
        icon_shipwreck = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'Shipwreck.png'))
        self.actionShipwreck = QAction(QIcon(icon_shipwreck), "Shipwreck",
                                       self.iface.mainWindow())
        self.actionShipwreck.setWhatsThis("Shipwreck")
        self.actionShipwreck.triggered.connect(self.runShipwreck)

        self.ShipwreckToolButton.addActions([self.actionShipwreck])
        self.ShipwreckToolButton.setDefaultAction(self.actionShipwreck)

        self.toolBar.addWidget(self.ShipwreckToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the documentation
        # add Actions documentation
        self.docToolButton = QToolButton(self.toolBar)
        self.docToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_imageViewer = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'photo.png'))
        self.actionimageViewer = QAction(QIcon(icon_imageViewer),
                                         "Media manager",
                                         self.iface.mainWindow())
        self.actionimageViewer.setWhatsThis("Media manager")
        self.actionimageViewer.triggered.connect(self.runImageViewer)

        icon_Directory_export = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'directoryExp.png'))
        self.actionImages_Directory_export = QAction(
            QIcon(icon_Directory_export), "Download image",
            self.iface.mainWindow())
        self.actionImages_Directory_export.setWhatsThis("Download image")
        self.actionImages_Directory_export.triggered.connect(
            self.runImages_directory_export)

        icon_excel_exp = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'excel-export.png'))
        self.actionexcelExp = QAction(QIcon(icon_excel_exp), "Download EXCEL",
                                      self.iface.mainWindow())
        self.actionexcelExp.setWhatsThis("Download EXCEL")
        self.actionexcelExp.triggered.connect(self.runPdfexp)

        self.docToolButton.addActions([
            self.actionexcelExp, self.actionimageViewer, self.actionexcelExp,
            self.actionImages_Directory_export
        ])

        self.docToolButton.setDefaultAction(self.actionimageViewer)

        #if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
        self.actionImages_Directory_export.setCheckable(True)
        self.actionexcelExp.setCheckable(True)
        self.actionimageViewer.setCheckable(True)

        self.toolBar.addWidget(self.docToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the plugin management

        self.manageToolButton = QToolButton(self.toolBar)
        self.manageToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_Con = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconConn.png'))
        self.actionConf = QAction(QIcon(icon_Con), "Config plugin",
                                  self.iface.mainWindow())
        self.actionConf.setWhatsThis("Config plugin")
        self.actionConf.triggered.connect(self.runConf)

        icon_Dbmanagment = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'backup.png'))
        self.actionDbmanagment = QAction(QIcon(icon_Dbmanagment),
                                         "Database manager",
                                         self.iface.mainWindow())
        self.actionDbmanagment.setWhatsThis("Database manager")
        self.actionDbmanagment.triggered.connect(self.runDbmanagment)

        icon_Info = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconInfo.png'))
        self.actionInfo = QAction(QIcon(icon_Info), "Plugin info",
                                  self.iface.mainWindow())
        self.actionInfo.setWhatsThis("Plugin info")
        self.actionInfo.triggered.connect(self.runInfo)

        self.manageToolButton.addActions(
            [self.actionConf, self.actionDbmanagment, self.actionInfo])
        self.manageToolButton.setDefaultAction(self.actionConf)

        self.toolBar.addWidget(self.manageToolButton)

        self.toolBar.addSeparator()

        # menu
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionUW)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionANC)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionART)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionPottery)

        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools",
                                   self.actionShipwreck)

        self.iface.addPluginToMenu(
            "HFF - Survey Terrestrial Archaeological GIS Tools",
            self.actionSite)
        self.iface.addPluginToMenu(
            "HFF - Survey Terrestrial Archaeological GIS Tools",
            self.actionEamena)

        self.iface.addPluginToMenu("HFF - Media manager GIS Tools",
                                   self.actionimageViewer)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools",
                                   self.actionexcelExp)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools",
                                   self.actionImages_Directory_export)

        self.iface.addPluginToMenu("HFF - Config GIS Tools", self.actionConf)

        self.iface.addPluginToMenu("HFF - Config GIS Tools",
                                   self.actionDbmanagment)
        self.iface.addPluginToMenu("HFF - Info GIS Tools", self.actionInfo)

        # MENU
        self.menu = QMenu("HFF")
        self.menu.addActions([self.actionSite, self.actionEamena])

        self.menu.addSeparator()
        self.menu.addActions([self.actionShipwreck])
        self.menu.addSeparator()
        self.menu.addActions([
            self.actionUW, self.actionART, self.actionANC, self.actionPottery
        ])

        self.menu.addActions([
            self.actionimageViewer, self.actionexcelExp,
            self.actionImages_Directory_export
        ])
        self.menu.addSeparator()

        self.menu.addActions(
            [self.actionConf, self.actionDbmanagment, self.actionInfo])
        menuBar = self.iface.mainWindow().menuBar()
        menuBar.addMenu(self.menu)

    ##
    def runSite(self):
        pluginGui = hff_system__Site(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runEamena(self):
        pluginGui = Eamena(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runUW(self):
        pluginGui = hff_system__UW(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runANC(self):
        pluginGui = hff_system__ANC(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runART(self):
        pluginGui = hff_system__ART(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runPottery(self):
        pluginGui = hff_system__Pottery(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runShipwreck(self):
        pluginGui = hff_system__Shipwreck(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runConf(self):
        pluginConfGui = HFF_systemDialog_Config()
        pluginConfGui.show()
        self.pluginGui = pluginConfGui  # save

    def runInfo(self):
        pluginInfoGui = HFF_systemDialog_Info()
        pluginInfoGui.show()
        self.pluginGui = pluginInfoGui  # save

    def runImageViewer(self):
        pluginImageView = Main()
        pluginImageView.show()
        self.pluginGui = pluginImageView  # save

    def runImages_directory_export(self):
        pluginImage_directory_export = hff_system__Images_directory_export()
        pluginImage_directory_export.show()
        self.pluginGui = pluginImage_directory_export  # save

    def runDbmanagment(self):
        pluginDbmanagment = hff_system__dbmanagment(self.iface)
        pluginDbmanagment.show()
        self.pluginGui = pluginDbmanagment  # save

    def runPdfexp(self):
        pluginPdfexp = hff_system__excel_export(self.iface)
        pluginPdfexp.show()
        self.pluginGui = pluginPdfexp  # save

    def unload(self):
        # Remove the plugin

        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools",
                                    self.actionUW)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools",
                                    self.actionANC)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools",
                                    self.actionART)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools",
                                    self.actionPottery)

        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools",
                                    self.actionShipwreck)

        self.iface.removePluginMenu(
            "HFF - Survey Terrestrial Archaeological GIS Tools",
            self.actionSite)
        self.iface.removePluginMenu(
            "HFF - Survey Terrestrial Archaeological GIS Tools",
            self.actionEamena)

        self.iface.removePluginMenu("HFF - Media manager GIS Tools",
                                    self.actionimageViewer)
        self.iface.removePluginMenu("HFF - Media manager GIS Tools",
                                    self.actionImages_Directory_export)
        self.iface.removePluginMenu("HFF - Media manager GIS Tools",
                                    self.actionexcelExp)

        self.iface.removePluginMenu("HFF - Config GIS Tools", self.actionConf)

        self.iface.removePluginMenu("HFF - Info GIS Tools", self.actionInfo)
        self.iface.removePluginMenu("HFF - Config GIS Tools",
                                    self.actionDbmanagment)

        self.iface.removeToolBarIcon(self.actionUW)
        self.iface.removeToolBarIcon(self.actionART)
        self.iface.removeToolBarIcon(self.actionANC)
        self.iface.removeToolBarIcon(self.actionPottery)

        self.iface.removeToolBarIcon(self.actionShipwreck)

        self.iface.removeToolBarIcon(self.actionSite)

        self.iface.removeToolBarIcon(self.actionimageViewer)
        self.iface.removeToolBarIcon(self.actionImages_Directory_export)
        self.iface.removeToolBarIcon(self.actionexcelExp)

        self.iface.removeToolBarIcon(self.actionConf)

        self.iface.removeToolBarIcon(self.actionInfo)
        self.iface.removeToolBarIcon(self.actionDbmanagment)

        self.dockWidget.setVisible(False)
        self.iface.removeDockWidget(self.dockWidget)

        # remove tool bar
        del self.toolBar

    def showHideDockWidget(self):
        if self.dockWidget.isVisible():
            self.dockWidget.hide()
        else:
            self.dockWidget.show()
コード例 #35
0
    def addLayer(self, index, old=None, addToMap=True):
        item = index.data(role=Qt.UserRole)
        if not isinstance(item, LayerItem):
            return
        if not self.plugin.setLoading(True):
            return
        addedData = []
        if isinstance(item, VectorItem):
            connector = self.getConnector()
            self.plugin.msgBar = ProgressMessageBar(self.iface, self.tr("Downloading layer '%s'...")%item.name, connector=connector)
            self.plugin.msgBar.setValue(10)
            connector.downloadingProgress.connect(self.plugin.updateDownloadProgress)
            data = connector.diviGetLayerFeatures(item.id)
            layers = []
            if data:
                permissions = connector.getUserPermission(item.id, 'layer')
                self.plugin.msgBar.setBoundries(50, 50)
                #Disable rendering for changing symbology
                self.iface.mapCanvas().setRenderFlag(False)
                layers = self.plugin.addLayer(data['features'], item, permissions, addToMap=addToMap)
                for layer in layers:
                    #Set symbols based on layer geometry type
                    item.setQgisStyle(layer)
                    self.iface.layerTreeView().refreshLayerSymbology(layer.id())
                self.iface.mapCanvas().setRenderFlag(True)
                addedData.extend( layers )
                item.items.extend( addedData )
            self.plugin.msgBar.setValue(100)
            aborted = self.plugin.msgBar.aborted
            self.plugin.msgBar.close()
            self.plugin.msgBar = None
            if aborted:
                # fix_print_with_import
                print('Aborted')
            elif not layers:
                #User can select geometry type in message bar
                widget = self.iface.messageBar().createMessage(
                    self.tr("Warning"),
                    self.tr(u"Layer '%s' is empty. To open it in QGIS you need to select geometry type.") % item.name
                )
                button = QToolButton(widget)
                button.setText(self.tr("Add layer as..."))
                button.setPopupMode(QToolButton.InstantPopup)
                menu = QMenu(button)
                def load_layer_as(geom_type):
                    self.plugin.loadLayerType(item = item, geom_type = geom_type)
                    self.iface.messageBar().clearWidgets()
                menu.addAction(QgsApplication.getThemeIcon('/mIconPointLayer.svg'), self.tr('Points'), lambda: load_layer_as(geom_type='MultiPoint'))
                menu.addAction(QgsApplication.getThemeIcon('/mIconLineLayer.svg'), self.tr('Linestring'), lambda: load_layer_as(geom_type='MultiLineString'))
                menu.addAction(QgsApplication.getThemeIcon('/mIconPolygonLayer.svg'), self.tr('Polygons'), lambda: load_layer_as(geom_type='MultiPolygon'))
                button.setMenu( menu )
                widget.layout().addWidget(button)
                self.iface.messageBar().pushWidget(widget, Qgis.Warning)

        elif isinstance(item, TableItem):
            if Qgis.QGIS_VERSION_INT < 21400:
                self.iface.messageBar().pushMessage('DIVI',
                    self.tr(u'QGIS 2.14 or later is required for loading DIVI tables.'),
                    Qgis.Critical,
                    duration = 3
                )
            else:
                self.plugin.msgBar = ProgressMessageBar(self.iface, self.tr("Downloading table '%s'...")%item.name)
                self.plugin.msgBar.setValue(10)
                connector = self.getConnector()
                connector.downloadingProgress.connect(self.plugin.updateDownloadProgress)
                data = connector.diviGetTableRecords(item.id)
                if data:
                    permissions = connector.getUserPermission(item.id, 'table')
                    self.plugin.msgBar.setBoundries(50, 50)
                    addedData.append( self.plugin.addTable(data['header'], data['data'], item, permissions, addToMap=addToMap) )
                    item.items.extend( addedData )
                self.plugin.msgBar.setValue(100)
                self.plugin.msgBar.close()
                self.plugin.msgBar = None
        elif isinstance(item, RasterItem):
            if Qgis.QGIS_VERSION_INT < 21800:
                self.iface.messageBar().pushMessage('DIVI',
                    self.tr(u'QGIS 2.18 or later is required for loading DIVI rasters.'),
                    Qgis.Critical,
                    duration = 3
                )
            else:
                uri = item.getUri(self.token)
                uri = uri.replace("b'", "").replace("'", "")
                QgsMessageLog.logMessage( uri, 'DIVI')
                r = QgsRasterLayer(uri, item.name, 'wms')
                r.setCustomProperty('DiviId', item.id)
                if item.extent is not None:
                    #Set extent for raster layer
                    bbox = self.transform2mercator.transformBoundingBox( QgsRectangle(
                            item.extent['st_xmin'],
                            item.extent['st_ymin'],
                            item.extent['st_xmax'],
                            item.extent['st_ymax']
                        ))
                    r.setExtent( bbox )
                addedData.append( r )
                item.items.extend( addedData )
                if addToMap:
                    QgsProject.instance().addMapLayer(r)
        elif isinstance(item, WmsItem):
            uri = item.getUri()
            QgsMessageLog.logMessage( uri, 'DIVI')
            r = QgsRasterLayer(uri, item.name, 'wms')
            r.setCustomProperty('DiviId', item.id)
            addedData.append( r )
            item.items.extend( addedData )
            if addToMap:
                QgsProject.instance().addMapLayer(r)
        elif isinstance(item, BasemapItem):
            uri = item.getUri()
            QgsMessageLog.logMessage( uri, 'DIVI')
            r = QgsRasterLayer(uri, item.name, 'wms')
            r.setCustomProperty('DiviId', item.id)
            addedData.append( r )
            item.items.extend( addedData )
            if addToMap:
                QgsProject.instance().addMapLayer(r)
        else:
            return
        index.model().dataChanged.emit(index.parent().parent(), index)
        self.plugin.setLoading(False)
        return addedData
コード例 #36
0
    def initWidgets(self):
        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                self.grpAdvanced.show()
                break

        widget_context = QgsProcessingParameterWidgetContext()
        if iface is not None:
            widget_context.setMapCanvas(iface.mapCanvas())
        if isinstance(self.alg, QgsProcessingModelAlgorithm):
            widget_context.setModel(self.alg)

        # Create widgets and put them in layouts
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            if param.isDestination():
                continue
            else:
                wrapper = WidgetWrapperFactory.create_wrapper(
                    param, self.parent)
                wrapper.setWidgetContext(widget_context)
                wrapper.registerProcessingContextGenerator(
                    self.context_generator)
                self.wrappers[param.name()] = wrapper

                # For compatibility with 3.x API, we need to check whether the wrapper is
                # the deprecated WidgetWrapper class. If not, it's the newer
                # QgsAbstractProcessingParameterWidgetWrapper class
                # TODO QGIS 4.0 - remove
                is_python_wrapper = issubclass(wrapper.__class__,
                                               WidgetWrapper)
                if not is_python_wrapper:
                    widget = wrapper.createWrappedWidget(
                        self.processing_context)
                else:
                    widget = wrapper.widget

                if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
                    # don't show the input/output parameter widgets in in-place mode
                    # we still need to CREATE them, because other wrappers may need to interact
                    # with them (e.g. those parameters which need the input layer for field
                    # selections/crs properties/etc)
                    continue

                if widget is not None:
                    if is_python_wrapper:
                        widget.setToolTip(param.toolTip())

                    if isinstance(param, QgsProcessingParameterFeatureSource):
                        layout = QHBoxLayout()
                        layout.setSpacing(6)
                        layout.setMargin(0)
                        layout.addWidget(widget)
                        button = QToolButton()
                        icon = QIcon(
                            os.path.join(pluginPath, 'images', 'iterate.png'))
                        button.setIcon(icon)
                        button.setSizePolicy(QSizePolicy.Fixed,
                                             QSizePolicy.Expanding)
                        button.setToolTip(
                            self.
                            tr('Iterate over this layer, creating a separate output for every feature in the layer'
                               ))
                        button.setCheckable(True)
                        layout.addWidget(button)
                        layout.setAlignment(button, Qt.AlignTop)
                        self.iterateButtons[param.name()] = button
                        button.toggled.connect(self.buttonToggled)
                        widget = QWidget()
                        widget.setLayout(layout)

                    label = None
                    if not is_python_wrapper:
                        label = wrapper.createWrappedLabel()
                    else:
                        label = wrapper.label

                    if label is not None:
                        if param.flags(
                        ) & QgsProcessingParameterDefinition.FlagAdvanced:
                            self.layoutAdvanced.addWidget(label)
                        else:
                            self.layoutMain.insertWidget(
                                self.layoutMain.count() - 2, label)
                    elif is_python_wrapper:
                        desc = param.description()
                        if isinstance(param, QgsProcessingParameterExtent):
                            desc += self.tr(' (xmin, xmax, ymin, ymax)')
                        if isinstance(param, QgsProcessingParameterPoint):
                            desc += self.tr(' (x, y)')
                        if param.flags(
                        ) & QgsProcessingParameterDefinition.FlagOptional:
                            desc += self.tr(' [optional]')
                        widget.setText(desc)
                    if param.flags(
                    ) & QgsProcessingParameterDefinition.FlagAdvanced:
                        self.layoutAdvanced.addWidget(widget)
                    else:
                        self.layoutMain.insertWidget(
                            self.layoutMain.count() - 2, widget)

        for output in self.alg.destinationParameterDefinitions():
            if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
                continue

            label = QLabel(output.description())
            widget = DestinationSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (QgsProcessingParameterRasterDestination,
                                   QgsProcessingParameterFeatureSink,
                                   QgsProcessingParameterVectorDestination)):
                check = QCheckBox()
                check.setText(
                    QCoreApplication.translate(
                        'ParametersPanel',
                        'Open output file after running algorithm'))

                def skipOutputChanged(checkbox, skipped):
                    checkbox.setEnabled(not skipped)
                    if skipped:
                        checkbox.setChecked(False)

                check.setChecked(not widget.outputIsSkipped())
                check.setEnabled(not widget.outputIsSkipped())
                widget.skipOutputChanged.connect(
                    partial(skipOutputChanged, check))
                self.layoutMain.insertWidget(self.layoutMain.count() - 1,
                                             check)
                self.checkBoxes[output.name()] = check

            widget.setToolTip(param.toolTip())
            self.outputWidgets[output.name()] = widget

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
コード例 #37
0
ファイル: mapwidget.py プロジェクト: terry-longmacch/Roam
class MapWidget(Ui_CanvasWidget, QMainWindow):
    def __init__(self, parent=None):
        super(MapWidget, self).__init__(parent)
        self.setupUi(self)
        self.snapping = True

        icon = roam_style.iconsize()
        self.projecttoolbar.setIconSize(QSize(icon, icon))

        self.defaultextent = None
        self.current_form = None
        self.last_form = None
        self.layerbuttons = []
        self.editfeaturestack = []
        self.lastgpsposition = None
        self.project = None
        self.gps = None
        self.gpslogging = None
        self.selectionbands = defaultdict(partial(QgsRubberBand, self.canvas))

        self.bridge = QgsLayerTreeMapCanvasBridge(
            QgsProject.instance().layerTreeRoot(), self.canvas)
        self.bridge.setAutoSetupOnFirstLayer(False)

        self.canvas.setCanvasColor(Qt.white)
        self.canvas.enableAntiAliasing(True)

        self.snappingutils = SnappingUtils(self.canvas, self)
        self.canvas.setSnappingUtils(self.snappingutils)

        threadcount = QThread.idealThreadCount()
        threadcount = 2 if threadcount > 2 else 1
        QgsApplication.setMaxThreads(threadcount)
        self.canvas.setParallelRenderingEnabled(True)

        self.canvas.setFrameStyle(QFrame.NoFrame)

        self.editgroup = QActionGroup(self)
        self.editgroup.setExclusive(True)
        self.editgroup.addAction(self.actionPan)
        self.editgroup.addAction(self.actionZoom_In)
        self.editgroup.addAction(self.actionZoom_Out)
        self.editgroup.addAction(self.actionInfo)

        self.actionGPS = GPSAction(self.canvas, self)
        self.projecttoolbar.addAction(self.actionGPS)

        if roam.config.settings.get('north_arrow', False):
            self.northarrow = NorthArrow(":/icons/north", self.canvas)
            self.northarrow.setPos(10, 10)
            self.canvas.scene().addItem(self.northarrow)

        smallmode = roam.config.settings.get("smallmode", False)
        self.projecttoolbar.setSmallMode(smallmode)

        self.projecttoolbar.setContextMenuPolicy(Qt.CustomContextMenu)

        gpsspacewidget = QWidget()
        gpsspacewidget.setMinimumWidth(30)
        gpsspacewidget.setSizePolicy(QSizePolicy.Expanding,
                                     QSizePolicy.Expanding)

        self.topspaceraction = self.projecttoolbar.insertWidget(
            self.actionGPS, gpsspacewidget)

        self.dataentryselection = QAction(self.projecttoolbar)
        self.dataentryaction = self.projecttoolbar.insertAction(
            self.topspaceraction, self.dataentryselection)
        self.dataentryselection.triggered.connect(self.select_data_entry)

        self.gpsMarker = GPSMarker(self.canvas)
        self.gpsMarker.hide()

        self.currentfeatureband = CurrentSelection(self.canvas)
        self.currentfeatureband.setIconSize(30)
        self.currentfeatureband.setWidth(10)
        self.currentfeatureband.setColor(QColor(88, 64, 173, 50))
        self.currentfeatureband.setOutlineColour(QColor(88, 64, 173))

        self.gpsband = QgsRubberBand(self.canvas)
        self.gpsband.setColor(QColor(165, 111, 212, 75))
        self.gpsband.setWidth(5)

        RoamEvents.refresh_map.connect(self.refresh_map)
        RoamEvents.editgeometry.connect(self.queue_feature_for_edit)
        RoamEvents.selectioncleared.connect(self.clear_selection)
        RoamEvents.selectionchanged.connect(self.highlight_selection)
        RoamEvents.openfeatureform.connect(self.feature_form_loaded)
        RoamEvents.sync_complete.connect(self.refresh_map)
        RoamEvents.snappingChanged.connect(self.snapping_changed)

        self.snappingbutton = QToolButton()
        self.snappingbutton.setText("Snapping: On")
        self.snappingbutton.setAutoRaise(True)
        self.snappingbutton.pressed.connect(self.toggle_snapping)

        spacer = QWidget()
        spacer2 = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        self.scalewidget = QgsScaleComboBox()

        self.scalebutton = QToolButton()
        self.scalebutton.setAutoRaise(True)
        self.scalebutton.setMaximumHeight(self.statusbar.height())
        self.scalebutton.pressed.connect(self.selectscale)
        self.scalebutton.setText("Scale")

        self.scalelist = BigList(parent=self.canvas,
                                 centeronparent=True,
                                 showsave=False)
        self.scalelist.hide()
        self.scalelist.setlabel("Map Scale")
        self.scalelist.setmodel(self.scalewidget.model())
        self.scalelist.closewidget.connect(self.scalelist.close)
        self.scalelist.itemselected.connect(self.update_scale_from_item)
        self.scalelist.itemselected.connect(self.scalelist.close)

        self.positionlabel = QLabel('')
        self.gpslabel = QLabel("GPS: Not active")
        self.gpslabelposition = QLabel("")
        self.gpslabelaveraging = QLabel('')  # averaging

        self.statusbar.addWidget(self.snappingbutton)
        self.statusbar.addWidget(spacer2)
        self.statusbar.addWidget(self.gpslabel)
        self.statusbar.addWidget(self.gpslabelposition)
        self.statusbar.addWidget(self.gpslabelaveraging)  # averaging
        self.statusbar.addPermanentWidget(self.scalebutton)

        self.canvas.extentsChanged.connect(self.update_status_label)
        self.canvas.scaleChanged.connect(self.update_status_label)

        self.connectButtons()

        scalebar_enabled = roam.config.settings.get('scale_bar', False)
        self.scalebar_enabled = False
        if scalebar_enabled:
            roam.utils.warning(
                "Unsupported feature: Scale bar support not ported to QGIS 3 API yet."
            )
            RoamEvents.raisemessage(
                "Unsupported feature",
                "Scale bar support not ported to QGIS 3 API yet",
                level=RoamEvents.CRITICAL)
            self.scalebar_enabled = False
            # self.scalebar = ScaleBarItem(self.canvas)
            # self.canvas.scene().addItem(self.scalebar)

    def clear_plugins(self) -> None:
        """
        Clear all the plugin added toolbars from the map interface.
        """
        toolbars = self.findChildren(QToolBar)
        for toolbar in toolbars:
            if toolbar.property("plugin_toolbar"):
                toolbar.unload()
                self.removeToolBar(toolbar)
                toolbar.deleteLater()

    def add_plugins(self, pluginnames) -> None:
        """
        Add the given plugins to to the mapping interface.

        Adds the toolbars the plugin exposes as new toolbars for the user.
        :param pluginnames: The names of the plugins to load.  Must already be loaded
                            by the plugin loader
        """
        for name in pluginnames:
            # Get the plugin
            try:
                plugin_mod = plugins.loaded_plugins[name]
            except KeyError:
                continue

            if not hasattr(plugin_mod, 'toolbars'):
                roam.utils.warning(
                    "No toolbars() function found in {}".format(name))
                continue

            toolbars = plugin_mod.toolbars()
            self.load_plugin_toolbars(toolbars)

    def load_plugin_toolbars(self, toolbars):
        """
        Load the plugin toolbars into the mapping interface.
        :param toolbars: The list of toolbars class objects to load.
        :return:
        """
        for ToolBarClass in toolbars:
            toolbar = ToolBarClass(plugins.api, self)
            self.addToolBar(Qt.BottomToolBarArea, toolbar)
            toolbar.setProperty("plugin_toolbar", True)

    def snapping_changed(self, snapping):
        """
        Called when the snapping settings have changed. Updates the label in the status bar.
        :param snapping:
        """
        self.snapping = snapping
        if snapping:
            self.snappingbutton.setText("Snapping: On")
        else:
            self.snappingbutton.setText("Snapping: Off")

    def toggle_snapping(self):
        """
        Toggle snapping on or off.
        """
        self.snapping = not self.snapping
        try:
            self.canvas.mapTool().toggle_snapping()
        except AttributeError:
            pass

        RoamEvents.snappingChanged.emit(self.snapping)

    def selectscale(self):
        """
        Show the select scale widget.
        :return:
        """
        self.scalelist.show()

    def update_scale_from_item(self, index):
        """
        Update the canvas scale from the selected scale item.
        :param index: The index of the selected item.
        """
        scale, _ = self.scalewidget.toDouble(index.data(Qt.DisplayRole))
        self.canvas.zoomScale(1.0 / scale)

    def update_gps_fixed_label(self, fixed, gpsinfo):
        if not fixed:
            self.gpslabel.setText("GPS: Acquiring fix")
            self.gpslabelposition.setText("")
            self.gpslabelaveraging.setText('')  # averaging

    quality_mappings = {
        0: "invalid",
        1: "GPS",
        2: "DGPS",
        3: "PPS",
        4: "Real Time Kinematic",
        5: "Float RTK",
        6: "Estimated",
        7: "Manual input mode",
        8: "Simulation mode"
    }

    def update_gps_label(self, position, gpsinfo):
        """
        Update the GPS label in the status bar with the GPS status.
        :param position: The current GPS position.
        :param gpsinfo: The current extra GPS information.
        """
        if not self.gps.connected:
            return

        fixtype = self.quality_mappings.get(gpsinfo.quality, "")
        self.gpslabel.setText(
            "DOP P:<b>{0:.2f}</b> H:<b>{1:.2f}</b> V:<b>{2:.2f}</b> "
            "Fix: <b>{3}</b> "
            "Sats: <b>{4}</b> ".format(gpsinfo.pdop, gpsinfo.hdop,
                                       gpsinfo.vdop, fixtype,
                                       gpsinfo.satellitesUsed))

        places = roam.config.settings.get("gpsplaces", 8)

        # if averaging, don't show this
        if not roam.config.settings.get('gps_averaging', True):
            self.gpslabelposition.setText("X: <b>{x:.{places}f}</b> "
                                          "Y: <b>{y:.{places}f}</b> "
                                          "Z: <b>{z}m</b> ".format(
                                              x=position.x(),
                                              y=position.y(),
                                              z=position.z(),
                                              places=places))
        else:
            self.gpslabelposition.setText('')
        # --- averaging -------------------------------------------------------
        # if turned on
        if roam.config.settings.get('gps_averaging', True):
            time = roam.config.settings.get('gps_averaging_start_time', '')
            # if currently happening
            if roam.config.settings.get('gps_averaging_in_action', True):
                time = datetime.now().replace(microsecond=0) - time.replace(
                    microsecond=0)
            count = roam.config.settings.get('gps_averaging_measurements', int)
            avglabel = 'AVG: <b>%s / %s</b>' % (time, count)
        else:
            avglabel = ''
        self.gpslabelaveraging.setText(avglabel)
        # ---------------------------------------------------------------------

    def gps_disconnected(self):
        self.gpslabel.setText("GPS: Not Active")
        self.gpslabelposition.setText("")
        self.gpslabelaveraging.setText("")
        self.gpsMarker.hide()

    def zoom_to_feature(self, feature):
        """
        Zoom to the given feature in the map.
        :param feature:
        :return:
        """
        box = feature.geometry().boundingBox()
        xmin, xmax, ymin, ymax = box.xMinimum(), box.xMaximum(), box.yMinimum(
        ), box.yMaximum()
        xmin -= 5
        xmax += 5
        ymin -= 5
        ymax += 5
        box = QgsRectangle(xmin, ymin, xmax, ymax)
        self.canvas.setExtent(box)
        self.canvas.refresh()

    def update_status_label(self, *args) -> None:
        """
        Update the status bar labels when the information has changed.
        """
        extent = self.canvas.extent()
        self.positionlabel.setText("Map Center: {}".format(
            extent.center().toString()))
        scale = 1.0 / self.canvas.scale()
        scale = self.scalewidget.toString(scale)
        self.scalebutton.setText(scale)

    def refresh_map(self) -> None:
        """
        Refresh the map
        """
        self.canvas.refresh()

    def updatescale(self) -> None:
        """
        Update the scale of the map with the current scale from the scale widget
        :return:
        """
        self.canvas.zoomScale(1.0 / self.scalewidget.scale())

    @property
    def crs(self) -> QgsCoordinateReferenceSystem:
        """
        Get the CRS used that is being used in the canvas
        :return: The QgsCoordinateReferenceSystem that is used by the canvas
        """
        return self.canvas.mapSettings().destinationCrs()

    def feature_form_loaded(self, form, feature, *args):
        """
        Called when the feature form is loaded.
        :param form: The Form object. Holds a reference to the forms layer.
        :param feature: The current capture feature
        """
        self.currentfeatureband.setToGeometry(feature.geometry(),
                                              form.QGISLayer)

    def highlight_selection(self, results):
        """
        Highlight the selection on the canvas.  This updates all selected objects based on the result set.
        :param results: A dict-of-list of layer-features.
        """
        self.clear_selection()
        for layer, features in results.items():
            band = self.selectionbands[layer]
            band.setColor(QColor(255, 0, 0))
            band.setIconSize(25)
            band.setWidth(5)
            band.setBrushStyle(Qt.NoBrush)
            band.reset(layer.geometryType())
            band.setZValue(self.currentfeatureband.zValue() - 1)
            for feature in features:
                band.addGeometry(feature.geometry(), layer)
        self.canvas.update()

    def highlight_active_selection(self, layer, feature, features):
        """
        Update the current active selected feature.
        :param layer: The layer of the active feature.
        :param feature: The active feature.
        :param features: The other features in the set to show as non active selection.
        :return:
        """
        self.clear_selection()
        self.highlight_selection({layer: features})
        self.currentfeatureband.setToGeometry(feature.geometry(), layer)
        self.canvas.update()

    def clear_selection(self):
        """
        Clear the selection from the canvas. Resets all selection rubber bands.
        :return:
        """
        # Clear the main selection rubber band
        self.canvas.scene().update()
        self.currentfeatureband.reset()
        # Clear the rest
        for band in self.selectionbands.values():
            band.reset()

        self.canvas.update()
        self.editfeaturestack = []

    def queue_feature_for_edit(self, form, feature):
        """
        Push a feature on the edit stack so the feature can have the geometry edited.
        :note: This is a big hack and I don't like it!
        :param form: The form for the current feature
        :param feature: The active feature.
        """
        def trigger_default_action():
            for action in self.projecttoolbar.actions():
                if action.property('dataentry') and action.isdefault:
                    action.trigger()
                    self.canvas.currentLayer().startEditing()
                    self.canvas.mapTool().setEditMode(True, feature.geometry(),
                                                      feature)
                    break

        self.editfeaturestack.append((form, feature))
        self.save_current_form()
        self.load_form(form)
        trigger_default_action()

    def save_current_form(self):
        self.last_form = self.current_form

    def restore_last_form(self):
        self.load_form(self.last_form)

    def clear_temp_objects(self):
        """
        Clear all temp objects from the canvas.
        :return:
        """
        def clear_tool_band():
            """
            Clear the rubber band of the active tool if it has one
            """
            tool = self.canvas.mapTool()
            if hasattr(tool, "clearBand"):
                tool.clearBand()

        self.currentfeatureband.reset()
        clear_tool_band()

    def settings_updated(self, settings):
        """
        Called when the settings have been updated in the Roam config.
        :param settings: A dict of the settings.
        """
        self.actionGPS.updateGPSPort()
        gpslogging = settings.get('gpslogging', True)
        if self.gpslogging:
            self.gpslogging.logging = gpslogging
        smallmode = settings.get("smallmode", False)
        self.projecttoolbar.setSmallMode(smallmode)

    def set_gps(self, gps, logging):
        """
        Set the GPS for the map widget.  Connects GPS signals
        """
        self.gps = gps
        self.gpslogging = logging
        self.gps.gpsfixed.connect(self.update_gps_fixed_label)
        self.gps.gpsposition.connect(self.update_gps_label)
        self.gps.gpsposition.connect(self.gps_update_canvas)
        self.gps.firstfix.connect(self.gps_first_fix)
        self.gps.gpsdisconnected.connect(self.gps_disconnected)

        self.gpsMarker.setgps(self.gps)
        self.actionGPS.setgps(gps)

    def gps_update_canvas(self, position, gpsinfo):
        """
        Updates the map canvas based on the GPS position.  By default if the GPS is outside the canvas
        extent the canvas will move to center on the GPS.  Can be turned off in settings.
        :param postion: The current GPS position.
        :param gpsinfo: The extra GPS information
        """
        # Recenter map if we go outside of the 95% of the area
        if self.gpslogging.logging:
            self.gpsband.addPoint(position)
            self.gpsband.show()

        if roam.config.settings.get('gpscenter', True):
            if not self.lastgpsposition == position:
                self.lastgpsposition = position.clone()
                rect = QgsRectangle(QgsPointXY(position), QgsPointXY(position))
                extentlimt = QgsRectangle(self.canvas.extent())
                extentlimt.scale(0.95)

                if not extentlimt.contains(QgsPointXY(position)):
                    self.zoom_to_location(position)

        self.gpsMarker.show()
        self.gpsMarker.setCenter(position, gpsinfo)

    def gps_first_fix(self, postion, gpsinfo):
        """
        Called the first time the GPS gets a fix.  If set this will zoom to the GPS after the first fix
        :param postion: The current GPS position.
        :param gpsinfo: The extra GPS information
        """
        zoomtolocation = roam.config.settings.get('gpszoomonfix', True)
        if zoomtolocation:
            self.canvas.zoomScale(1000)
            self.zoom_to_location(postion)

    def zoom_to_location(self, position):
        """
        Zoom to ta given position on the map..
        """
        rect = QgsRectangle(QgsPointXY(position), QgsPointXY(position))
        self.canvas.setExtent(rect)
        self.canvas.refresh()

    def select_data_entry(self):
        """
        Open the form selection widget to allow the user to pick the active capture form.
        """
        def showformerror(form):
            pass

        def actions():
            for form in self.project.forms:
                if not self.form_valid_for_capture(form):
                    continue

                action = form.createuiaction()
                valid, failreasons = form.valid
                if not valid:
                    roam.utils.warning("Form {} failed to load".format(
                        form.label))
                    roam.utils.warning("Reasons {}".format(failreasons))
                    action.triggered.connect(partial(showformerror, form))
                else:
                    action.triggered.connect(partial(self.load_form, form))
                yield action

        formpicker = PickActionDialog(msg="Select data entry form", wrap=5)
        formpicker.addactions(actions())
        formpicker.exec_()

    def project_loaded(self, project):
        """
        Called when the project is loaded. Main entry point for a loade project.
        :param project: The Roam project that has been loaded.
        """
        self.snappingutils.setConfig(QgsProject.instance().snappingConfig())
        self.project = project
        self.actionPan.trigger()
        firstform = self.first_capture_form()
        if firstform:
            self.load_form(firstform)
            self.dataentryselection.setVisible(True)
        else:
            self.dataentryselection.setVisible(False)

        # Enable the raster layers button only if the project contains a raster layer.
        layers = roam.api.utils.layers()
        hasrasters = any(layer.type() == QgsMapLayer.RasterLayer
                         for layer in layers)
        self.actionRaster.setEnabled(hasrasters)
        self.defaultextent = self.canvas.extent()
        roam.utils.info("Extent: {}".format(self.defaultextent.toString()))

        self.infoTool.selectionlayers = project.selectlayersmapping()

        self.canvas.refresh()

        projectscales, _ = QgsProject.instance().readBoolEntry(
            "Scales", "/useProjectScales")
        if projectscales:
            projectscales, _ = QgsProject.instance().readListEntry(
                "Scales", "/ScalesList")

            self.scalewidget.updateScales(projectscales)
        else:
            scales = [
                "1:50000", "1:25000", "1:10000", "1:5000", "1:2500", "1:1000",
                "1:500", "1:250", "1:200", "1:100"
            ]
            scales = roam.config.settings.get('scales', scales)
            self.scalewidget.updateScales(scales)

        if self.scalebar_enabled:
            self.scalebar.update()

        red = QgsProject.instance().readNumEntry("Gui", "/CanvasColorRedPart",
                                                 255)[0]
        green = QgsProject.instance().readNumEntry("Gui",
                                                   "/CanvasColorGreenPart",
                                                   255)[0]
        blue = QgsProject.instance().readNumEntry("Gui",
                                                  "/CanvasColorBluePart",
                                                  255)[0]
        myColor = QColor(red, green, blue)
        self.canvas.setCanvasColor(myColor)

        self.actionPan.toggle()
        self.clear_plugins()
        self.add_plugins(project.enabled_plugins)

    def setMapTool(self, tool, *args):
        """
        Set the active map tool in the canvas.
        :param tool: The QgsMapTool to set.
        """
        if tool == self.canvas.mapTool():
            return

        if hasattr(tool, "setSnapping"):
            tool.setSnapping(self.snapping)
        self.canvas.setMapTool(tool)

    def connectButtons(self):
        """
        Connect the default buttons in the interface. Zoom, pan, etc
        """
        def connectAction(action, tool):
            action.toggled.connect(partial(self.setMapTool, tool))

        def cursor(name):
            pix = QPixmap(name)
            pix = pix.scaled(QSize(24, 24))
            return QCursor(pix)

        self.zoomInTool = QgsMapToolZoom(self.canvas, False)
        self.zoomOutTool = QgsMapToolZoom(self.canvas, True)
        self.panTool = QgsMapToolPan(self.canvas)
        self.infoTool = InfoTool(self.canvas)

        self.infoTool.setAction(self.actionInfo)
        self.zoomInTool.setAction(self.actionZoom_In)
        self.zoomOutTool.setAction(self.actionZoom_Out)
        self.panTool.setAction(self.actionPan)

        connectAction(self.actionZoom_In, self.zoomInTool)
        connectAction(self.actionZoom_Out, self.zoomOutTool)
        connectAction(self.actionPan, self.panTool)
        connectAction(self.actionInfo, self.infoTool)

        self.zoomInTool.setCursor(cursor(':/icons/in'))
        self.zoomOutTool.setCursor(cursor(':/icons/out'))
        self.infoTool.setCursor(cursor(':/icons/select'))

        self.actionRaster.triggered.connect(self.toggle_raster_layers)
        self.actionHome.triggered.connect(self.homeview)

    def homeview(self):
        """
        Zoom the mapview canvas to the extents the project was opened at i.e. the
        default extent.
        """
        if self.defaultextent:
            self.canvas.setExtent(self.defaultextent)
            self.canvas.refresh()

    def form_valid_for_capture(self, form):
        """
        Check if the given form is valid for capture.
        :param form: The form to check.
        :return: True if valid form for capture
        """
        return form.has_geometry and self.project.layer_can_capture(
            form.QGISLayer)

    def first_capture_form(self):
        """
        Return the first valid form for capture.
        """
        for form in self.project.forms:
            if self.form_valid_for_capture(form):
                return form

    def load_form(self, form):
        """
        Load the given form so it's the active one for capture
        :param form: The form to load
        """
        self.clear_capture_tools()
        self.dataentryselection.setIcon(QIcon(form.icon))
        self.dataentryselection.setText(form.icontext)
        self.create_capture_buttons(form)
        self.current_form = form

    def create_capture_buttons(self, form):
        """
        Create the capture buttons in the toolbar for the given form.
        :param form: The active form.
        """
        tool = form.getMaptool()(self.canvas, form.settings)
        for action in tool.actions:
            # Create the action here.
            if action.ismaptool:
                action.toggled.connect(partial(self.setMapTool, tool))

            # Set the action as a data entry button so we can remove it later.
            action.setProperty("dataentry", True)
            self.editgroup.addAction(action)
            self.layerbuttons.append(action)
            self.projecttoolbar.insertAction(self.topspaceraction, action)
            action.setChecked(action.isdefault)

        if hasattr(tool, 'geometryComplete'):
            add = partial(self.add_new_feature, form)
            tool.geometryComplete.connect(add)
        else:
            tool.finished.connect(self.openForm)

        tool.error.connect(self.show_invalid_geometry_message)

    def show_invalid_geometry_message(self, message) -> None:
        """
        Shows the message to the user if the there is a invalid geometry capture.
        :param message: The message to show the user.
        """
        RoamEvents.raisemessage("Invalid geometry capture",
                                message,
                                level=RoamEvents.CRITICAL)
        if self.canvas.currentLayer() is not None:
            self.canvas.currentLayer().rollBack()
        RoamEvents.editgeometry_invalid.emit()

    def add_new_feature(self, form, geometry: QgsGeometry):
        """
        Add a new new feature to the given layer
        :param form:  The form to use for the new feature.
        :param geometry: The new geometry to create the feature for.
        """
        # NOTE This function is doing too much, acts as add and also edit.
        layer = form.QGISLayer
        if geometry.isMultipart():
            geometry.convertToMultiType()

        # Transform the new geometry back into the map layers geometry if it's needed
        transform = self.canvas.mapSettings().layerTransform(layer)
        if transform.isValid():
            geometry.transform(transform,
                               QgsCoordinateTransform.ReverseTransform)

        try:
            form, feature = self.editfeaturestack.pop()
            self.editfeaturegeometry(form, feature, newgeometry=geometry)
            return
        except IndexError:
            pass

        feature = form.new_feature(geometry=geometry)
        RoamEvents.load_feature_form(form, feature, editmode=False)

    def editfeaturegeometry(self, form, feature, newgeometry):
        # TODO Extract into function.
        layer = form.QGISLayer
        layer.startEditing()
        feature.setGeometry(newgeometry)
        layer.updateFeature(feature)
        saved = layer.commitChanges()
        if not saved:
            map(roam.utils.error, layer.commitErrors())
        self.canvas.refresh()
        self.currentfeatureband.setToGeometry(feature.geometry(), layer)
        RoamEvents.editgeometry_complete.emit(form, feature)
        self.canvas.mapTool().setEditMode(False, None, None)
        self.restore_last_form()

    def clear_capture_tools(self):
        """
        Clear the capture tools from the toolbar.
        :return: True if the capture button was active at the time of clearing.
        """
        captureselected = False
        for action in self.projecttoolbar.actions():
            if action.objectName() == "capture" and action.isChecked():
                captureselected = True

            if action.property('dataentry'):
                self.projecttoolbar.removeAction(action)
        return captureselected

    def toggle_raster_layers(self) -> None:
        """
        Toggle all raster layers on or off.
        """
        # Freeze the canvas to save on UI refresh
        dlg = PickActionDialog(msg="Raster visibility")
        actions = [
            (":/icons/raster_0", "Off", partial(self._set_basemaps_opacity,
                                                0), "photo_off"),
            (":/icons/raster_25", "25%",
             partial(self._set_basemaps_opacity, .25), "photo_25"),
            (":/icons/raster_50", "50%",
             partial(self._set_basemaps_opacity, .50), "photo_50"),
            (":/icons/raster_75", "75%",
             partial(self._set_basemaps_opacity, .75), "photo_75"),
            (":/icons/raster_100", "100%",
             partial(self._set_basemaps_opacity, 1), "photo_100"),
        ]

        # ":/icons/raster_100"), "100%", self, triggered=partial(self._set_raster_layer_value, 1),
        #                                                objectName="photo_100")
        dialog_actions = []
        for action in actions:
            icon = QIcon(action[0])
            qaction = QAction(icon,
                              action[1],
                              self,
                              triggered=action[2],
                              objectName=action[3])
            dialog_actions.append(qaction)

        dlg.addactions(dialog_actions)
        dlg.exec_()

    def _set_basemaps_opacity(self, value=0) -> None:
        """
        Set the opacity for all basemap raster layers.
        :param value: The opacity value betwen 0 and 1
        """
        tree = QgsProject.instance().layerTreeRoot()
        for node in tree.findLayers():
            layer = node.layer()
            if node.layer().type() == QgsMapLayer.RasterLayer:
                if value > 0:
                    node.setItemVisibilityChecked(Qt.Checked)
                    renderer = layer.renderer()
                    renderer.setOpacity(value)
                if value == 0:
                    node.setItemVisibilityChecked(Qt.Unchecked)

        self.canvas.refresh()

    def cleanup(self):
        """
        Clean up when the project has changed.
        :return:
        """
        # TODO Review cleanup
        # self.bridge.clear()
        self.gpsband.reset()
        self.gpsband.hide()
        self.clear_selection()
        self.clear_temp_objects()
        self.clear_capture_tools()
        for action in self.layerbuttons:
            self.editgroup.removeAction(action)
コード例 #38
0
class Plugin():
    """The QGIS interface implementation for the InaSAFE plugin.

    This class acts as the 'glue' between QGIS and our custom logic.
    It creates a toolbar and menu bar entry and launches the InaSAFE user
    interface if these are activated.
    """
    def __init__(self, iface):
        """Class constructor.

        On instantiation, the plugin instance will be assigned a copy
        of the QGIS iface object which will allow this plugin to access and
        manipulate the running QGIS instance that spawned it.

        :param iface:Quantum GIS iface instance. This instance is
            automatically passed to the plugin by QGIS when it loads the
            plugin.
        :type iface: QgisAppInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        self.dock_widget = None

        # Actions
        self.action_add_layers = None
        self.action_add_osm_layer = None
        self.action_add_petabencana_layer = None
        self.action_batch_runner = None
        self.action_dock = None
        self.action_extent_selector = None
        self.action_field_mapping = None
        self.action_multi_exposure = None
        self.action_function_centric_wizard = None
        self.action_import_dialog = None
        self.action_keywords_wizard = None
        self.action_minimum_needs = None
        self.action_minimum_needs_config = None
        self.action_multi_buffer = None
        self.action_options = None
        self.action_run_tests = None
        self.action_save_scenario = None
        self.action_shake_converter = None
        self.action_show_definitions = None
        self.action_toggle_rubberbands = None
        self.action_metadata_converter = None

        self.translator = None
        self.toolbar = None
        self.wizard = None
        self.actions = []  # list of all QActions we create for InaSAFE

        self.message_bar_item = None
        # Flag indicating if toolbar should show only common icons or not
        self.full_toolbar = False
        # print self.tr('InaSAFE')
        # For enable/disable the keyword editor icon
        self.iface.currentLayerChanged.connect(self.layer_changed)

        developer_mode = setting('developer_mode', False, expected_type=bool)
        self.hide_developer_buttons = (inasafe_release_status == 'final'
                                       and not developer_mode)

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('Plugin', message)

    def add_action(self, action, add_to_toolbar=True, add_to_legend=False):
        """Add a toolbar icon to the InaSAFE toolbar.

        :param action: The action that should be added to the toolbar.
        :type action: QAction

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the InaSAFE toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param add_to_legend: Flag indicating whether the action should also
            be added to the layer legend menu. Default to False.
        :type add_to_legend: bool
        """
        # store in the class list of actions for easy plugin unloading
        self.actions.append(action)
        self.iface.addPluginToMenu(self.tr('InaSAFE'), action)
        if add_to_toolbar:
            self.toolbar.addAction(action)
        if add_to_legend:
            # The id is the action name without spaces, tabs ...
            self.iface.addCustomActionForLayerType(action, self.tr('InaSAFE'),
                                                   QgsMapLayer.VectorLayer,
                                                   True)
            self.iface.addCustomActionForLayerType(action, self.tr('InaSAFE'),
                                                   QgsMapLayer.RasterLayer,
                                                   True)

    def _create_dock_toggle_action(self):
        """Create action for plugin dockable window (show/hide)."""
        # pylint: disable=W0201
        icon = resources_path('img', 'icons', 'icon.svg')
        self.action_dock = QAction(QIcon(icon), self.tr('Toggle InaSAFE Dock'),
                                   self.iface.mainWindow())
        self.action_dock.setObjectName('InaSAFEDockToggle')
        self.action_dock.setStatusTip(self.tr('Show/hide InaSAFE dock widget'))
        self.action_dock.setWhatsThis(self.tr('Show/hide InaSAFE dock widget'))
        self.action_dock.setCheckable(True)
        self.action_dock.setChecked(True)
        self.action_dock.triggered.connect(self.toggle_dock_visibility)
        self.add_action(self.action_dock)

        # --------------------------------------
        # Create action for keywords creation wizard
        # -------------------------------------

    def _create_keywords_wizard_action(self):
        """Create action for keywords creation wizard."""
        icon = resources_path('img', 'icons', 'show-keyword-wizard.svg')
        self.action_keywords_wizard = QAction(
            QIcon(icon), self.tr('Keywords Creation Wizard'),
            self.iface.mainWindow())
        self.action_keywords_wizard.setStatusTip(
            self.tr('Open InaSAFE keywords creation wizard'))
        self.action_keywords_wizard.setWhatsThis(
            self.tr('Open InaSAFE keywords creation wizard'))
        self.action_keywords_wizard.setEnabled(False)
        self.action_keywords_wizard.triggered.connect(
            self.show_keywords_wizard)
        self.add_action(self.action_keywords_wizard, add_to_legend=True)

    def _create_analysis_wizard_action(self):
        """Create action for IF-centric wizard."""
        icon = resources_path('img', 'icons', 'show-wizard.svg')
        self.action_function_centric_wizard = QAction(
            QIcon(icon), self.tr('Impact Function Centric Wizard'),
            self.iface.mainWindow())
        self.action_function_centric_wizard.setStatusTip(
            self.tr('Open InaSAFE impact function centric wizard'))
        self.action_function_centric_wizard.setWhatsThis(
            self.tr('Open InaSAFE impact function centric wizard'))
        self.action_function_centric_wizard.setEnabled(True)
        self.action_function_centric_wizard.triggered.connect(
            self.show_function_centric_wizard)
        self.add_action(self.action_function_centric_wizard)

    def _create_options_dialog_action(self):
        """Create action for options dialog."""
        icon = resources_path('img', 'icons', 'configure-inasafe.svg')
        self.action_options = QAction(QIcon(icon), self.tr('Options'),
                                      self.iface.mainWindow())
        self.action_options.setStatusTip(
            self.tr('Open InaSAFE options dialog'))
        self.action_options.setWhatsThis(
            self.tr('Open InaSAFE options dialog'))
        self.action_options.triggered.connect(self.show_options)
        self.add_action(self.action_options, add_to_toolbar=self.full_toolbar)

    def _create_minimum_needs_action(self):
        """Create action for minimum needs dialog."""
        icon = resources_path('img', 'icons', 'show-minimum-needs.svg')
        self.action_minimum_needs = QAction(
            QIcon(icon), self.tr('Minimum Needs Calculator'),
            self.iface.mainWindow())
        self.action_minimum_needs.setStatusTip(
            self.tr('Open InaSAFE minimum needs calculator'))
        self.action_minimum_needs.setWhatsThis(
            self.tr('Open InaSAFE minimum needs calculator'))
        self.action_minimum_needs.triggered.connect(self.show_minimum_needs)
        self.add_action(self.action_minimum_needs,
                        add_to_toolbar=self.full_toolbar)

    def _create_multi_buffer_action(self):
        """Create action for multi buffer dialog."""
        icon = resources_path('img', 'icons', 'show-multi-buffer.svg')
        self.action_multi_buffer = QAction(QIcon(icon),
                                           self.tr('Multi Buffer'),
                                           self.iface.mainWindow())
        self.action_multi_buffer.setStatusTip(
            self.tr('Open InaSAFE multi buffer'))
        self.action_multi_buffer.setWhatsThis(
            self.tr('Open InaSAFE multi buffer'))
        self.action_multi_buffer.triggered.connect(self.show_multi_buffer)
        self.add_action(self.action_multi_buffer,
                        add_to_toolbar=self.full_toolbar)

    def _create_minimum_needs_options_action(self):
        """Create action for global minimum needs dialog."""
        icon = resources_path('img', 'icons', 'show-global-minimum-needs.svg')
        self.action_minimum_needs_config = QAction(
            QIcon(icon), self.tr('Minimum Needs Configuration'),
            self.iface.mainWindow())
        self.action_minimum_needs_config.setStatusTip(
            self.tr('Open InaSAFE minimum needs configuration'))
        self.action_minimum_needs_config.setWhatsThis(
            self.tr('Open InaSAFE minimum needs configuration'))
        self.action_minimum_needs_config.triggered.connect(
            self.show_minimum_needs_configuration)
        self.add_action(self.action_minimum_needs_config,
                        add_to_toolbar=self.full_toolbar)

    def _create_shakemap_converter_action(self):
        """Create action for converter dialog."""
        icon = resources_path('img', 'icons', 'show-converter-tool.svg')
        self.action_shake_converter = QAction(QIcon(icon),
                                              self.tr('Shakemap Converter'),
                                              self.iface.mainWindow())
        self.action_shake_converter.setStatusTip(
            self.tr('Open InaSAFE Converter'))
        self.action_shake_converter.setWhatsThis(
            self.tr('Open InaSAFE Converter'))
        self.action_shake_converter.triggered.connect(
            self.show_shakemap_importer)
        self.add_action(self.action_shake_converter,
                        add_to_toolbar=self.full_toolbar)

    def _create_batch_runner_action(self):
        """Create action for batch runner dialog."""
        icon = resources_path('img', 'icons', 'show-batch-runner.svg')
        self.action_batch_runner = QAction(QIcon(icon),
                                           self.tr('Batch Runner'),
                                           self.iface.mainWindow())
        self.action_batch_runner.setStatusTip(self.tr('Open Batch Runner'))
        self.action_batch_runner.setWhatsThis(self.tr('Open Batch Runner'))
        self.action_batch_runner.triggered.connect(self.show_batch_runner)
        self.add_action(self.action_batch_runner,
                        add_to_toolbar=self.full_toolbar)

    def _create_save_scenario_action(self):
        """Create action for save scenario dialog."""
        icon = resources_path('img', 'icons', 'save-as-scenario.svg')
        self.action_save_scenario = QAction(QIcon(icon),
                                            self.tr('Save Current Scenario'),
                                            self.iface.mainWindow())
        message = self.tr('Save current scenario to text file')
        self.action_save_scenario.setStatusTip(message)
        self.action_save_scenario.setWhatsThis(message)
        # noinspection PyUnresolvedReferences
        self.action_save_scenario.triggered.connect(self.save_scenario)
        self.add_action(self.action_save_scenario,
                        add_to_toolbar=self.full_toolbar)

    def _create_osm_downloader_action(self):
        """Create action for import OSM Dialog."""
        icon = resources_path('img', 'icons', 'show-osm-download.svg')
        self.action_import_dialog = QAction(
            QIcon(icon), self.tr('OpenStreetMap Downloader'),
            self.iface.mainWindow())
        self.action_import_dialog.setStatusTip(
            self.tr('OpenStreetMap Downloader'))
        self.action_import_dialog.setWhatsThis(
            self.tr('OpenStreetMap Downloader'))
        self.action_import_dialog.triggered.connect(self.show_osm_downloader)
        self.add_action(self.action_import_dialog, add_to_toolbar=True)

    def _create_geonode_uploader_action(self):
        """Create action for Geonode uploader dialog."""
        icon = resources_path('img', 'icons', 'geonode.png')
        label = tr('Geonode Uploader')
        self.action_geonode = QAction(QIcon(icon), label,
                                      self.iface.mainWindow())
        self.action_geonode.setStatusTip(label)
        self.action_geonode.setWhatsThis(label)
        self.action_geonode.triggered.connect(self.show_geonode_uploader)
        self.add_action(self.action_geonode, add_to_toolbar=False)

    def _create_add_osm_layer_action(self):
        """Create action for import OSM Dialog."""
        icon = resources_path('img', 'icons', 'add-osm-tiles-layer.svg')
        self.action_add_osm_layer = QAction(
            QIcon(icon), self.tr('Add OpenStreetMap Tile Layer'),
            self.iface.mainWindow())
        self.action_add_osm_layer.setStatusTip(
            self.tr('Add OpenStreetMap Tile Layer'))
        self.action_add_osm_layer.setWhatsThis(
            self.tr('Use this to add an OSM layer to your map. '
                    'It needs internet access to function.'))
        self.action_add_osm_layer.triggered.connect(self.add_osm_layer)
        self.add_action(self.action_add_osm_layer, add_to_toolbar=True)

    def _create_show_definitions_action(self):
        """Create action for showing definitions / help."""
        icon = resources_path('img', 'icons', 'show-inasafe-help.svg')
        self.action_show_definitions = QAction(QIcon(icon),
                                               self.tr('InaSAFE Help'),
                                               self.iface.mainWindow())
        self.action_show_definitions.setStatusTip(self.tr('Show InaSAFE Help'))
        self.action_show_definitions.setWhatsThis(
            self.
            tr('Use this to show a document describing all InaSAFE concepts.'))
        self.action_show_definitions.triggered.connect(self.show_definitions)
        self.add_action(self.action_show_definitions, add_to_toolbar=True)

    def _create_metadata_converter_action(self):
        """Create action for showing metadata converter dialog."""
        icon = resources_path('img', 'icons', 'show-metadata-converter.svg')
        self.action_metadata_converter = QAction(
            QIcon(icon), self.tr('InaSAFE Metadata Converter'),
            self.iface.mainWindow())
        self.action_metadata_converter.setStatusTip(
            self.tr('Convert metadata from version 4.3 to version 3.5.'))
        self.action_metadata_converter.setWhatsThis(
            self.tr('Use this tool to convert metadata 4.3 to version 3.5'))
        self.action_metadata_converter.triggered.connect(
            self.show_metadata_converter)
        self.add_action(self.action_metadata_converter,
                        add_to_toolbar=self.full_toolbar)

    def _create_field_mapping_action(self):
        """Create action for showing field mapping dialog."""
        icon = resources_path('img', 'icons', 'show-mapping-tool.svg')
        self.action_field_mapping = QAction(
            QIcon(icon), self.tr('InaSAFE Field Mapping Tool'),
            self.iface.mainWindow())
        self.action_field_mapping.setStatusTip(
            self.tr('Assign field mapping to layer.'))
        self.action_field_mapping.setWhatsThis(
            self.tr('Use this tool to assign field mapping in layer.'))
        self.action_field_mapping.setEnabled(False)
        self.action_field_mapping.triggered.connect(self.show_field_mapping)
        self.add_action(self.action_field_mapping,
                        add_to_toolbar=self.full_toolbar)

    def _create_multi_exposure_action(self):
        """Create action for showing the multi exposure tool."""
        self.action_multi_exposure = QAction(
            QIcon(resources_path('img', 'icons', 'show-multi-exposure.svg')),
            self.tr('InaSAFE Multi Exposure Tool'), self.iface.mainWindow())
        self.action_multi_exposure.setStatusTip(
            self.tr('Open the multi exposure tool.'))
        self.action_multi_exposure.setWhatsThis(
            self.tr('Open the multi exposure tool.'))
        self.action_multi_exposure.setEnabled(True)
        self.action_multi_exposure.triggered.connect(self.show_multi_exposure)
        self.add_action(self.action_multi_exposure,
                        add_to_toolbar=self.full_toolbar)

    def _create_add_petabencana_layer_action(self):
        """Create action for import OSM Dialog."""
        icon = resources_path('img', 'icons', 'add-petabencana-layer.svg')
        self.action_add_petabencana_layer = QAction(
            QIcon(icon), self.tr('Add PetaBencana Flood Layer'),
            self.iface.mainWindow())
        self.action_add_petabencana_layer.setStatusTip(
            self.tr('Add PetaBencana Flood Layer'))
        self.action_add_petabencana_layer.setWhatsThis(
            self.tr('Use this to add a PetaBencana layer to your map. '
                    'It needs internet access to function.'))
        self.action_add_petabencana_layer.triggered.connect(
            self.add_petabencana_layer)
        self.add_action(self.action_add_petabencana_layer,
                        add_to_toolbar=self.full_toolbar)

    def _create_rubber_bands_action(self):
        """Create action for toggling rubber bands."""
        icon = resources_path('img', 'icons', 'toggle-rubber-bands.svg')
        self.action_toggle_rubberbands = QAction(
            QIcon(icon), self.tr('Toggle Scenario Outlines'),
            self.iface.mainWindow())
        message = self.tr('Toggle rubber bands showing scenario extents.')
        self.action_toggle_rubberbands.setStatusTip(message)
        self.action_toggle_rubberbands.setWhatsThis(message)
        # Set initial state
        self.action_toggle_rubberbands.setCheckable(True)
        flag = setting('showRubberBands', False, expected_type=bool)
        self.action_toggle_rubberbands.setChecked(flag)
        # noinspection PyUnresolvedReferences
        self.action_toggle_rubberbands.triggered.connect(
            self.dock_widget.toggle_rubber_bands)
        self.add_action(self.action_toggle_rubberbands)

    def _create_analysis_extent_action(self):
        """Create action for analysis extent dialog."""
        icon = resources_path('img', 'icons', 'set-extents-tool.svg')
        self.action_extent_selector = QAction(QIcon(icon),
                                              self.tr('Set Analysis Area'),
                                              self.iface.mainWindow())
        self.action_extent_selector.setStatusTip(
            self.tr('Set the analysis area for InaSAFE'))
        self.action_extent_selector.setWhatsThis(
            self.tr('Set the analysis area for InaSAFE'))
        self.action_extent_selector.triggered.connect(
            self.show_extent_selector)
        self.add_action(self.action_extent_selector)

    def _create_test_layers_action(self):
        """Create action for adding layers (developer mode, non final only)."""
        if self.hide_developer_buttons:
            return

        icon = resources_path('img', 'icons', 'add-test-layers.svg')
        self.action_add_layers = QAction(QIcon(icon),
                                         self.tr('Add Test Layers'),
                                         self.iface.mainWindow())
        self.action_add_layers.setStatusTip(self.tr('Add test layers'))
        self.action_add_layers.setWhatsThis(self.tr('Add test layers'))
        self.action_add_layers.triggered.connect(self.add_test_layers)

        self.add_action(self.action_add_layers)

    def _create_run_test_action(self):
        """Create action for running tests (developer mode, non final only)."""
        if self.hide_developer_buttons:
            return

        default_package = str(setting('testPackage', 'safe',
                                      expected_type=str))
        msg = self.tr('Run tests in %s' % default_package)

        self.test_button = QToolButton()
        self.test_button.setMenu(QMenu())
        self.test_button.setPopupMode(QToolButton.MenuButtonPopup)

        icon = resources_path('img', 'icons', 'run-tests.svg')
        self.action_run_tests = QAction(QIcon(icon), msg,
                                        self.iface.mainWindow())

        self.action_run_tests.setStatusTip(msg)
        self.action_run_tests.setWhatsThis(msg)
        self.action_run_tests.triggered.connect(self.run_tests)

        self.test_button.menu().addAction(self.action_run_tests)
        self.test_button.setDefaultAction(self.action_run_tests)

        self.action_select_package = QAction(QIcon(icon),
                                             self.tr('Select package'),
                                             self.iface.mainWindow())

        self.action_select_package.setStatusTip(self.tr('Select Test Package'))
        self.action_select_package.setWhatsThis(self.tr('Select Test Package'))
        self.action_select_package.triggered.connect(self.select_test_package)
        self.test_button.menu().addAction(self.action_select_package)
        self.toolbar.addWidget(self.test_button)

        self.add_action(self.action_run_tests, add_to_toolbar=False)
        self.add_action(self.action_select_package, add_to_toolbar=False)

    def _create_dock(self):
        """Create dockwidget and tabify it with the legend."""
        # Import dock here as it needs to be imported AFTER i18n is set up
        from safe.gui.widgets.dock import Dock
        self.dock_widget = Dock(self.iface)
        self.dock_widget.setObjectName('InaSAFE-Dock')
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget)
        legend_tab = self.iface.mainWindow().findChild(QApplication, 'Legend')
        if legend_tab:
            self.iface.mainWindow().tabifyDockWidget(legend_tab,
                                                     self.dock_widget)
            self.dock_widget.raise_()

    # noinspection PyPep8Naming
    def initGui(self):
        """Gui initialisation procedure (for QGIS plugin api).

        .. note:: Don't change the name of this method from initGui!

        This method is called by QGIS and should be used to set up
        any graphical user interface elements that should appear in QGIS by
        default (i.e. before the user performs any explicit action with the
        plugin).
        """
        self.toolbar = self.iface.addToolBar('InaSAFE')
        self.toolbar.setObjectName('InaSAFEToolBar')
        self.dock_widget = None
        # Now create the actual dock
        self._create_dock()
        # And all the menu actions
        # Configuration Group
        self._create_dock_toggle_action()
        self._create_options_dialog_action()
        self._create_minimum_needs_options_action()
        self._create_analysis_extent_action()
        self._create_rubber_bands_action()
        self._add_spacer_to_menu()
        self._create_keywords_wizard_action()
        self._create_analysis_wizard_action()
        self._add_spacer_to_menu()
        self._create_field_mapping_action()
        self._create_multi_exposure_action()
        self._create_metadata_converter_action()
        self._create_osm_downloader_action()
        self._create_add_osm_layer_action()
        self._create_add_petabencana_layer_action()
        self._create_geonode_uploader_action()
        self._create_shakemap_converter_action()
        self._create_minimum_needs_action()
        self._create_multi_buffer_action()
        self._create_test_layers_action()
        self._create_run_test_action()
        self._add_spacer_to_menu()
        self._create_batch_runner_action()
        self._create_save_scenario_action()
        self._add_spacer_to_menu()
        self._create_show_definitions_action()

        # Hook up a slot for when the dock is hidden using its close button
        # or  view-panels
        #
        self.dock_widget.visibilityChanged.connect(self.toggle_inasafe_action)
        # Also deal with the fact that on start of QGIS dock may already be
        # hidden.
        self.action_dock.setChecked(self.dock_widget.isVisible())

        self.iface.initializationCompleted.connect(
            partial(self.show_welcome_message))

    def _add_spacer_to_menu(self):
        """Create a spacer to the menu to separate action groups."""
        separator = QAction(self.iface.mainWindow())
        separator.setSeparator(True)
        self.iface.addPluginToMenu(self.tr('InaSAFE'), separator)

    @staticmethod
    def clear_modules():
        """Unload inasafe functions and try to return QGIS to before InaSAFE.

        .. todo:: I think this function can be removed. TS.
        """
        # next lets force remove any inasafe related modules
        modules = []
        for module in sys.modules:
            if 'inasafe' in module:
                # Check if it is really one of our modules i.e. exists in the
                # plugin directory
                tokens = module.split('.')
                path = ''
                for myToken in tokens:
                    path += os.path.sep + myToken
                parent = os.path.abspath(
                    os.path.join(__file__, os.path.pardir, os.path.pardir))
                full_path = os.path.join(parent, path + '.py')
                if os.path.exists(os.path.abspath(full_path)):
                    LOGGER.debug('Removing: %s' % module)
                    modules.append(module)
        for module in modules:
            del (sys.modules[module])
        for module in sys.modules:
            if 'inasafe' in module:
                print(module)

        # Lets also clean up all the path additions that were made
        package_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir))
        LOGGER.debug('Path to remove: %s' % package_path)
        # We use a list comprehension to ensure duplicate entries are removed
        LOGGER.debug(sys.path)
        sys.path = [y for y in sys.path if package_path not in y]
        LOGGER.debug(sys.path)

    def unload(self):
        """GUI breakdown procedure (for QGIS plugin api).

        .. note:: Don't change the name of this method from unload!

        This method is called by QGIS and should be used to *remove*
        any graphical user interface elements that should appear in QGIS.
        """
        # Remove the plugin menu item and icon
        if self.wizard:
            self.wizard.deleteLater()
        for myAction in self.actions:
            self.iface.removePluginMenu(self.tr('InaSAFE'), myAction)
            self.iface.removeToolBarIcon(myAction)
            self.iface.removeCustomActionForLayerType(myAction)
        self.iface.mainWindow().removeDockWidget(self.dock_widget)
        self.iface.mainWindow().removeToolBar(self.toolbar)
        self.dock_widget.setVisible(False)
        self.dock_widget.destroy()
        self.iface.currentLayerChanged.disconnect(self.layer_changed)

        # Unload QGIS expressions loaded by the plugin.
        for qgis_expression in list(qgis_expressions().keys()):
            QgsExpression.unregisterFunction(qgis_expression)

    def toggle_inasafe_action(self, checked):
        """Check or un-check the toggle inaSAFE toolbar button.

        This slot is called when the user hides the inaSAFE panel using its
        close button or using view->panels.

        :param checked: True if the dock should be shown, otherwise False.
        :type checked: bool
        """
        self.action_dock.setChecked(checked)

    # Run method that performs all the real work
    def toggle_dock_visibility(self):
        """Show or hide the dock widget."""
        if self.dock_widget.isVisible():
            self.dock_widget.setVisible(False)
        else:
            self.dock_widget.setVisible(True)
            self.dock_widget.raise_()

    def add_test_layers(self):
        """Add standard test layers."""
        from safe.test.utilities import load_standard_layers
        load_standard_layers()
        rect = QgsRectangle(106.806, -6.195, 106.837, -6.167)
        self.iface.mapCanvas().setExtent(rect)

    def select_test_package(self):
        """Select the test package."""
        default_package = 'safe'
        user_package = str(
            setting('testPackage', default_package, expected_type=str))

        test_package, _ = QInputDialog.getText(
            self.iface.mainWindow(), self.tr('Select the python test package'),
            self.tr('Select the python test package'), QLineEdit.Normal,
            user_package)

        if test_package == '':
            test_package = default_package

        set_setting('testPackage', test_package)
        msg = self.tr('Run tests in %s' % test_package)
        self.action_run_tests.setWhatsThis(msg)
        self.action_run_tests.setText(msg)

    def run_tests(self):
        """Run unit tests in the python console."""
        from qgis.PyQt.QtWidgets import QDockWidget
        main_window = self.iface.mainWindow()
        action = main_window.findChild(QAction, 'mActionShowPythonDialog')
        action.trigger()
        package = str(setting('testPackage', 'safe', expected_type=str))
        for child in main_window.findChildren(QDockWidget, 'PythonConsole'):
            if child.objectName() == 'PythonConsole':
                child.show()
                for widget in child.children():
                    if 'PythonConsoleWidget' in str(widget.__class__):
                        # print "Console widget found"
                        shell = widget.shell
                        shell.runCommand(
                            'from inasafe.test_suite import test_package')
                        shell.runCommand('test_package(\'%s\')' % package)
                        break

    def show_extent_selector(self):
        """Show the extent selector widget for defining analysis extents."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.extent_selector_dialog import ExtentSelectorDialog
        widget = ExtentSelectorDialog(
            self.iface,
            self.iface.mainWindow(),
            extent=self.dock_widget.extent.user_extent,
            crs=self.dock_widget.extent.crs)
        widget.clear_extent.connect(
            self.dock_widget.extent.clear_user_analysis_extent)
        widget.extent_defined.connect(
            self.dock_widget.define_user_analysis_extent)
        # This ensures that run button state is updated on dialog close
        widget.extent_selector_closed.connect(
            self.dock_widget.validate_impact_function)
        # Needs to be non modal to support hide -> interact with map -> show
        widget.show()  # non modal

    def show_minimum_needs(self):
        """Show the minimum needs dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.minimum_needs.needs_calculator_dialog import (
            NeedsCalculatorDialog)

        dialog = NeedsCalculatorDialog(self.iface.mainWindow())
        dialog.exec_()

    def show_minimum_needs_configuration(self):
        """Show the minimum needs dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.minimum_needs.needs_manager_dialog import (
            NeedsManagerDialog)

        dialog = NeedsManagerDialog(parent=self.iface.mainWindow(),
                                    dock=self.dock_widget)
        dialog.exec_()  # modal

    def show_options(self):
        """Show the options dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.options_dialog import OptionsDialog

        dialog = OptionsDialog(iface=self.iface,
                               parent=self.iface.mainWindow())
        dialog.show_option_dialog()
        if dialog.exec_():  # modal
            self.dock_widget.read_settings()
            from safe.gui.widgets.message import getting_started_message
            send_static_message(self.dock_widget, getting_started_message())
            # Issue #4734, make sure to update the combobox after update the
            # InaSAFE option
            self.dock_widget.get_layers()

    def show_welcome_message(self):
        """Show the welcome message."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.options_dialog import OptionsDialog

        # Do not show by default
        show_message = False

        previous_version = StrictVersion(setting('previous_version'))
        current_version = StrictVersion(inasafe_version)

        # Set previous_version to the current inasafe_version
        set_setting('previous_version', inasafe_version)

        if setting('always_show_welcome_message', expected_type=bool):
            # Show if it the setting said so
            show_message = True
        elif previous_version < current_version:
            # Always show if the user installed new version
            show_message = True

        # Allow to disable welcome message when running automated tests
        if os.environ.get('INASAFE_DISABLE_WELCOME_MESSAGE', False):
            show_message = False

        if show_message:
            dialog = OptionsDialog(iface=self.iface,
                                   parent=self.iface.mainWindow())
            dialog.show_welcome_dialog()
            if dialog.exec_():  # modal
                self.dock_widget.read_settings()

    def show_keywords_wizard(self):
        """Show the keywords creation wizard."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.wizard.wizard_dialog import WizardDialog

        if self.iface.activeLayer() is None:
            return

        # Don't break an existing wizard session if accidentally clicked
        if self.wizard and self.wizard.isVisible():
            return

        # Prevent spawning multiple copies since the IFCW is non modal
        if not self.wizard:
            self.wizard = WizardDialog(self.iface.mainWindow(), self.iface,
                                       self.dock_widget)
        self.wizard.set_keywords_creation_mode()
        self.wizard.exec_()  # modal

    def show_function_centric_wizard(self):
        """Show the function centric wizard."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.wizard.wizard_dialog import WizardDialog

        # Don't break an existing wizard session if accidentally clicked
        if self.wizard and self.wizard.isVisible():
            return

        # Prevent spawning multiple copies since it is non modal
        if not self.wizard:
            self.wizard = WizardDialog(self.iface.mainWindow(), self.iface,
                                       self.dock_widget)
        self.wizard.set_function_centric_mode()
        # non-modal in order to hide for selecting user extent
        self.wizard.show()

    def show_shakemap_importer(self):
        """Show the converter dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.shake_grid.shakemap_converter_dialog import (
            ShakemapConverterDialog)

        dialog = ShakemapConverterDialog(self.iface.mainWindow(), self.iface,
                                         self.dock_widget)
        dialog.exec_()  # modal

    def show_multi_buffer(self):
        """Show the multi buffer tool."""
        from safe.gui.tools.multi_buffer_dialog import (MultiBufferDialog)

        dialog = MultiBufferDialog(self.iface.mainWindow(), self.iface,
                                   self.dock_widget)
        dialog.exec_()  # modal

    def show_osm_downloader(self):
        """Show the OSM buildings downloader dialog."""
        from safe.gui.tools.osm_downloader_dialog import OsmDownloaderDialog

        dialog = OsmDownloaderDialog(self.iface.mainWindow(), self.iface)
        # otherwise dialog is never deleted
        dialog.setAttribute(Qt.WA_DeleteOnClose, True)
        dialog.show()  # non modal

    def show_geonode_uploader(self):
        """Show the Geonode uploader dialog."""
        from safe.gui.tools.geonode_uploader import GeonodeUploaderDialog

        dialog = GeonodeUploaderDialog(self.iface.mainWindow())
        dialog.show()  # non modal

    def add_osm_layer(self):
        """Add OSM tile layer to the map.

        This uses a gdal wrapper around the OSM tile service - see the
        WorldOSM.gdal file for how it is constructed.
        """
        path = resources_path('osm', 'WorldOSM.gdal')
        layer = QgsRasterLayer(path, self.tr('OpenStreetMap'))
        project = QgsProject.instance()

        # Try to add it as the last layer in the list
        # False flag prevents layer being added to legend
        project.addMapLayer(layer, False)
        root = QgsProject.instance().layerTreeRoot()
        index = len(root.findLayers()) + 1
        # LOGGER.info('Inserting layer %s at position %s' % (
        #    layer.source(), index))
        root.insertLayer(index, layer)
        project.addMapLayer(layer)

    def show_definitions(self):
        """Show InaSAFE Definitions (a report showing all key metadata)."""
        from safe.utilities.help import show_help
        from safe.gui.tools.help import definitions_help
        show_help(definitions_help.definitions_help())

    def show_field_mapping(self):
        """Show InaSAFE Field Mapping."""
        from safe.gui.tools.field_mapping_dialog import FieldMappingDialog
        dialog = FieldMappingDialog(
            parent=self.iface.mainWindow(),
            iface=self.iface,
        )
        if dialog.exec_():  # modal
            LOGGER.debug('Show field mapping accepted')
            self.dock_widget.layer_changed(self.iface.activeLayer())
        else:
            LOGGER.debug('Show field mapping not accepted')

    def show_metadata_converter(self):
        """Show InaSAFE Metadata Converter."""
        from safe.gui.tools.metadata_converter_dialog import (
            MetadataConverterDialog)
        dialog = MetadataConverterDialog(
            parent=self.iface.mainWindow(),
            iface=self.iface,
        )
        dialog.exec_()

    def show_multi_exposure(self):
        """Show InaSAFE Multi Exposure."""
        from safe.gui.tools.multi_exposure_dialog import MultiExposureDialog
        dialog = MultiExposureDialog(self.iface.mainWindow(), self.iface)
        dialog.exec_()  # modal

    def add_petabencana_layer(self):
        """Add petabencana layer to the map.

        This uses the PetaBencana API to fetch the latest floods in JK. See
        https://data.petabencana.id/floods
        """
        from safe.gui.tools.peta_bencana_dialog import PetaBencanaDialog
        dialog = PetaBencanaDialog(self.iface.mainWindow(), self.iface)
        dialog.show()  # non modal

    def show_batch_runner(self):
        """Show the batch runner dialog."""
        from safe.gui.tools.batch.batch_dialog import BatchDialog

        dialog = BatchDialog(parent=self.iface.mainWindow(),
                             iface=self.iface,
                             dock=self.dock_widget)
        dialog.exec_()  # modal

    def save_scenario(self):
        """Save current scenario to text file."""
        from safe.gui.tools.save_scenario import SaveScenarioDialog

        dialog = SaveScenarioDialog(iface=self.iface, dock=self.dock_widget)
        dialog.save_scenario()

    def layer_changed(self, layer):
        """Enable or disable keywords editor icon when active layer changes.

        :param layer: The layer that is now active.
        :type layer: QgsMapLayer
        """
        if not layer:
            enable_keyword_wizard = False
        elif not hasattr(layer, 'providerType'):
            enable_keyword_wizard = False
        elif layer.providerType() == 'wms':
            enable_keyword_wizard = False
        else:
            enable_keyword_wizard = True

        try:
            if layer:
                if is_raster_layer(layer):
                    enable_field_mapping_tool = False
                else:
                    keywords = KeywordIO().read_keywords(layer)
                    keywords_version = keywords.get('keyword_version')
                    if not keywords_version:
                        supported = False
                    else:
                        supported = (
                            is_keyword_version_supported(keywords_version))
                    if not supported:
                        enable_field_mapping_tool = False
                    else:
                        layer_purpose = keywords.get('layer_purpose')

                        if not layer_purpose:
                            enable_field_mapping_tool = False
                        else:
                            if layer_purpose == layer_purpose_exposure['key']:
                                layer_subcategory = keywords.get('exposure')
                            elif layer_purpose == layer_purpose_hazard['key']:
                                layer_subcategory = keywords.get('hazard')
                            else:
                                layer_subcategory = None
                            field_groups = get_field_groups(
                                layer_purpose, layer_subcategory)
                            if len(field_groups) == 0:
                                # No field group, disable field mapping tool.
                                enable_field_mapping_tool = False
                            else:
                                enable_field_mapping_tool = True
            else:
                enable_field_mapping_tool = False
        except (KeywordNotFoundError, NoKeywordsFoundError, MetadataReadError):
            # No keywords, disable field mapping tool.
            enable_field_mapping_tool = False

        self.action_keywords_wizard.setEnabled(enable_keyword_wizard)
        self.action_field_mapping.setEnabled(enable_field_mapping_tool)

    def shortcut_f7(self):
        """Executed when user press F7 - will show the shakemap importer."""
        self.show_shakemap_importer()
コード例 #39
0
class QmsSearchResultItemWidget(QWidget):
    def __init__(self, geoservice, image_ba, parent=None, extent_renderer=None):
        QWidget.__init__(self, parent)

        self.extent_renderer = extent_renderer

        self.layout = QHBoxLayout(self)
        self.layout.setContentsMargins(5, 10, 5, 10)
        self.setLayout(self.layout)

        self.service_icon = QLabel(self)
        self.service_icon.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.service_icon.resize(24, 24)

        qimg = QImage.fromData(image_ba)
        pixmap = QPixmap.fromImage(qimg)
        self.service_icon.setPixmap(pixmap)
        self.layout.addWidget(self.service_icon)

        self.service_desc_layout = QGridLayout(self)
        self.service_desc_layout.setSpacing(0)
        self.layout.addLayout(self.service_desc_layout)

        self.service_name = QLabel(self)
        self.service_name.setTextFormat(Qt.RichText)
        self.service_name.setWordWrap(True)
        self.service_name.setText(u"   <strong> {} </strong>".format(geoservice.get('name', u"")))
        self.service_desc_layout.addWidget(self.service_name, 0, 0, 1, 3)

        self.service_type = QLabel(self)
        self.service_type.setTextFormat(Qt.RichText)
        self.service_type.setWordWrap(True)
        self.service_type.setText(geoservice.get('type', u"").upper() + " ")
        self.service_desc_layout.addWidget(self.service_type, 1, 0)

        self.service_deteils = QLabel(self)
        self.service_deteils.setTextFormat(Qt.RichText)
        self.service_deteils.setWordWrap(True)
        self.service_deteils.setOpenExternalLinks(True)
        self.service_deteils.setText(u"<a href=\"{0}\">{1}</a>, ".format(
            Client().geoservice_info_url(geoservice.get('id', u"")),
            self.tr('details')
        ))
        self.service_desc_layout.addWidget(self.service_deteils, 1, 1)

        self.service_report = QLabel(self)
        self.service_report.setTextFormat(Qt.RichText)
        self.service_report.setWordWrap(True)
        self.service_report.setOpenExternalLinks(True)
        self.service_report.setText(u"<a href=\"{0}\">{1}</a><div/>".format(
            Client().geoservice_report_url(geoservice.get('id', u"")),
            self.tr('report a problem')
        ))
        self.service_desc_layout.addWidget(self.service_report, 1, 2)
        self.service_desc_layout.setColumnStretch(2, 1)


        self.status_label = QLabel(self)
        self.status_label.setTextFormat(Qt.RichText)
        self.status_label.setText(u'\u2022')


        status = geoservice.get('cumulative_status', u'')
        if status == 'works':
            self.status_label.setStyleSheet("color: green; font-size: 30px")
        if status == 'failed':
            self.status_label.setStyleSheet("color: red; font-size: 30px")
        if status == 'problematic':
            self.status_label.setStyleSheet("color: yellow; font-size: 30px")
        self.layout.addWidget(self.status_label)


        self.addButton = QToolButton()
        self.addButton.setText(self.tr("Add"))
        self.addButton.clicked.connect(self.addToMap)
        self.layout.addWidget(self.addButton)
        
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)

        self.geoservice = geoservice
        self.image_ba = image_ba

    def addToMap(self):
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            client = Client()
            client.set_proxy(*QGISSettings.get_qgis_proxy())
            geoservice_info = client.get_geoservice_info(self.geoservice)
            ds = DataSourceSerializer.read_from_json(geoservice_info)
            add_layer_to_map(ds)

            CachedServices().add_service(self.geoservice, self.image_ba)
        except Exception as ex:
            plPrint(unicode(ex))
            pass
        finally:
            QApplication.restoreOverrideCursor()

    def mouseDoubleClickEvent(self, event):
        self.addToMap()

    def enterEvent(self, event):
        extent = self.geoservice.get('extent', None)
        if self.extent_renderer and extent:
            if ';' in extent:
                extent = extent.split(';')[1]
            geom = QgsGeometry.fromWkt(extent)
            self.extent_renderer.show_feature(geom)

    def leaveEvent(self, event):
        if self.extent_renderer:
            self.extent_renderer.clear_feature()
コード例 #40
0
class PositionDisplay(QWidget):
    '''
    Widget to display the mouse position on the canvas in geographic coordinates (lat/lon)
    The display format can be altered.
    '''

    __FORMATS = ('DD', 'DDM', 'DMDS')

    exportPosition = pyqtSignal(str)

    def __init__(self, iface, parent=None):
        '''Constructor

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        '''
        super(PositionDisplay, self).__init__(parent)
        self.setObjectName('positionDisplay')
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 3, 0)
        self.button = QToolButton(self)
        self.button.setObjectName('toolButtonFormat')
        self.button.clicked.connect(self.switchCoordinateFormat)
        self.button.setAutoRaise(True)
        layout.addWidget(self.button)
        self.label = QLineEdit('---  ---')
        self.label.setReadOnly(True)
        self.label.setAlignment(Qt.AlignHCenter)
        self.label.setStyleSheet('font-weight: bold;')
        layout.addWidget(self.label)
        self.setLayout(layout)

        s = QSettings()
        self.format = s.value('PosiView/PositionDisplay/Format',
                              defaultValue=1,
                              type=int)
        self.button.setText(self.__FORMATS[self.format])

        canvas = iface.mapCanvas()
        crsDest = QgsCoordinateReferenceSystem('EPSG:4326')
        crsSrc = canvas.mapSettings().destinationCrs()
        self.xform = QgsCoordinateTransform(crsSrc, crsDest,
                                            QgsProject.instance())
        canvas.xyCoordinates.connect(self.mouseMoved)
        canvas.destinationCrsChanged.connect(self.mapCrsHasChanged)
        self.canvas = canvas
        try:
            self.sep = cf.separator() + ' '
        except AttributeError:
            self.sep = ', '

    @pyqtSlot(name='on_toolButtonFormat_clicked')
    def switchCoordinateFormat(self):
        self.format = (self.format + 1) % 3
        self.button.setText(self.tr(self.__FORMATS[self.format]))
        s = QSettings()
        s.setValue('PosiView/PositionDisplay/Format', self.format)

    @pyqtSlot()
    def mapCrsHasChanged(self):
        crsSrc = self.canvas.mapSettings().destinationCrs()
        self.xform.setSourceCrs(crsSrc)

    @pyqtSlot(QgsPointXY)
    def mouseMoved(self, point):
        pt = self.xform.transform(point)
        pos = self.posToStr(pt)
        self.label.setText(pos)
        self.exportPosition.emit(pos)

    def posToStr(self, pos):
        flg = cf.FlagDegreesUseStringSuffix
        if self.format == 1:
            f, pr = cf.FormatDegreesMinutes, 4
        elif self.format == 2:
            f, pr = cf.FormatDegreesMinutesSeconds, 2
        else:
            f, pr, flg = cf.FormatDecimalDegrees, 6, cf.FormatFlag(0)

        return self.sep.join(
            (cf.formatY(pos.y(), f, pr, flg), cf.formatX(pos.x(), f, pr, flg)))
コード例 #41
0
    def initWidgets(self):
        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameters:
            if param.isAdvanced:
                self.grpAdvanced.show()
                break
        # Create widgets and put them in layouts
        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]')

            wrapper = self.getWidgetWrapperFromParameter(param)
            self.wrappers[param.name] = wrapper
            widget = wrapper.widget

            if widget is not None:
                if isinstance(param, ParameterVector):
                    layout = QHBoxLayout()
                    layout.setSpacing(2)
                    layout.setMargin(0)
                    layout.addWidget(widget)
                    button = QToolButton()
                    icon = QIcon(
                        os.path.join(pluginPath, 'images', 'iterate.png'))
                    button.setIcon(icon)
                    button.setToolTip(self.tr('Iterate over this layer'))
                    button.setCheckable(True)
                    layout.addWidget(button)
                    self.iterateButtons[param.name] = button
                    button.toggled.connect(self.buttonToggled)
                    widget = QWidget()
                    widget.setLayout(layout)

                tooltips = self.alg.getParameterDescriptions()
                widget.setToolTip(tooltips.get(param.name, param.description))

                if type(widget) is QCheckBox:
                    # checkbox widget - so description is embedded in widget rather than a separate
                    # label
                    widget.setText(desc)
                else:
                    label = QLabel(desc)
                    # label.setToolTip(tooltip)
                    self.labels[param.name] = label

                    if param.isAdvanced:
                        self.layoutAdvanced.addWidget(label)
                    else:
                        self.layoutMain.insertWidget(
                            self.layoutMain.count() - 2, label)

                if param.isAdvanced:
                    self.layoutAdvanced.addWidget(widget)
                else:
                    self.layoutMain.insertWidget(self.layoutMain.count() - 2,
                                                 widget)

        for output in self.alg.outputs:
            if output.hidden:
                continue

            label = QLabel(output.description)
            widget = OutputSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (OutputRaster, OutputVector, OutputTable)):
                check = QCheckBox()
                check.setText(
                    self.tr('Open output file after running algorithm'))
                check.setChecked(True)
                self.layoutMain.insertWidget(self.layoutMain.count() - 1,
                                             check)
                self.checkBoxes[output.name] = check
            self.outputWidgets[output.name] = widget
        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
コード例 #42
0
ファイル: wrappers.py プロジェクト: ashokdahal/QGIS
    def createWidget(self):
        if self.dialogType == DIALOG_STANDARD:
            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            self.combo = QgsMapLayerComboBox()
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)

            widget.setLayout(layout)

            if self.param.optional:
                self.combo.setAllowEmptyLayer(True)

            self.combo.setFilters(QgsMapLayerProxyModel.VectorLayer)
            self.combo.setExcludedProviders(['grass'])
            try:
                if iface.activeLayer().type() == QgsMapLayer.VectorLayer:
                    self.combo.setLayer(iface.activeLayer())
            except:
                pass

            self.combo.currentIndexChanged.connect(
                lambda: self.widgetValueHasChanged.emit(self))
            self.combo.currentTextChanged.connect(
                lambda: self.widgetValueHasChanged.emit(self))
            return widget

        elif self.dialogType == DIALOG_BATCH:
            return BatchInputSelectionPanel(self.param, self.row, self.col,
                                            self.dialog)
        else:
            self.combo = QComboBox()
            layers = self.dialog.getAvailableValuesOfType(
                ParameterRaster, OutputRaster)
            self.combo.setEditable(True)
            tables = self.dialog.getAvailableValuesOfType(
                ParameterTable, OutputTable)
            layers = self.dialog.getAvailableValuesOfType(
                ParameterVector, OutputVector)
            if self.param.optional:
                self.combo.addItem(self.NOT_SELECTED, None)
            for table in tables:
                self.combo.addItem(self.dialog.resolveValueDescription(table),
                                   table)
            for layer in layers:
                self.combo.addItem(self.dialog.resolveValueDescription(layer),
                                   layer)

            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)
            widget.setLayout(layout)
            return widget
コード例 #43
0
ファイル: ParametersPanel.py プロジェクト: lukeandrew/QGIS
    def initWidgets(self):
        #tooltips = self.alg.getParameterDescriptions()

        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameters:
            if param.isAdvanced:
                self.grpAdvanced.show()
                break

        # Create widgets and put them in layouts
        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)')
            try:
                if param.optional:
                    desc += self.tr(' [optional]')
            except:
                pass

            widget = self.getWidgetFromParameter(param)
            self.valueItems[param.name] = widget

            if isinstance(param, ParameterVector) and \
                    not self.alg.allowOnlyOpenedLayers:
                layout = QHBoxLayout()
                layout.setSpacing(2)
                layout.setMargin(0)
                layout.addWidget(widget)
                button = QToolButton()
                icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png'))
                button.setIcon(icon)
                button.setToolTip(self.tr('Iterate over this layer'))
                button.setCheckable(True)
                layout.addWidget(button)
                self.iterateButtons[param.name] = button
                button.toggled.connect(self.buttonToggled)
                widget = QWidget()
                widget.setLayout(layout)

            #~ if param.name in tooltips.keys():
            #~ tooltip = tooltips[param.name]
            #~ else:
            #~ tooltip = param.description
            #~ widget.setToolTip(tooltip)

            if isinstance(param, ParameterBoolean):
                widget.setText(desc)
                if param.isAdvanced:
                    self.layoutAdvanced.addWidget(widget)
                else:
                    self.layoutMain.insertWidget(self.layoutMain.count() - 2,
                                                 widget)
            else:
                label = QLabel(desc)
                #label.setToolTip(tooltip)
                self.labels[param.name] = label
                if param.isAdvanced:
                    self.layoutAdvanced.addWidget(label)
                    self.layoutAdvanced.addWidget(widget)
                else:
                    self.layoutMain.insertWidget(self.layoutMain.count() - 2,
                                                 label)
                    self.layoutMain.insertWidget(self.layoutMain.count() - 2,
                                                 widget)

            self.widgets[param.name] = widget

        for output in self.alg.outputs:
            if output.hidden:
                continue

            label = QLabel(output.description)
            widget = OutputSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (OutputRaster, OutputVector, OutputTable)):
                check = QCheckBox()
                check.setText(
                    self.tr('Open output file after running algorithm'))
                check.setChecked(True)
                self.layoutMain.insertWidget(self.layoutMain.count() - 1,
                                             check)
                self.checkBoxes[output.name] = check
            self.valueItems[output.name] = widget
コード例 #44
0
ファイル: ParametersPanel.py プロジェクト: enricofer/QGIS
    def initWidgets(self):
        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                self.grpAdvanced.show()
                break

        widget_context = QgsProcessingParameterWidgetContext()
        if iface is not None:
            widget_context.setMapCanvas(iface.mapCanvas())

        # Create widgets and put them in layouts
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            if param.isDestination():
                continue
            else:
                wrapper = WidgetWrapperFactory.create_wrapper(param, self.parent)
                self.wrappers[param.name()] = wrapper

                # For compatibility with 3.x API, we need to check whether the wrapper is
                # the deprecated WidgetWrapper class. If not, it's the newer
                # QgsAbstractProcessingParameterWidgetWrapper class
                # TODO QGIS 4.0 - remove
                is_python_wrapper = issubclass(wrapper.__class__, WidgetWrapper)
                if not is_python_wrapper:
                    wrapper.setWidgetContext(widget_context)
                    widget = wrapper.createWrappedWidget(self.processing_context)
                    wrapper.registerProcessingContextGenerator(self.context_generator)
                else:
                    widget = wrapper.widget

                if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
                    # don't show the input/output parameter widgets in in-place mode
                    # we still need to CREATE them, because other wrappers may need to interact
                    # with them (e.g. those parameters which need the input layer for field
                    # selections/crs properties/etc)
                    continue

                if widget is not None:
                    if is_python_wrapper:
                        widget.setToolTip(param.toolTip())

                    if isinstance(param, QgsProcessingParameterFeatureSource):
                        layout = QHBoxLayout()
                        layout.setSpacing(6)
                        layout.setMargin(0)
                        layout.addWidget(widget)
                        button = QToolButton()
                        icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png'))
                        button.setIcon(icon)
                        button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
                        button.setToolTip(self.tr('Iterate over this layer, creating a separate output for every feature in the layer'))
                        button.setCheckable(True)
                        layout.addWidget(button)
                        layout.setAlignment(button, Qt.AlignTop)
                        self.iterateButtons[param.name()] = button
                        button.toggled.connect(self.buttonToggled)
                        widget = QWidget()
                        widget.setLayout(layout)

                    label = None
                    if not is_python_wrapper:
                        label = wrapper.createWrappedLabel()
                    else:
                        label = wrapper.label

                    if label is not None:
                        if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                            self.layoutAdvanced.addWidget(label)
                        else:
                            self.layoutMain.insertWidget(
                                self.layoutMain.count() - 2, label)
                    elif is_python_wrapper:
                        desc = param.description()
                        if isinstance(param, QgsProcessingParameterExtent):
                            desc += self.tr(' (xmin, xmax, ymin, ymax)')
                        if isinstance(param, QgsProcessingParameterPoint):
                            desc += self.tr(' (x, y)')
                        if param.flags() & QgsProcessingParameterDefinition.FlagOptional:
                            desc += self.tr(' [optional]')
                        widget.setText(desc)
                    if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                        self.layoutAdvanced.addWidget(widget)
                    else:
                        self.layoutMain.insertWidget(
                            self.layoutMain.count() - 2, widget)

        for output in self.alg.destinationParameterDefinitions():
            if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            if self.in_place and param.name() in ('INPUT', 'OUTPUT'):
                continue

            label = QLabel(output.description())
            widget = DestinationSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterVectorDestination)):
                check = QCheckBox()
                check.setText(QCoreApplication.translate('ParametersPanel', 'Open output file after running algorithm'))

                def skipOutputChanged(checkbox, skipped):
                    checkbox.setEnabled(not skipped)
                    if skipped:
                        checkbox.setChecked(False)
                check.setChecked(not widget.outputIsSkipped())
                check.setEnabled(not widget.outputIsSkipped())
                widget.skipOutputChanged.connect(partial(skipOutputChanged, check))
                self.layoutMain.insertWidget(self.layoutMain.count() - 1, check)
                self.checkBoxes[output.name()] = check

            widget.setToolTip(param.toolTip())
            self.outputWidgets[output.name()] = widget

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
コード例 #45
0
ファイル: ParametersPanel.py プロジェクト: AM7000000/QGIS
    def initWidgets(self):
        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameters:
            if param.isAdvanced:
                self.grpAdvanced.show()
                break
        # Create widgets and put them in layouts
        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)')
            try:
                if param.optional:
                    desc += self.tr(' [optional]')
            except:
                pass

            widget = self.getWidgetFromParameter(param)
            self.valueItems[param.name] = widget

            if isinstance(param, ParameterVector) and \
                    not self.alg.allowOnlyOpenedLayers:
                layout = QHBoxLayout()
                layout.setSpacing(2)
                layout.setMargin(0)
                layout.addWidget(widget)
                button = QToolButton()
                icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png'))
                button.setIcon(icon)
                button.setToolTip(self.tr('Iterate over this layer'))
                button.setCheckable(True)
                layout.addWidget(button)
                self.iterateButtons[param.name] = button
                button.toggled.connect(self.buttonToggled)
                widget = QWidget()
                widget.setLayout(layout)

            tooltips = self.alg.getParameterDescriptions()
            widget.setToolTip(tooltips.get(param.name, param.description))

            if isinstance(param, ParameterBoolean):
                widget.setText(desc)
                if param.isAdvanced:
                    self.layoutAdvanced.addWidget(widget)
                else:
                    self.layoutMain.insertWidget(
                        self.layoutMain.count() - 2, widget)
            else:
                label = QLabel(desc)
                #label.setToolTip(tooltip)
                self.labels[param.name] = label
                if param.isAdvanced:
                    self.layoutAdvanced.addWidget(label)
                    self.layoutAdvanced.addWidget(widget)
                else:
                    self.layoutMain.insertWidget(
                        self.layoutMain.count() - 2, label)
                    self.layoutMain.insertWidget(
                        self.layoutMain.count() - 2, widget)

            self.widgets[param.name] = widget

        for output in self.alg.outputs:
            if output.hidden:
                continue

            label = QLabel(output.description)
            widget = OutputSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (OutputRaster, OutputVector, OutputTable)):
                check = QCheckBox()
                check.setText(self.tr('Open output file after running algorithm'))
                check.setChecked(True)
                self.layoutMain.insertWidget(self.layoutMain.count() - 1, check)
                self.checkBoxes[output.name] = check
            self.valueItems[output.name] = widget

            if isinstance(output, OutputVector):
                if output.base_input in self.dependentItems:
                    items = self.dependentItems[output.base_input]
                else:
                    items = []
                    self.dependentItems[output.base_input] = items
                items.append(output)

                base_input = self.alg.getParameterFromName(output.base_input)
                if isinstance(base_input, ParameterVector):
                    layers = dataobjects.getVectorLayers(base_input.shapetype)
                else:
                    layers = dataobjects.getTables()
                if len(layers) > 0:
                    output.base_layer = layers[0]
コード例 #46
0
    def createWidget(self):
        if self.dialogType == DIALOG_STANDARD:
            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            self.combo = QgsMapLayerComboBox()
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)

            widget.setLayout(layout)

            filters = QgsMapLayerProxyModel.Filters()
            if self.param.datatype == [-1] or -1 in self.param.datatype:
                filters = QgsMapLayerProxyModel.HasGeometry
            if QgsWkbTypes.PointGeometry in self.param.datatype:
                filters |= QgsMapLayerProxyModel.PointLayer
            if QgsWkbTypes.LineGeometry in self.param.datatype:
                filters |= QgsMapLayerProxyModel.LineLayer
            if QgsWkbTypes.PolygonGeometry in self.param.datatype:
                filters |= QgsMapLayerProxyModel.PolygonLayer

            if self.param.optional:
                self.combo.setAllowEmptyLayer(True)
            if ProcessingConfig.getSetting(ProcessingConfig.SHOW_CRS_DEF):
                self.combo.setShowCrs(True)

            self.combo.setFilters(filters)
            self.combo.setExcludedProviders(['grass'])

            self.combo.currentIndexChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
            self.combo.currentTextChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
            return widget

        elif self.dialogType == DIALOG_BATCH:
            widget = BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
            widget.valueChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
            return widget
        else:
            self.combo = QComboBox()
            layers = self.dialog.getAvailableValuesOfType(ParameterVector, OutputVector)
            self.combo.setEditable(True)
            for layer in layers:
                self.combo.addItem(self.dialog.resolveValueDescription(layer), layer)
            if self.param.optional:
                self.combo.setEditText("")

            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)
            widget.setLayout(layout)
            return widget
コード例 #47
0
ファイル: ParametersPanel.py プロジェクト: cayetanobv/QGIS
    def initWidgets(self):
        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameters:
            if param.isAdvanced:
                self.grpAdvanced.show()
                break
        # Create widgets and put them in layouts
        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]')

            wrapper = self.getWidgetWrapperFromParameter(param)
            self.wrappers[param.name] = wrapper
            widget = wrapper.widget

            if widget is not None:
                if isinstance(param, ParameterVector):
                    layout = QHBoxLayout()
                    layout.setSpacing(2)
                    layout.setMargin(0)
                    layout.addWidget(widget)
                    button = QToolButton()
                    icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png'))
                    button.setIcon(icon)
                    button.setToolTip(self.tr('Iterate over this layer'))
                    button.setCheckable(True)
                    layout.addWidget(button)
                    self.iterateButtons[param.name] = button
                    button.toggled.connect(self.buttonToggled)
                    widget = QWidget()
                    widget.setLayout(layout)

                tooltips = self.alg.getParameterDescriptions()
                widget.setToolTip(tooltips.get(param.name, param.description))

                if type(widget) is QCheckBox:
                    # checkbox widget - so description is embedded in widget rather than a separate
                    # label
                    widget.setText(desc)
                else:
                    label = QLabel(desc)
                    # label.setToolTip(tooltip)
                    self.labels[param.name] = label

                    if param.isAdvanced:
                        self.layoutAdvanced.addWidget(label)
                    else:
                        self.layoutMain.insertWidget(
                            self.layoutMain.count() - 2, label)

                if param.isAdvanced:
                    self.layoutAdvanced.addWidget(widget)
                else:
                    self.layoutMain.insertWidget(
                        self.layoutMain.count() - 2, widget)

        for output in self.alg.outputs:
            if output.hidden:
                continue

            label = QLabel(output.description)
            widget = OutputSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (OutputRaster, OutputVector, OutputTable)):
                check = QCheckBox()
                check.setText(self.tr('Open output file after running algorithm'))
                check.setChecked(True)
                self.layoutMain.insertWidget(self.layoutMain.count() - 1, check)
                self.checkBoxes[output.name] = check
            self.outputWidgets[output.name] = widget
        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
コード例 #48
0
class PdokServicesPlugin(object):
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface

        # docked or dialog, defaults to dialog
        # 2018 may: RD: deprecating Docked window, as the content is getting to big anyway
        # if isinstance(QSettings().value("/pdokservicesplugin/docked"), QVariant):
        #     self.docked = QSettings().value("/pdokservicesplugin/docked", QVariant(False))
        # else:
        #     self.docked = QSettings().value("/pdokservicesplugin/docked", False)
        #
        # # Create the dialog and keep reference
        # if "True" == self.docked or "true" == self.docked or True is self.docked:
        #     self.dlg = PdokServicesPluginDockWidget()
        #     self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dlg)
        # else:
        #     self.dlg = PdokServicesPluginDialog(parent=self.iface.mainWindow())

        self.dlg = PdokServicesPluginDialog(parent=self.iface.mainWindow())
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        self.currentLayer = None
        self.SETTINGS_SECTION = '/pdokservicesplugin/'
        self.pointer = None
        self.pdokgeocoder = PDOKGeoLocator(self.iface)
        self.geocoderSourceModel = None

    def getSettingsValue(self, key, default=''):
        if QSettings().contains(self.SETTINGS_SECTION + key):
            key = self.SETTINGS_SECTION + key
            if Qgis.QGIS_VERSION_INT < 10900:  # qgis <= 1.8
                return str(QSettings().value(key).toString())
            else:
                return str(QSettings().value(key))
        else:
            return default

    def setSettingsValue(self, key, value):
        key = self.SETTINGS_SECTION + key
        if Qgis.QGIS_VERSION_INT < 10900:
            # qgis <= 1.8
            QSettings().setValue(key, QVariant(value))
        else:
            QSettings().setValue(key, value)

    def initGui(self):
        # Create action that will start plugin configuration
        self.runIcon = QIcon(
            os.path.join(self.plugin_dir, 'icon_add_service.svg'))

        self.run_action = QAction(self.runIcon, "PDOK Services plugin",
                                  self.iface.mainWindow())

        self.run_button = QToolButton()
        self.run_button.setMenu(QMenu())
        self.run_button.setPopupMode(QToolButton.MenuButtonPopup)
        self.run_button.setDefaultAction(self.run_action)

        self.servicesLoaded = False
        # connect the action to the run method
        self.run_action.triggered.connect(self.run)
        self.setupfq()

        # Add toolbar button and menu item
        #self.iface.addToolBarIcon(self.action)

        self.toolbar = self.iface.addToolBar("PDOK services plugin")
        self.toolbar.setObjectName("PDOK services plugin")
        #self.toolbar.addAction(self.run_action)
        self.toolbar.addWidget(self.run_button)

        #self.run_button.menu().addSection('Favorieten')

        self.favourite_1_action = QAction('Favoriet 1',
                                          self.iface.mainWindow())
        self.favourite_1_action.setIcon(self.runIcon)
        self.favourite_1_action.triggered.connect(
            lambda: self.load_favourite(1))
        self.set_favourite_action(self.favourite_1_action, 1)
        self.run_button.menu().addAction(self.favourite_1_action)

        self.favourite_2_action = QAction('Favoriet 2',
                                          self.iface.mainWindow())
        self.favourite_2_action.setIcon(self.runIcon)
        self.favourite_2_action.triggered.connect(
            lambda: self.load_favourite(2))
        self.set_favourite_action(self.favourite_2_action, 2)
        self.run_button.menu().addAction(self.favourite_2_action)

        # TODO :-)
        #self.run_button.menu().addSection('Meest Recent')
        #self.run_button.menu().addSeparator()

        self.toolbarSearch = QLineEdit()
        self.toolbarSearch.setMaximumWidth(200)
        self.toolbarSearch.setAlignment(Qt.AlignLeft)
        self.toolbarSearch.setPlaceholderText("PDOK Locatieserver zoek")
        self.toolbar.addWidget(self.toolbarSearch)
        self.toolbarSearch.returnPressed.connect(self.searchAddressFromToolbar)
        # address/point cleanup
        eraserIcon = QIcon(
            os.path.join(self.plugin_dir, 'icon_remove_cross.svg'))
        self.clean_action = QAction(eraserIcon, "Cleanup", self.eraseAddress())
        self.toolbar.addAction(self.clean_action)
        self.clean_action.triggered.connect(self.eraseAddress)
        self.clean_action.setEnabled(False)

        self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.run_action)

        # about
        self.aboutAction = QAction(QIcon(":/plugins/pdokservicesplugin/icon_help.png"), \
                            "About", self.iface.mainWindow())
        self.aboutAction.setWhatsThis("Pdok Services Plugin About")
        self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.aboutAction)

        self.aboutAction.triggered.connect(self.about)
        self.dlg.ui.btnLoadLayer.clicked.connect(self.loadService)

        self.dlg.geocoderSearch.returnPressed.connect(self.searchAddress)

        self.dlg.geocoderSearch.textEdited.connect(self.searchAddress)
        self.dlg.geocoderSearch.setPlaceholderText(
            "PDOK Locatieserver zoek, bv postcode of postcode huisnummer")

        self.dlg.geocoderResultSearch.textChanged.connect(
            self.filterGeocoderResult)
        self.dlg.geocoderResultSearch.setPlaceholderText(
            "een of meer zoekwoorden uit resultaat")
        #self.iface.mapCanvas().renderStarting.connect(self.extentsChanged)

        ui = self.dlg.ui
        cbxs = [
            ui.cbx_gem, ui.cbx_wpl, ui.cbx_weg, ui.cbx_pcd, ui.cbx_adr,
            ui.cbx_pcl, ui.cbx_hmp
        ]
        # connect all fq checkboxes with suggest, so upon a change in fq filter we re-search
        for cbx in cbxs:
            cbx.stateChanged.connect(self.searchAddress)

        self.run(True)

    # for now hiding the pointer as soon as the extent changes
    #def extentsChanged(self):
    #    self.removePointer()

    # 2021-02 hiding the check JSON: to much hassle
    def checkPdokJson(self):
        myversion = self.getSettingsValue('pdokversion', '1')
        msgtxt = ''
        msglvl = 0  # QgsMessageBar.INFO
        try:
            response = urllib.request.urlopen(
                'http://www.qgis.nl/pdok.version')
            str_response = response.read().decode('utf-8')
            pdokversion = json.loads(str_response)
            if pdokversion > int(myversion):
                response = urllib.request.urlopen(
                    'http://www.qgis.nl/pdok.json')
                str_response = response.read().decode('utf-8')
                pdokjson = json.loads(str_response)
                with open(os.path.join(self.plugin_dir, 'pdok.json'),
                          'w') as outfile:
                    json.dump(pdokjson, outfile)
                msgtxt = "De laatste versie is opgehaald en zal worden gebruikt " + \
                    str(pdokversion) + ' (was ' + myversion +')'
                self.servicesLoaded = False  # reset reading of json
                self.run()
                self.setSettingsValue('pdokversion', pdokversion)
            else:
                msgtxt = "Geen nieuwere versie beschikbaar dan " + str(
                    pdokversion)
        except Exception as e:
            #print e
            msgtxt = "Fout bij ophalen van service info. Netwerk probleem?"
            msglvl = 2  # QgsMessageBar.CRITICAL
        # msg
        if hasattr(self.iface, 'messageBar'):
            self.iface.messageBar().pushMessage("PDOK services update",
                                                msgtxt,
                                                level=msglvl,
                                                duration=10)
        else:  # 1.8
            QMessageBox.information(self.iface.mainWindow(),
                                    "Pdok Services Plugin", msgtxt)

    def showAndRaise(self):
        self.dlg.show()
        self.dlg.raise_()
        # also remove the pointer
        self.removePointer()

    def about(self):
        infoString = "Written by Richard Duivenvoorde\nEmail - [email protected]\n"
        infoString += "Company - Zuidt - http://www.zuidt.nl\n"
        infoString += "Source: https://github.com/rduivenvoorde/pdokservicesplugin"
        QMessageBox.information(self.iface.mainWindow(),
                                "Pdok Services Plugin About", infoString)

    def unload(self):
        self.removePointer()
        # Remove the plugin menu item and icon
        self.iface.removePluginMenu("&Pdok Services Plugin", self.run_action)
        self.iface.removePluginMenu("&Pdok Services Plugin", self.aboutAction)
        del self.toolbarSearch
        del self.run_action
        del self.aboutAction

    def showService(self, selectedIndexes):
        if len(selectedIndexes) == 0:
            self.currentLayer = None
            self.dlg.ui.layerInfo.setHtml('')
            self.dlg.ui.comboSelectProj.clear()
            return
        # needed to scroll To the selected row incase of using the keyboard / arrows
        self.dlg.servicesView.scrollTo(
            self.dlg.servicesView.selectedIndexes()[0])
        # itemType holds the data (== column 1)
        self.currentLayer = self.dlg.servicesView.selectedIndexes()[1].data(
            Qt.UserRole)
        if isinstance(self.currentLayer, QVariant):
            self.currentLayer = self.currentLayer.toMap()
            # QGIS 1.8: QVariants
            currentLayer = {}
            for key in list(self.currentLayer.keys()):
                val = self.currentLayer[key]
                currentLayer[str(key)] = str(val.toString())
            self.currentLayer = currentLayer
        url = self.currentLayer['url']
        title = self.currentLayer['title']
        style = ''
        if 'style' in self.currentLayer:
            style = self.currentLayer['style']
            title += f' [{style}]'
        servicetitle = self.currentLayer['servicetitle']
        layername = self.currentLayer['layers']
        abstract = self.currentLayer['abstract']
        stype = self.currentLayer['type'].upper()
        minscale = ''
        if 'minscale' in self.currentLayer and self.currentLayer[
                'minscale'] != None and self.currentLayer['minscale'] != '':
            minscale = "min. schaal 1:" + self.currentLayer['minscale']
        maxscale = ''
        if 'maxscale' in self.currentLayer and self.currentLayer[
                'maxscale'] != None and self.currentLayer['maxscale'] != '':
            maxscale = "max. schaal 1:" + self.currentLayer['maxscale']
        self.dlg.ui.layerInfo.setText('')
        self.dlg.ui.btnLoadLayer.setEnabled(True)
        self.dlg.ui.layerInfo.setHtml(
            '<h4>%s</h4><h3>%s</h3><lu><li>%s</li><li>&nbsp;</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li></lu>'
            % (servicetitle, title, abstract, stype, url, layername, style,
               minscale, maxscale))
        self.dlg.ui.comboSelectProj.clear()
        if stype == "WMS":
            try:
                crs = self.currentLayer['crs']
            except KeyError:
                crs = 'EPSG:28992'
            crs = crs.split(',')
            self.dlg.ui.comboSelectProj.addItems(crs)
            for i in range(len(crs)):
                if crs[i] == 'EPSG:28992':
                    self.dlg.ui.comboSelectProj.setCurrentIndex(i)
        if stype == "WMTS":
            tilematrixsets = self.currentLayer['tilematrixsets'].split(',')
            self.dlg.ui.comboSelectProj.addItems(tilematrixsets)
            for i in range(len(tilematrixsets)):
                if tilematrixsets[i].startswith('EPSG:28992'):
                    self.dlg.ui.comboSelectProj.setCurrentIndex(i)

    def set_favourite_action(self, action, favourite_number):
        if QSettings().contains(
                f'/pdokservicesplugin/favourite_{favourite_number}'):
            layer = QSettings().value(
                f'/pdokservicesplugin/favourite_{favourite_number}', None)
            if layer:
                action.setToolTip(layer['title'].capitalize())
                title = layer['title'].capitalize()
                if 'style' in layer:
                    style = layer['style']
                    title += f' [{style}]'
                if 'type' in layer:
                    stype = layer['type'].upper()
                    title += f' ({stype})'
                action.setText(title)
                action.setIcon(self.runIcon)

    def load_favourite(self, favourite_number):
        if QSettings().contains(
                f'/pdokservicesplugin/favourite_{favourite_number}'):
            layer = QSettings().value(
                f'/pdokservicesplugin/favourite_{favourite_number}', None)
            if layer and layer in self.pdok['services']:
                self.currentLayer = layer
                self.loadService()
                return
        QMessageBox.warning(self.iface.mainWindow(), "Geen Favoriet aanwezig (of verouderd)...", ( \
            "Maak een Favoriet aan door in de dialoog met services en lagen\n via het context menu (rechter muisknop) een Favoriet te kiezen..."
            ), QMessageBox.Ok, QMessageBox.Ok)
        self.run()

    def loadService(self):
        if self.currentLayer == None:
            return
        servicetype = self.currentLayer['type']
        url = self.currentLayer['url']
        # some services have an url with query parameters in it, we have to urlencode those:
        location, query = urllib.parse.splitquery(url)
        url = location
        # RD: 20200820: lijkt of het quoten van de query problemen geeft bij WFS, is/was dit nodig???
        #if query != None and query != '':
        #    url +=('?'+urllib.parse.quote_plus(query))
        title = self.currentLayer['title']
        if 'style' in self.currentLayer:
            style = self.currentLayer['style']
            title += f' [{style}]'
        else:
            style = ''  # == default for this service
        layers = self.currentLayer['layers']
        # mmm, tricky: we take the first one while we can actually want png/gif or jpeg
        if servicetype == "wms":
            imgformat = self.currentLayer['imgformats'].split(',')[0]
            if self.dlg.ui.comboSelectProj.currentIndex() == -1:
                crs = 'EPSG:28992'
            else:
                crs = self.dlg.ui.comboSelectProj.currentText()
            if Qgis.QGIS_VERSION_INT < 10900:
                # qgis <= 1.8
                uri = url
                self.iface.addRasterLayer(
                    uri,  # service uri
                    title,  # name for layer (as seen in QGIS)
                    "wms",  # dataprovider key
                    [layers],  # array of layername(s) for provider (id's)
                    [""
                     ],  # array of stylename(s)  NOTE: ignoring styles here!!!
                    imgformat,  # image format searchstring
                    crs)  # crs code searchstring
            else:
                # qgis > 1.8
                uri = "crs=" + crs + "&layers=" + layers + "&styles=" + style + "&format=" + imgformat + "&url=" + url
                self.iface.addRasterLayer(uri, title, "wms")
        elif servicetype == "wmts":
            if Qgis.QGIS_VERSION_INT < 10900:
                QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", (
                    "Sorry, dit type layer: '" + servicetype.upper() +
                    "' \nkan niet worden geladen in deze versie van QGIS.\nMisschien kunt u QGIS 2.0 installeren (die kan het WEL)?\nOf is de laag niet ook beschikbaar als wms of wfs?"
                ), QMessageBox.Ok, QMessageBox.Ok)
                return
            if self.dlg.ui.comboSelectProj.currentIndex() == -1:
                tilematrixset = 'EPSG:28992'
            else:
                tilematrixset = self.dlg.ui.comboSelectProj.currentText()
            imgformat = self.currentLayer['imgformats'].split(',')[0]
            # special case for luchtfoto
            #if layers=="luchtfoto":
            #    # tileMatrixSet=nltilingschema&crs=EPSG:28992&layers=luchtfoto&styles=&format=image/jpeg&url=http://geodata1.nationaalgeoregister.nl/luchtfoto/wmts/1.0.0/WMTSCapabilities.xml
            #    # {u'layers': u'luchtfoto', u'imgformats': u'image/jpeg', u'title': u'PDOK-achtergrond luchtfoto', u'url': u'http://geodata1.nationaalgeoregister.nl/luchtfoto/wms', u'abstract': u'', u'tilematrixsets': u'nltilingschema', u'type': u'wmts'}
            #    uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=&format="+imgformat+"&url="+url
            #else:
            #    uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=&format="+imgformat+"&url="+url;
            #uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=default&format="+imgformat+"&url="+url;
            if tilematrixset.startswith('EPSG:'):
                crs = tilematrixset
                i = crs.find(':', 5)
                if i > -1:
                    crs = crs[:i]
            elif tilematrixset.startswith('OGC:1.0'):
                crs = 'EPSG:3857'
            uri = "tileMatrixSet=" + tilematrixset + "&crs=" + crs + "&layers=" + layers + "&styles=default&format=" + imgformat + "&url=" + url
            #print "############ PDOK URI #################"
            #print uri
            self.iface.addRasterLayer(uri, title, "wms")
        elif servicetype == "wfs":
            location, query = urllib.parse.splitquery(url)
            #uri = location+"?SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME="+layers+"&SRSNAME=EPSG:28992"
            #uri = location + "?SERVICE=WFS&REQUEST=GetFeature&TYPENAME=" + layers + "&SRSNAME=EPSG:28992"
            # adding a bbox paramater forces QGIS to NOT cache features but retrieve new features all the time
            # QGIS will update the BBOX to the right value
            #uri += "&BBOX=-10000,310000,290000,650000"
            uri = " pagingEnabled='true' restrictToRequestBBOX='1' srsname='EPSG:28992' typename='" + layers + "' url='" + url + "' version='2.0.0' "
            self.iface.addVectorLayer(uri, title, "WFS")
        elif servicetype == "wcs":
            # cache=AlwaysCache&crs=EPSG:28992&format=GeoTIFF&identifier=ahn25m:ahn25m&url=http://geodata.nationaalgeoregister.nl/ahn25m/wcs
            uri = ''
            # cache=AlwaysCache
            # cache=PreferNetwork
            # cache=AlwaysNetwork
            # cache=AlwaysNetwork&crs=EPSG:28992&format=GeoTIFF&identifier=ahn25m:ahn25m&url=http://geodata.nationaalgeoregister.nl/ahn25m/wcs
            #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=image/tiff&version=1.1.1&identifier="+layers+"&url="+url
            # working for ahn1 ahn2 and ahn3: GEOTIFF_FLOAT32
            format = 'GEOTIFF_FLOAT32'
            # working for ahn25m is only image/tiff
            if layers == 'ahn25m':
                format = 'image/tiff'
            # we handcrated some wcs layers with 2 different image formats: tiff (RGB) and tiff (float32):
            if 'imgformats' in self.currentLayer:
                format = self.currentLayer['imgformats'].split(',')[0]
            uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=" + format + "&identifier=" + layers + "&url=" + url
            #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format="+format+"&version=1.1.2&identifier=" + layers + "&url=" + url
            #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=image/tiff&version=1.1.2&identifier=" + layers + "&url=" + url
            self.iface.addRasterLayer(uri, title, "wcs")
        else:
            QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", (
                "Sorry, dit type layer: '" + servicetype.upper() +
                "' \nkan niet worden geladen door de plugin of door QGIS.\nIs het niet beschikbaar als wms, wmts of wfs?"
            ), QMessageBox.Ok, QMessageBox.Ok)
            return

    def filterGeocoderResult(self, string):
        #print "filtering geocoder results: %s" % string
        self.dlg.geocoderResultView.selectRow(0)
        self.geocoderProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.geocoderProxyModel.setFilterFixedString(string)

    def searchAddressFromToolbar(self):
        self.removePointer()
        self.geocoderSourceModel.clear()
        self.geocode()

    def searchAddress(self):
        self.removePointer()
        #print "search geocoder for: %s" % self.dlg.geocoderSearch.text()
        self.geocoderSourceModel.clear()
        #self.geocode(self.dlg.geocoderSearch.text())
        self.suggest()

    def eraseAddress(self):
        """
        clean the input and remove the pointer
        """
        self.removePointer()
        if self.geocoderSourceModel is not None:
            self.geocoderSourceModel.clear()
        if self.dlg.geocoderSearch is not None:
            self.dlg.geocoderSearch.clear()
        if self.toolbarSearch is not None:
            self.toolbarSearch.clear()

    def filterLayers(self, string):
        # remove selection if one row is selected
        self.dlg.servicesView.selectRow(0)
        #self.currentLayer = None
        self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setFilterFixedString(string)

    #def addSourceRow(self, service, layer):
    def addSourceRow(self, serviceLayer):
        # you can attache different "data's" to to an QStandarditem
        # default one is the visible one:
        itemType = QStandardItem("%s" % (serviceLayer["type"].upper()))
        # userrole is a free form one:
        # only attach the data to the first item
        # service layer = a dict/object with all props of the layer
        itemType.setData(serviceLayer, Qt.UserRole)
        itemType.setToolTip(
            "%s - %s" % (serviceLayer["type"].upper(), serviceLayer["title"]))
        # only wms services have styles (sometimes)
        layername = serviceLayer["title"]
        if 'style' in serviceLayer:
            itemLayername = QStandardItem(
                "%s [%s]" % (serviceLayer["title"], serviceLayer["style"]))
            layername = "%s [%s]" % (serviceLayer["title"],
                                     serviceLayer["style"])
        else:
            itemLayername = QStandardItem("%s" % (serviceLayer["title"]))
        itemLayername.setToolTip(
            "%s - %s" %
            (serviceLayer["type"].upper(), serviceLayer["servicetitle"]))
        # itemFilter is the item used to search filter in. That is why layername is a combi of layername + filter here
        itemFilter = QStandardItem(
            "%s %s %s %s" %
            (serviceLayer["type"], layername, serviceLayer["servicetitle"],
             serviceLayer["abstract"]))
        itemServicetitle = QStandardItem("%s" % (serviceLayer["servicetitle"]))
        itemServicetitle.setToolTip(
            "%s - %s" % (serviceLayer["type"].upper(), serviceLayer["title"]))
        self.sourceModel.appendRow(
            [itemLayername, itemType, itemServicetitle, itemFilter])

    # run method that performs all the real work
    def run(self, hiddenDialog=False):

        # enable possible remote pycharm debugging
        #import pydevd
        #pydevd.settrace('localhost', port=5678, stdoutToServer=True, stderrToServer=True)

        # last viewed/selected tab
        if QSettings().contains("/pdokservicesplugin/currenttab"):
            if Qgis.QGIS_VERSION_INT < 10900:
                # qgis <= 1.8
                self.dlg.tabs.widget(QSettings().value(
                    "/pdokservicesplugin/currenttab").toInt()[0])
            else:
                self.dlg.tabs.widget(
                    int(QSettings().value("/pdokservicesplugin/currenttab")))

        if self.servicesLoaded == False:
            pdokjson = os.path.join(self.plugin_dir, "pdok.json")
            with open(pdokjson, 'r', encoding='utf-8') as f:
                self.pdok = json.load(f)
                print(f'self.pdok type = {type(self.pdok)}')

            self.proxyModel = QSortFilterProxyModel()
            self.sourceModel = QStandardItemModel()
            self.proxyModel.setSourceModel(self.sourceModel)
            # filter == search on itemFilter column:
            self.proxyModel.setFilterKeyColumn(3)
            self.dlg.servicesView.setModel(self.proxyModel)
            self.dlg.servicesView.setEditTriggers(
                QAbstractItemView.NoEditTriggers)

            self.geocoderProxyModel = QSortFilterProxyModel()
            self.geocoderSourceModel = QStandardItemModel()

            self.geocoderProxyModel.setSourceModel(self.geocoderSourceModel)
            self.geocoderProxyModel.setFilterKeyColumn(0)
            self.dlg.geocoderResultView.setModel(self.geocoderProxyModel)
            self.dlg.geocoderResultView.setEditTriggers(
                QAbstractItemView.NoEditTriggers)

            #{"services":[
            #   {"naam":"WMS NHI","url":"http://geodata.nationaalgeoregister.nl/nhi/ows","layers":["dmlinks","dmnodes"],"type":"wms"},
            #   {"naam":"WMS NHI","url":"http://geodata.nationaalgeoregister.nl/nhi/ows","layers":["dmlinks","dmnodes"],"type":"wms"}
            # ]}
            #
            for service in self.pdok["services"]:
                # service[layer] was an array
                if isinstance(service["layers"], str):
                    self.addSourceRow(service)

            self.dlg.layerSearch.textChanged.connect(self.filterLayers)
            self.dlg.layerSearch.setPlaceholderText(
                "woord uit laagnaam, type of service ")
            self.dlg.servicesView.selectionModel().selectionChanged.connect(
                self.showService)
            self.dlg.servicesView.doubleClicked.connect(self.loadService)

            self.dlg.servicesView.setContextMenuPolicy(Qt.CustomContextMenu)
            self.dlg.servicesView.customContextMenuRequested.connect(
                self.make_favourite)

            # actually I want to load a service when doubleclicked on header
            # but as I cannot get this to work, let's disable clicking it then
            self.dlg.servicesView.verticalHeader().setSectionsClickable(False)
            self.dlg.servicesView.horizontalHeader().setSectionsClickable(
                False)

            #self.dlg.geocoderResultView.doubleClicked.connect(self.zoomToAddress)
            self.dlg.geocoderResultView.selectionModel(
            ).selectionChanged.connect(self.zoomToAddress)

            # hide itemFilter column:
            self.dlg.servicesView.hideColumn(3)
            self.servicesLoaded = True

        self.sourceModel.setHeaderData(2, Qt.Horizontal, "Service")
        self.sourceModel.setHeaderData(1, Qt.Horizontal, "Type")
        self.sourceModel.setHeaderData(0, Qt.Horizontal, "Laagnaam [style]")
        self.sourceModel.horizontalHeaderItem(2).setTextAlignment(Qt.AlignLeft)
        self.sourceModel.horizontalHeaderItem(1).setTextAlignment(Qt.AlignLeft)
        self.sourceModel.horizontalHeaderItem(0).setTextAlignment(Qt.AlignLeft)
        #self.dlg.servicesView.verticalHeader().hide()
        #self.dlg.servicesView.resizeColumnsToContents()
        self.dlg.servicesView.setColumnWidth(
            0, 300)  # set name to 300px (there are some huge layernames)
        self.dlg.servicesView.horizontalHeader().setStretchLastSection(True)
        # show the dialog ?
        if not hiddenDialog:
            self.dlg.show()
        # Run the dialog event loop
        #result = self.dlg.exec_()
        if Qgis.QGIS_VERSION_INT < 10900:
            # qgis <= 1.8
            QSettings().setValue("/pdokservicesplugin/currenttab",
                                 QVariant(self.dlg.tabs.currentIndex()))
        else:
            QSettings().setValue("/pdokservicesplugin/currenttab",
                                 self.dlg.tabs.currentIndex())
        self.removePointer()

    def make_favourite(self, position):
        menu = QMenu()
        create_fav1_action = menu.addAction("Maak Deze Laag Favoriet 1")
        create_fav2_action = menu.addAction("Maak Deze Laag Favoriet 2")
        action = menu.exec_(self.dlg.servicesView.mapToGlobal(position))
        if action == create_fav1_action:
            QSettings().setValue("/pdokservicesplugin/favourite_1",
                                 self.currentLayer)
            self.set_favourite_action(self.favourite_1_action, 1)
        elif action == create_fav2_action:
            QSettings().setValue("/pdokservicesplugin/favourite_2",
                                 self.currentLayer)
            self.set_favourite_action(self.favourite_2_action, 2)

    def setupfq(self):
        """
        Setup the fq checkboxes in the gui, by looking into the settings for the
        'pdokservicesplugin/checkedfqs' key, which contains a list of type strings
        like ['weg','adres']
        """
        checked_fqs = self.getSettingsValue('checkedfqs', [])
        #self.info('setup fq: {}'.format(checked_fqs))
        if len(checked_fqs
               ) > 0:  # else there is not saved state... take gui defaults
            self.dlg.ui.cbx_gem.setChecked('gemeente' in checked_fqs)
            self.dlg.ui.cbx_wpl.setChecked('woonplaats' in checked_fqs)
            self.dlg.ui.cbx_weg.setChecked('weg' in checked_fqs)
            self.dlg.ui.cbx_pcd.setChecked('postcode' in checked_fqs)
            self.dlg.ui.cbx_adr.setChecked('adres' in checked_fqs)
            self.dlg.ui.cbx_pcl.setChecked('perceel' in checked_fqs)
            self.dlg.ui.cbx_hmp.setChecked('hectometerpaal' in checked_fqs)

    def createfq(self):
        """
        This creates a fq-string (Filter Query, see https://github.com/PDOK/locatieserver/wiki/Zoekvoorbeelden-Locatieserver)
        Based on the checkboxes in the dialog.
        Defaults to ''
        Example: 'fq=+type:adres+type:gemeente'  (only gemeente AND addresses)
        :return:
        """
        fqlist = []
        if self.dlg.ui.cbx_gem.isChecked():
            fqlist.append('gemeente')
        if self.dlg.ui.cbx_wpl.isChecked():
            fqlist.append('woonplaats')
        if self.dlg.ui.cbx_weg.isChecked():
            fqlist.append('weg')
        if self.dlg.ui.cbx_pcd.isChecked():
            fqlist.append('postcode')
        if self.dlg.ui.cbx_adr.isChecked():
            fqlist.append('adres')
        if self.dlg.ui.cbx_pcl.isChecked():
            fqlist.append('perceel')
        if self.dlg.ui.cbx_hmp.isChecked():
            fqlist.append('hectometerpaal')
        self.setSettingsValue('checkedfqs', fqlist)
        #self.info(self.getSettingsValue('checkedfqs', ['leeg?']))
        fq = ''
        if len(fqlist) > 0:
            fq = '&fq=+type:' + '+type:'.join(fqlist)
        return fq

    def suggest(self):
        self.dlg.ui.lookupinfo.setHtml('')
        search_text = self.dlg.geocoderSearch.text()
        if len(search_text) <= 1:
            # QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
            #     "meer input aub: {}".format(search_text)
            #     ), QMessageBox.Ok, QMessageBox.Ok)
            return
        # QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
        #     "zoeken: {}".format(search_text)
        # ), QMessageBox.Ok, QMessageBox.Ok)
        results = self.pdokgeocoder.suggest(search_text, self.createfq())
        if len(results) == 0:
            # ignore, as we are suggesting, maybe more characters will reveal something...
            return
        for result in results:
            #print address
            adrestekst = QStandardItem("%s" % (result["adrestekst"]))
            adrestekst.setData(result, Qt.UserRole)
            type = QStandardItem("%s" % (result["type"]))
            id = QStandardItem("%s" % (result["id"]))
            score = QStandardItem("%s" % (result["score"]))
            adrestekst.setData(result, Qt.UserRole)
            self.geocoderSourceModel.appendRow([adrestekst, type])
        self.geocoderSourceModel.setHeaderData(0, Qt.Horizontal, "Resultaat")
        self.geocoderSourceModel.setHeaderData(1, Qt.Horizontal, "Type")
        self.geocoderSourceModel.horizontalHeaderItem(0).setTextAlignment(
            Qt.AlignLeft)
        self.dlg.geocoderResultView.resizeColumnsToContents()
        self.dlg.geocoderResultView.horizontalHeader().setStretchLastSection(
            True)

    def geocode(self):
        self.dlg.geocoderSearch.setText(self.toolbarSearch.text())
        self.suggest()
        if self.dlg.geocoderResultView.model().rowCount() > 0:
            self.dlg.geocoderResultView.selectRow(0)
            self.zoomToAddress()
        else:
            QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
                "Niets gevonden.\nProbeer een andere spelling, of alleen postcode/huisnummer?\n\nSelecteer meer (Locatieserver) 'typen' in de PdokServicesPlugin dialoog.\n\nOf gebruik de 'PDOK geocoder'-tab in de PdokServicesPlugin dialoog."
                ), QMessageBox.Ok, QMessageBox.Ok)

    # def geocode(self):
    #     self.dlg.ui.lookupinfo.setHtml('')
    #     search_text = self.toolbarSearch.text()
    #     addresses = self.pdokgeocoder.search(search_text)
    #     if len(addresses) == 0:
    #         QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
    #             "Niets gevonden. Probeer een andere spelling of alleen postcode/huisnummer."
    #             ), QMessageBox.Ok, QMessageBox.Ok)
    #         return
    #     for address in addresses:
    #         #print address
    #         adrestekst = QStandardItem("%s" % (address["adrestekst"]))
    #         adrestekst.setData(address, Qt.UserRole)
    #         straat = QStandardItem("%s" % (address["straat"]))
    #         nummer = QStandardItem("%s" % (address["nummer"]))
    #         postcode = QStandardItem("%s" % (address["postcode"]))
    #         plaats = QStandardItem("%s" % (address["plaats"]))
    #         gemeente = QStandardItem("%s" % (address["gemeente"]))
    #         provincie = QStandardItem("%s" % (address["provincie"]))
    #         self.geocoderSourceModel.appendRow([adrestekst, straat, nummer, postcode, plaats, gemeente, provincie])
    #
    #     self.dlg.geocoderResultView.selectRow(0)
    #     self.zoomToAddress()
    #
    #     self.geocoderSourceModel.setHeaderData(0, Qt.Horizontal, "Resultaat")
    #     self.geocoderSourceModel.setHeaderData(1, Qt.Horizontal, "Straat")
    #     self.geocoderSourceModel.setHeaderData(2, Qt.Horizontal, "Nr")
    #     self.geocoderSourceModel.setHeaderData(3, Qt.Horizontal, "Postcode")
    #     self.geocoderSourceModel.setHeaderData(4, Qt.Horizontal, "Plaats")
    #     self.geocoderSourceModel.setHeaderData(5, Qt.Horizontal, "Gemeente")
    #     self.geocoderSourceModel.setHeaderData(6, Qt.Horizontal, "Provincie")
    #
    #     self.geocoderSourceModel.horizontalHeaderItem(0).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(1).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(2).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(3).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(4).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(5).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(6).setTextAlignment(Qt.AlignLeft)
    #
    #     self.dlg.geocoderResultView.resizeColumnsToContents()
    #     self.dlg.geocoderResultView.horizontalHeader().setStretchLastSection(True)

    def zoomToAddress(self):
        # get x,y from data of record
        self.removePointer()

        data = self.dlg.geocoderResultView.selectedIndexes()[0].data(
            Qt.UserRole)

        if 'centroide_rd' in data:  # free OR lookup service
            geom = QgsGeometry.fromWkt(data['centroide_rd'])
            adrestekst = data['adrestekst']
        else:
            # no centroid yet, probably only object id, retrieve it via lookup service
            id = data['id']
            data = self.pdokgeocoder.lookup(id)
            geom = QgsGeometry.fromWkt(data['centroide_rd'])
            adrestekst = data['adrestekst']
            lookup_data = data['data']
            lis = ''
            for key in lookup_data.keys():
                lis = lis + '<li>{}: {}</li>'.format(key, lookup_data[key])
            self.dlg.ui.lookupinfo.setHtml('<h4>{}</h4><lu>{}</lu>'.format(
                adrestekst, lis))

        # just always transform from 28992 to mapcanvas crs
        crs = self.iface.mapCanvas().mapSettings().destinationCrs()
        crs28992 = QgsCoordinateReferenceSystem()
        crs28992.createFromId(28992)
        crsTransform = QgsCoordinateTransform(crs28992, crs,
                                              QgsProject.instance())
        z = 1587
        if adrestekst.lower().startswith('adres'):
            z = 794
        elif adrestekst.lower().startswith('perceel'):
            z = 794
        elif adrestekst.lower().startswith('hectometer'):
            z = 1587
        elif adrestekst.lower().startswith('straat'):
            z = 3175
        elif adrestekst.lower().startswith('postcode'):
            z = 6350
        elif adrestekst.lower().startswith('woonplaats'):
            z = 25398
        elif adrestekst.lower().startswith('gemeente'):
            z = 50797
        elif adrestekst.lower().startswith('provincie'):
            z = 812750
        geom.transform(crsTransform)
        center = geom.asPoint()
        self.setPointer(center)
        # zoom to with center is actually setting a point rectangle and then zoom
        rect = QgsRectangle(center, center)
        self.iface.mapCanvas().setExtent(rect)
        self.iface.mapCanvas().zoomScale(z)
        self.iface.mapCanvas().refresh()

    def setPointer(self, point):
        self.removePointer()
        self.pointer = QgsVertexMarker(self.iface.mapCanvas())
        self.pointer.setColor(QColor(255, 255, 0))
        self.pointer.setIconSize(10)
        self.pointer.setPenWidth(5)
        self.pointer.setCenter(point)
        self.clean_action.setEnabled(True)

    def removePointer(self):
        if self.pointer is not None and self.pointer.scene() is not None:
            self.iface.mapCanvas().scene().removeItem(self.pointer)
            self.pointer = None
            self.clean_action.setEnabled(False)

    def info(self, msg=""):
        QgsMessageLog.logMessage('{}'.format(msg), 'PDOK-services Plugin',
                                 Qgis.Info)
コード例 #49
0
ファイル: AlgorithmDialogBase.py プロジェクト: nirvn/QGIS
class AlgorithmDialogBase(BASE, WIDGET):

    def __init__(self, alg):
        super(AlgorithmDialogBase, self).__init__(iface.mainWindow() if iface else None)
        self.setupUi(self)

        # don't collapse parameters panel
        self.splitter.setCollapsible(0, False)

        # add collapse button to splitter
        splitterHandle = self.splitter.handle(1)
        handleLayout = QVBoxLayout()
        handleLayout.setContentsMargins(0, 0, 0, 0)
        self.btnCollapse = QToolButton(splitterHandle)
        self.btnCollapse.setAutoRaise(True)
        self.btnCollapse.setFixedSize(12, 12)
        self.btnCollapse.setCursor(Qt.ArrowCursor)
        handleLayout.addWidget(self.btnCollapse)
        handleLayout.addStretch()
        splitterHandle.setLayout(handleLayout)

        self.settings = QgsSettings()
        self.splitter.restoreState(self.settings.value("/Processing/dialogBaseSplitter", QByteArray()))
        self.restoreGeometry(self.settings.value("/Processing/dialogBase", QByteArray()))
        self.splitterState = self.splitter.saveState()
        self.splitterChanged(0, 0)

        self.executed = False
        self.mainWidget = None
        self.alg = alg

        self.setWindowTitle(self.alg.displayName())

        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)

        # Rename OK button to Run
        self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok)
        self.btnRun.setText(self.tr('Run'))

        self.buttonCancel.setEnabled(False)

        self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)

        self.buttonBox.helpRequested.connect(self.openHelp)

        self.btnCollapse.clicked.connect(self.toggleCollapsed)
        self.splitter.splitterMoved.connect(self.splitterChanged)

        # desktop = QDesktopWidget()
        # if desktop.physicalDpiX() > 96:
        # self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96)

        algHelp = self.formatHelp(self.alg)
        if algHelp is None:
            self.textShortHelp.hide()
        else:
            self.textShortHelp.document().setDefaultStyleSheet('''.summary { margin-left: 10px; margin-right: 10px; }
                                                    h2 { color: #555555; padding-bottom: 15px; }
                                                    a { text-decoration: none; color: #3498db; font-weight: bold; }
                                                    p { color: #666666; }
                                                    b { color: #333333; }
                                                    dl dd { margin-bottom: 5px; }''')
            self.textShortHelp.setHtml(algHelp)

        def linkClicked(url):
            webbrowser.open(url.toString())

        self.textShortHelp.anchorClicked.connect(linkClicked)

        self.showDebug = ProcessingConfig.getSetting(
            ProcessingConfig.SHOW_DEBUG_IN_DIALOG)

    def createFeedback(self):
        feedback = AlgorithmDialogFeedback(self)
        feedback.progressChanged.connect(self.setPercentage)
        feedback.error.connect(self.error)
        feedback.progress_text.connect(self.setText)
        feedback.info.connect(self.setInfo)
        feedback.command_info.connect(self.setCommand)
        feedback.debug_info.connect(self.setDebugInfo)
        feedback.console_info.connect(self.setConsoleInfo)

        self.buttonCancel.clicked.connect(feedback.cancel)
        return feedback

    def formatHelp(self, alg):
        text = alg.shortHelpString()
        if not text:
            return None
        return "<h2>%s</h2>%s" % (alg.displayName(), "".join(["<p>%s</p>" % s for s in text.split("\n")]))

    def closeEvent(self, event):
        self._saveGeometry()
        super(AlgorithmDialogBase, self).closeEvent(event)

    def setMainWidget(self, widget):
        if self.mainWidget is not None:
            QgsProject.instance().layerWasAdded.disconnect(self.mainWidget.layerRegistryChanged)
            QgsProject.instance().layersWillBeRemoved.disconnect(self.mainWidget.layerRegistryChanged)
        self.mainWidget = widget
        self.tabWidget.widget(0).layout().addWidget(self.mainWidget)
        QgsProject.instance().layerWasAdded.connect(self.mainWidget.layerRegistryChanged)
        QgsProject.instance().layersWillBeRemoved.connect(self.mainWidget.layerRegistryChanged)

    def error(self, msg):
        self.setInfo(msg, True)
        self.resetGUI()
        self.tabWidget.setCurrentIndex(1)

    def resetGUI(self):
        self.lblProgress.setText('')
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)
        self.btnRun.setEnabled(True)
        self.btnClose.setEnabled(True)

    def setInfo(self, msg, error=False, escape_html=True):
        if error:
            self.txtLog.append('<span style="color:red">{}</span><br />'.format(msg, quote=False))
        elif escape_html:
            self.txtLog.append(html.escape(msg))
        else:
            self.txtLog.append(msg)

    def setCommand(self, cmd):
        if self.showDebug:
            self.txtLog.append('<code>{}<code>'.format(html.escape(cmd, quote=False)))

    def setDebugInfo(self, msg):
        if self.showDebug:
            self.txtLog.append('<span style="color:blue">{}</span>'.format(html.escape(msg, quote=False)))

    def setConsoleInfo(self, msg):
        if self.showDebug:
            self.txtLog.append('<code><span style="color:darkgray">{}</span></code>'.format(html.escape(msg, quote=False)))

    def setPercentage(self, value):
        if self.progressBar.maximum() == 0:
            self.progressBar.setMaximum(100)
        self.progressBar.setValue(value)

    def setText(self, text):
        self.lblProgress.setText(text)
        self.setInfo(text, False)

    def getParamValues(self):
        return {}

    def accept(self):
        pass

    def reject(self):
        self._saveGeometry()
        super(AlgorithmDialogBase, self).reject()

    def finish(self, successful, result, context, feedback):
        pass

    def toggleCollapsed(self):
        if self.helpCollapsed:
            self.splitter.restoreState(self.splitterState)
            self.btnCollapse.setArrowType(Qt.RightArrow)
        else:
            self.splitterState = self.splitter.saveState()
            self.splitter.setSizes([1, 0])
            self.btnCollapse.setArrowType(Qt.LeftArrow)
        self.helpCollapsed = not self.helpCollapsed

    def splitterChanged(self, pos, index):
        if self.splitter.sizes()[1] == 0:
            self.helpCollapsed = True
            self.btnCollapse.setArrowType(Qt.LeftArrow)
        else:
            self.helpCollapsed = False
            self.btnCollapse.setArrowType(Qt.RightArrow)

    def openHelp(self):
        algHelp = self.alg.helpUrl()
        if not algHelp:
            algHelp = QgsHelp.helpUrl("processing_algs/{}/{}".format(
                self.alg.provider().id(), self.alg.id())).toString()

        if algHelp not in [None, ""]:
            webbrowser.open(algHelp)

    def _saveGeometry(self):
        self.settings.setValue("/Processing/dialogBaseSplitter", self.splitter.saveState())
        self.settings.setValue("/Processing/dialogBase", self.saveGeometry())

    class InvalidParameterValue(Exception):

        def __init__(self, param, widget):
            (self.parameter, self.widget) = (param, widget)
コード例 #50
0
ファイル: ProcessingToolbox.py プロジェクト: dimespi/QGIS
    def addProviderActions(self, provider):
        if provider.id() in ProviderActions.actions:
            toolbarButton = QToolButton()
            toolbarButton.setObjectName('provideraction_' + provider.id())
            toolbarButton.setIcon(provider.icon())
            toolbarButton.setToolTip(provider.name())
            toolbarButton.setPopupMode(QToolButton.InstantPopup)

            actions = ProviderActions.actions[provider.id()]
            menu = QMenu(provider.name(), self)
            for action in actions:
                action.setData(self)
                act = QAction(action.name, menu)
                act.triggered.connect(action.execute)
                menu.addAction(act)
            toolbarButton.setMenu(menu)
            self.processingToolbar.addWidget(toolbarButton)
コード例 #51
0
ファイル: ParametersPanel.py プロジェクト: minorua/QGIS
    def initWidgets(self):
        # If there are advanced parameters — show corresponding groupbox
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                self.grpAdvanced.show()
                break
        # Create widgets and put them in layouts
        for param in self.alg.parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            if param.isDestination():
                continue
            else:
                desc = param.description()
                if isinstance(param, QgsProcessingParameterExtent):
                    desc += self.tr(' (xmin, xmax, ymin, ymax)')
                if isinstance(param, QgsProcessingParameterPoint):
                    desc += self.tr(' (x, y)')
                if param.flags() & QgsProcessingParameterDefinition.FlagOptional:
                    desc += self.tr(' [optional]')

                wrapper = WidgetWrapperFactory.create_wrapper(param, self.parent)
                self.wrappers[param.name()] = wrapper
                widget = wrapper.widget

                if widget is not None:
                    if isinstance(param, QgsProcessingParameterFeatureSource):
                        layout = QHBoxLayout()
                        layout.setSpacing(2)
                        layout.setMargin(0)
                        layout.addWidget(widget)
                        button = QToolButton()
                        icon = QIcon(os.path.join(pluginPath, 'images', 'iterate.png'))
                        button.setIcon(icon)
                        button.setToolTip(self.tr('Iterate over this layer, creating a separate output for every feature in the layer'))
                        button.setCheckable(True)
                        layout.addWidget(button)
                        layout.setAlignment(button, Qt.AlignTop)
                        self.iterateButtons[param.name()] = button
                        button.toggled.connect(self.buttonToggled)
                        widget = QWidget()
                        widget.setLayout(layout)

                    widget.setToolTip(param.toolTip())

                    if type(widget) is QCheckBox:
                        # checkbox widget - so description is embedded in widget rather than a separate
                        # label
                        widget.setText(desc)
                    else:
                        label = QLabel(desc)
                        # label.setToolTip(tooltip)
                        self.labels[param.name()] = label

                        if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                            self.layoutAdvanced.addWidget(label)
                        else:
                            self.layoutMain.insertWidget(
                                self.layoutMain.count() - 2, label)

                    if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced:
                        self.layoutAdvanced.addWidget(widget)
                    else:
                        self.layoutMain.insertWidget(
                            self.layoutMain.count() - 2, widget)

        for output in self.alg.destinationParameterDefinitions():
            if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue

            label = QLabel(output.description())
            widget = DestinationSelectionPanel(output, self.alg)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
            self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
            if isinstance(output, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterVectorDestination)):
                check = QCheckBox()
                check.setText(self.tr('Open output file after running algorithm'))
                check.setChecked(True)
                self.layoutMain.insertWidget(self.layoutMain.count() - 1, check)
                self.checkBoxes[output.name()] = check

            widget.setToolTip(param.toolTip())
            self.outputWidgets[output.name()] = widget

        for wrapper in list(self.wrappers.values()):
            wrapper.postInitialize(list(self.wrappers.values()))
コード例 #52
0
class AlgorithmDialogBase(BASE, WIDGET):
    def __init__(self, alg):
        super(AlgorithmDialogBase,
              self).__init__(iface.mainWindow() if iface else None)
        self.setupUi(self)

        # don't collapse parameters panel
        self.splitter.setCollapsible(0, False)

        # add collapse button to splitter
        splitterHandle = self.splitter.handle(1)
        handleLayout = QVBoxLayout()
        handleLayout.setContentsMargins(0, 0, 0, 0)
        self.btnCollapse = QToolButton(splitterHandle)
        self.btnCollapse.setAutoRaise(True)
        self.btnCollapse.setFixedSize(12, 12)
        self.btnCollapse.setCursor(Qt.ArrowCursor)
        handleLayout.addWidget(self.btnCollapse)
        handleLayout.addStretch()
        splitterHandle.setLayout(handleLayout)

        self.settings = QgsSettings()
        self.splitter.restoreState(
            self.settings.value("/Processing/dialogBaseSplitter",
                                QByteArray()))
        self.restoreGeometry(
            self.settings.value("/Processing/dialogBase", QByteArray()))
        self.splitterState = self.splitter.saveState()
        self.splitterChanged(0, 0)

        self.executed = False
        self.mainWidget = None
        self.alg = alg

        self.setWindowTitle(self.alg.displayName())

        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)

        # Rename OK button to Run
        self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok)
        self.btnRun.setText(self.tr('Run'))

        self.buttonCancel.setEnabled(False)

        self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)

        self.buttonBox.helpRequested.connect(self.openHelp)

        self.btnCollapse.clicked.connect(self.toggleCollapsed)
        self.splitter.splitterMoved.connect(self.splitterChanged)

        # desktop = QDesktopWidget()
        # if desktop.physicalDpiX() > 96:
        # self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96)

        algHelp = self.formatHelp(self.alg)
        if algHelp is None:
            self.textShortHelp.hide()
        else:
            self.textShortHelp.document().setDefaultStyleSheet(
                '''.summary { margin-left: 10px; margin-right: 10px; }
                                                    h2 { color: #555555; padding-bottom: 15px; }
                                                    a { text-decoration: none; color: #3498db; font-weight: bold; }
                                                    p { color: #666666; }
                                                    b { color: #333333; }
                                                    dl dd { margin-bottom: 5px; }'''
            )
            self.textShortHelp.setHtml(algHelp)

        def linkClicked(url):
            webbrowser.open(url.toString())

        self.textShortHelp.anchorClicked.connect(linkClicked)

        self.showDebug = ProcessingConfig.getSetting(
            ProcessingConfig.SHOW_DEBUG_IN_DIALOG)

    def createFeedback(self):
        feedback = AlgorithmDialogFeedback(self)
        feedback.progressChanged.connect(self.setPercentage)
        feedback.error.connect(self.error)
        feedback.progress_text.connect(self.setText)
        feedback.info.connect(self.setInfo)
        feedback.command_info.connect(self.setCommand)
        feedback.debug_info.connect(self.setDebugInfo)
        feedback.console_info.connect(self.setConsoleInfo)

        self.buttonCancel.clicked.connect(feedback.cancel)
        return feedback

    def formatHelp(self, alg):
        text = alg.shortHelpString()
        if not text:
            return None
        return "<h2>%s</h2>%s" % (alg.displayName(), "".join(
            ["<p>%s</p>" % s for s in text.split("\n")]))

    def closeEvent(self, event):
        self._saveGeometry()
        super(AlgorithmDialogBase, self).closeEvent(event)

    def setMainWidget(self, widget):
        if self.mainWidget is not None:
            QgsProject.instance().layerWasAdded.disconnect(
                self.mainWidget.layerRegistryChanged)
            QgsProject.instance().layersWillBeRemoved.disconnect(
                self.mainWidget.layerRegistryChanged)
        self.mainWidget = widget
        self.tabWidget.widget(0).layout().addWidget(self.mainWidget)
        QgsProject.instance().layerWasAdded.connect(
            self.mainWidget.layerRegistryChanged)
        QgsProject.instance().layersWillBeRemoved.connect(
            self.mainWidget.layerRegistryChanged)

    def error(self, msg):
        self.setInfo(msg, True)
        self.resetGUI()
        self.tabWidget.setCurrentIndex(1)

    def resetGUI(self):
        self.lblProgress.setText('')
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)
        self.btnRun.setEnabled(True)
        self.btnClose.setEnabled(True)

    def setInfo(self, msg, error=False, escape_html=True):
        if error:
            self.txtLog.append(
                '<span style="color:red">{}</span><br />'.format(msg,
                                                                 quote=False))
        elif escape_html:
            self.txtLog.append(html.escape(msg))
        else:
            self.txtLog.append(msg)

    def setCommand(self, cmd):
        if self.showDebug:
            self.txtLog.append('<code>{}<code>'.format(
                html.escape(cmd, quote=False)))

    def setDebugInfo(self, msg):
        if self.showDebug:
            self.txtLog.append('<span style="color:blue">{}</span>'.format(
                html.escape(msg, quote=False)))

    def setConsoleInfo(self, msg):
        if self.showDebug:
            self.txtLog.append(
                '<code><span style="color:darkgray">{}</span></code>'.format(
                    html.escape(msg, quote=False)))

    def setPercentage(self, value):
        if self.progressBar.maximum() == 0:
            self.progressBar.setMaximum(100)
        self.progressBar.setValue(value)

    def setText(self, text):
        self.lblProgress.setText(text)
        self.setInfo(text, False)

    def getParamValues(self):
        return {}

    def accept(self):
        pass

    def reject(self):
        self._saveGeometry()
        super(AlgorithmDialogBase, self).reject()

    def finish(self, successful, result, context, feedback):
        pass

    def toggleCollapsed(self):
        if self.helpCollapsed:
            self.splitter.restoreState(self.splitterState)
            self.btnCollapse.setArrowType(Qt.RightArrow)
        else:
            self.splitterState = self.splitter.saveState()
            self.splitter.setSizes([1, 0])
            self.btnCollapse.setArrowType(Qt.LeftArrow)
        self.helpCollapsed = not self.helpCollapsed

    def splitterChanged(self, pos, index):
        if self.splitter.sizes()[1] == 0:
            self.helpCollapsed = True
            self.btnCollapse.setArrowType(Qt.LeftArrow)
        else:
            self.helpCollapsed = False
            self.btnCollapse.setArrowType(Qt.RightArrow)

    def openHelp(self):
        algHelp = self.alg.helpUrl()
        if not algHelp:
            algHelp = QgsHelp.helpUrl("processing_algs/{}/{}".format(
                self.alg.provider().id(), self.alg.id())).toString()

        if algHelp not in [None, ""]:
            webbrowser.open(algHelp)

    def _saveGeometry(self):
        self.settings.setValue("/Processing/dialogBaseSplitter",
                               self.splitter.saveState())
        self.settings.setValue("/Processing/dialogBase", self.saveGeometry())

    class InvalidParameterValue(Exception):
        def __init__(self, param, widget):
            (self.parameter, self.widget) = (param, widget)
コード例 #53
0
ファイル: ModelerDialog.py プロジェクト: dwsilk/QGIS
    def __init__(self, model=None):
        super().__init__(None)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.setupUi(self)

        self._variables_scope = None

        # LOTS of bug reports when we include the dock creation in the UI file
        # see e.g. #16428, #19068
        # So just roll it all by hand......!
        self.propertiesDock = QgsDockWidget(self)
        self.propertiesDock.setFeatures(
            QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.propertiesDock.setObjectName("propertiesDock")
        propertiesDockContents = QWidget()
        self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents)
        self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0)
        self.verticalDockLayout_1.setSpacing(0)
        self.scrollArea_1 = QgsScrollArea(propertiesDockContents)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.scrollArea_1.sizePolicy().hasHeightForWidth())
        self.scrollArea_1.setSizePolicy(sizePolicy)
        self.scrollArea_1.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_1.setFrameShape(QFrame.NoFrame)
        self.scrollArea_1.setFrameShadow(QFrame.Plain)
        self.scrollArea_1.setWidgetResizable(True)
        self.scrollAreaWidgetContents_1 = QWidget()
        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1)
        self.gridLayout.setContentsMargins(6, 6, 6, 6)
        self.gridLayout.setSpacing(4)
        self.label_1 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
        self.textName = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textName, 0, 1, 1, 1)
        self.label_2 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1)
        self.label_1.setText(self.tr("Name"))
        self.textName.setToolTip(self.tr("Enter model name here"))
        self.label_2.setText(self.tr("Group"))
        self.textGroup.setToolTip(self.tr("Enter group name here"))
        self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1)
        self.verticalDockLayout_1.addWidget(self.scrollArea_1)
        self.propertiesDock.setWidget(propertiesDockContents)
        self.propertiesDock.setWindowTitle(self.tr("Model Properties"))

        self.inputsDock = QgsDockWidget(self)
        self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.inputsDock.setObjectName("inputsDock")
        self.inputsDockContents = QWidget()
        self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_2 = QgsScrollArea(self.inputsDockContents)
        sizePolicy.setHeightForWidth(self.scrollArea_2.sizePolicy().hasHeightForWidth())
        self.scrollArea_2.setSizePolicy(sizePolicy)
        self.scrollArea_2.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_2.setFrameShape(QFrame.NoFrame)
        self.scrollArea_2.setFrameShadow(QFrame.Plain)
        self.scrollArea_2.setWidgetResizable(True)
        self.scrollAreaWidgetContents_2 = QWidget()
        self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.inputsTree = QTreeWidget(self.scrollAreaWidgetContents_2)
        self.inputsTree.setAlternatingRowColors(True)
        self.inputsTree.header().setVisible(False)
        self.verticalLayout.addWidget(self.inputsTree)
        self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
        self.verticalLayout_3.addWidget(self.scrollArea_2)
        self.inputsDock.setWidget(self.inputsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock)
        self.inputsDock.setWindowTitle(self.tr("Inputs"))

        self.algorithmsDock = QgsDockWidget(self)
        self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.algorithmsDock.setObjectName("algorithmsDock")
        self.algorithmsDockContents = QWidget()
        self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents)
        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents)
        sizePolicy.setHeightForWidth(self.scrollArea_3.sizePolicy().hasHeightForWidth())
        self.scrollArea_3.setSizePolicy(sizePolicy)
        self.scrollArea_3.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_3.setFrameShape(QFrame.NoFrame)
        self.scrollArea_3.setFrameShadow(QFrame.Plain)
        self.scrollArea_3.setWidgetResizable(True)
        self.scrollAreaWidgetContents_3 = QWidget()
        self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setSpacing(4)
        self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.addWidget(self.searchBox)
        self.algorithmTree = QgsProcessingToolboxTreeView(None,
                                                          QgsApplication.processingRegistry())
        self.algorithmTree.setAlternatingRowColors(True)
        self.algorithmTree.header().setVisible(False)
        self.verticalLayout_2.addWidget(self.algorithmTree)
        self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
        self.verticalLayout_4.addWidget(self.scrollArea_3)
        self.algorithmsDock.setWidget(self.algorithmsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock)
        self.algorithmsDock.setWindowTitle(self.tr("Algorithms"))
        self.searchBox.setToolTip(self.tr("Enter algorithm name to filter list"))
        self.searchBox.setShowSearchIcon(True)

        self.variables_dock = QgsDockWidget(self)
        self.variables_dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.variables_dock.setObjectName("variablesDock")
        self.variables_dock_contents = QWidget()
        vl_v = QVBoxLayout()
        vl_v.setContentsMargins(0, 0, 0, 0)
        self.variables_editor = QgsVariableEditorWidget()
        vl_v.addWidget(self.variables_editor)
        self.variables_dock_contents.setLayout(vl_v)
        self.variables_dock.setWidget(self.variables_dock_contents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.variables_dock)
        self.variables_dock.setWindowTitle(self.tr("Variables"))
        self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock)
        self.tabifyDockWidget(self.propertiesDock, self.variables_dock)
        self.variables_editor.scopeChanged.connect(self.variables_changed)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.centralWidget().layout().insertWidget(0, self.bar)

        try:
            self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging)
        except:
            pass

        if iface is not None:
            self.mToolbar.setIconSize(iface.iconSize())
            self.setStyleSheet(iface.mainWindow().styleSheet())

        self.toolbutton_export_to_script = QToolButton()
        self.toolbutton_export_to_script.setPopupMode(QToolButton.InstantPopup)
        self.export_to_script_algorithm_action = QAction(QCoreApplication.translate('ModelerDialog', 'Export as Script Algorithm…'))
        self.toolbutton_export_to_script.addActions([self.export_to_script_algorithm_action])
        self.mToolbar.insertWidget(self.mActionExportImage, self.toolbutton_export_to_script)
        self.export_to_script_algorithm_action.triggered.connect(self.export_as_script_algorithm)

        self.mActionOpen.setIcon(
            QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
        self.mActionSave.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSave.svg'))
        self.mActionSaveAs.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSaveAs.svg'))
        self.mActionSaveInProject.setIcon(
            QgsApplication.getThemeIcon('/mAddToProject.svg'))
        self.mActionZoomActual.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomActual.svg'))
        self.mActionZoomIn.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomIn.svg'))
        self.mActionZoomOut.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomOut.svg'))
        self.mActionExportImage.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg'))
        self.mActionZoomToItems.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg'))
        self.mActionExportPdf.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg'))
        self.mActionExportSvg.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg'))
        self.toolbutton_export_to_script.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPython.svg'))
        self.mActionEditHelp.setIcon(
            QgsApplication.getThemeIcon('/mActionEditHelpContent.svg'))
        self.mActionRun.setIcon(
            QgsApplication.getThemeIcon('/mActionStart.svg'))

        self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock)
        self.tabifyDockWidget(self.inputsDock, self.algorithmsDock)
        self.inputsDock.raise_()

        self.setWindowFlags(Qt.WindowMinimizeButtonHint |
                            Qt.WindowMaximizeButtonHint |
                            Qt.WindowCloseButtonHint)

        settings = QgsSettings()
        self.restoreState(settings.value("/Processing/stateModeler", QByteArray()))
        self.restoreGeometry(settings.value("/Processing/geometryModeler", QByteArray()))

        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))

        self.view.setScene(self.scene)
        self.view.setAcceptDrops(True)
        self.view.ensureVisible(0, 0, 10, 10)
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96, QgsApplication.desktop().logicalDpiX() / 96)

        def _dragEnterEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'):
                event.acceptProposedAction()
            else:
                event.ignore()

        def _dropEvent(event):
            def alg_dropped(algorithm_id, pos):
                alg = QgsApplication.processingRegistry().createAlgorithmById(algorithm_id)
                if alg is not None:
                    self._addAlgorithm(alg, pos)
                else:
                    assert False, algorithm_id

            def input_dropped(id, pos):
                if id in [param.id() for param in QgsApplication.instance().processingRegistry().parameterTypes()]:
                    self.addInputOfType(itemId, pos)

            if event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'):
                data = event.mimeData().data('application/x-vnd.qgis.qgis.algorithmid')
                stream = QDataStream(data, QIODevice.ReadOnly)
                algorithm_id = stream.readQString()
                QTimer.singleShot(0, lambda id=algorithm_id, pos=self.view.mapToScene(event.pos()): alg_dropped(id, pos))
                event.accept()
            elif event.mimeData().hasText():
                itemId = event.mimeData().text()
                QTimer.singleShot(0, lambda id=itemId, pos=self.view.mapToScene(event.pos()): input_dropped(id, pos))
                event.accept()
            else:
                event.ignore()

        def _dragMoveEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'):
                event.accept()
            else:
                event.ignore()

        def _wheelEvent(event):
            self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

            settings = QgsSettings()
            factor = settings.value('/qgis/zoom_favor', 2.0)

            # "Normal" mouse has an angle delta of 120, precision mouses provide data
            # faster, in smaller steps
            factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y())

            if (event.modifiers() == Qt.ControlModifier):
                factor = 1.0 + (factor - 1.0) / 20.0

            if event.angleDelta().y() < 0:
                factor = 1 / factor

            self.view.scale(factor, factor)

        def _enterEvent(e):
            QGraphicsView.enterEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mouseReleaseEvent(e):
            QGraphicsView.mouseReleaseEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mousePressEvent(e):
            if e.button() == Qt.MidButton:
                self.previousMousePos = e.pos()
            else:
                QGraphicsView.mousePressEvent(self.view, e)

        def _mouseMoveEvent(e):
            if e.buttons() == Qt.MidButton:
                offset = self.previousMousePos - e.pos()
                self.previousMousePos = e.pos()

                self.view.verticalScrollBar().setValue(self.view.verticalScrollBar().value() + offset.y())
                self.view.horizontalScrollBar().setValue(self.view.horizontalScrollBar().value() + offset.x())
            else:
                QGraphicsView.mouseMoveEvent(self.view, e)

        self.view.setDragMode(QGraphicsView.ScrollHandDrag)
        self.view.dragEnterEvent = _dragEnterEvent
        self.view.dropEvent = _dropEvent
        self.view.dragMoveEvent = _dragMoveEvent
        self.view.wheelEvent = _wheelEvent
        self.view.enterEvent = _enterEvent
        self.view.mousePressEvent = _mousePressEvent
        self.view.mouseMoveEvent = _mouseMoveEvent

        def _mimeDataInput(items):
            mimeData = QMimeData()
            text = items[0].data(0, Qt.UserRole)
            mimeData.setText(text)
            return mimeData

        self.inputsTree.mimeData = _mimeDataInput

        self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
        self.inputsTree.setDropIndicatorShown(True)

        self.algorithms_model = ModelerToolboxModel(self, QgsApplication.processingRegistry())
        self.algorithmTree.setToolboxProxyModel(self.algorithms_model)
        self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly)
        self.algorithmTree.setDropIndicatorShown(True)

        filters = QgsProcessingToolboxProxyModel.Filters(QgsProcessingToolboxProxyModel.FilterModeler)
        if ProcessingConfig.getSetting(ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES):
            filters |= QgsProcessingToolboxProxyModel.FilterShowKnownIssues
        self.algorithmTree.setFilters(filters)

        if hasattr(self.searchBox, 'setPlaceholderText'):
            self.searchBox.setPlaceholderText(QCoreApplication.translate('ModelerDialog', 'Search…'))
        if hasattr(self.textName, 'setPlaceholderText'):
            self.textName.setPlaceholderText(self.tr('Enter model name here'))
        if hasattr(self.textGroup, 'setPlaceholderText'):
            self.textGroup.setPlaceholderText(self.tr('Enter group name here'))

        # Connect signals and slots
        self.inputsTree.doubleClicked.connect(self.addInput)
        self.searchBox.textChanged.connect(self.algorithmTree.setFilterString)
        self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

        # Ctrl+= should also trigger a zoom in action
        ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self)
        ctrlEquals.activated.connect(self.zoomIn)

        self.mActionOpen.triggered.connect(self.openModel)
        self.mActionSave.triggered.connect(self.save)
        self.mActionSaveAs.triggered.connect(self.saveAs)
        self.mActionSaveInProject.triggered.connect(self.saveInProject)
        self.mActionZoomIn.triggered.connect(self.zoomIn)
        self.mActionZoomOut.triggered.connect(self.zoomOut)
        self.mActionZoomActual.triggered.connect(self.zoomActual)
        self.mActionZoomToItems.triggered.connect(self.zoomToItems)
        self.mActionExportImage.triggered.connect(self.exportAsImage)
        self.mActionExportPdf.triggered.connect(self.exportAsPdf)
        self.mActionExportSvg.triggered.connect(self.exportAsSvg)
        #self.mActionExportPython.triggered.connect(self.exportAsPython)
        self.mActionEditHelp.triggered.connect(self.editHelp)
        self.mActionRun.triggered.connect(self.runModel)

        if model is not None:
            self.model = model.create()
            self.model.setSourceFilePath(model.sourceFilePath())
            self.textGroup.setText(self.model.group())
            self.textName.setText(self.model.displayName())
            self.repaintModel()

        else:
            self.model = QgsProcessingModelAlgorithm()
            self.model.setProvider(QgsApplication.processingRegistry().providerById('model'))
        self.update_variables_gui()

        self.fillInputsTree()

        self.view.centerOn(0, 0)
        self.help = None

        self.hasChanged = False
コード例 #54
0
ファイル: console.py プロジェクト: cayetanobv/QGIS
class PythonConsoleWidget(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QgsSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        # ------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        # self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        # self.splitterObj.setSizes([0, 0])
        # self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        # self.splitterEditor.addWidget(self.widgetEditor)
        # self.splitterObj.addWidget(self.listClassMethod)
        # self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        # ----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        # ------------------Toolbar Editor-------------------------------------

        # Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open Script...")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.png"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in External Editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        # Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.png"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        # Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.png"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        # Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCut.svg"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        # Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCopy.svg"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        # Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditPaste.svg"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        # Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.png"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        # Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.png"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        # Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.png"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        # Action for Object browser
        objList = QCoreApplication.translate("PythonConsole", "Object Inspector...")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp",
                                                             False, type=bool))
        self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        # Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        # ----------------Toolbar Console-------------------------------------

        # Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show Editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        # Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear Console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.png"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        # Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Options...")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.png"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        # Action menu for class
        actionClassBt = QCoreApplication.translate("PythonConsole", "Import Class")
        self.actionClass = QAction(self)
        self.actionClass.setCheckable(False)
        self.actionClass.setEnabled(True)
        self.actionClass.setIcon(QgsApplication.getThemeIcon("console/iconClassConsole.png"))
        self.actionClass.setMenuRole(QAction.PreferencesRole)
        self.actionClass.setIconVisibleInMenu(True)
        self.actionClass.setToolTip(actionClassBt)
        self.actionClass.setText(actionClassBt)
        # Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run Command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(QgsApplication.getThemeIcon("console/iconRunConsole.png"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        # Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help...")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.png"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(QSize(16, 16))
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.actionClass)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(QSize(16, 16))
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        # Menu Import Class
        default_command = {
            (QCoreApplication.translate("PythonConsole", "Import Processing Class"),
             QgsApplication.getThemeIcon("console/iconProcessingConsole.png")):
            ["import processing"],
            (QCoreApplication.translate("PythonConsole", "Import PyQt.QtCore Class"),
             QgsApplication.getThemeIcon("console/iconQtCoreConsole.png")):
            ["from qgis.PyQt.QtCore import *"],
            (QCoreApplication.translate("PythonConsole", "Import PyQt.QtGui Class"),
             QgsApplication.getThemeIcon("console/iconQtGuiConsole.png")):
            ["from qgis.PyQt.QtGui import *", "from qgis.PyQt.QtWidgets import *"]
        }

        self.classMenu = QMenu()
        for (title, icon), commands in list(default_command.items()):
            action = self.classMenu.addAction(icon, title)
            action.triggered.connect(partial(self.shell.commandConsole, commands))

        cM = self.toolBar.widgetForAction(self.actionClass)
        cM.setMenu(self.classMenu)
        cM.setPopupMode(QToolButton.InstantPopup)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        # ------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        #  Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...")

        self.lineEditFind.setPlaceholderText(placeHolderTxt)
        self.findNextButton = QToolButton()
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.png"))
        self.findNextButton.setIconSize(QSize(24, 24))
        self.findNextButton.setAutoRaise(True)
        self.findPrevButton = QToolButton()
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.png"))
        self.findPrevButton.setIconSize(QSize(24, 24))
        self.findPrevButton.setAutoRaise(True)
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)
        self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1)
        self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1)
        self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1)
        self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1)
        self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1)
        self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1)

        # ------------ Add first Tab in Editor -------------------------------

        # self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        # ------------ Signal -------------------------------

        self.findTextButton.triggered.connect(self._toggleFind)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.listClassMethod.itemClicked.connect(self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findNext)
        self.findNextButton.clicked.connect(self._findNext)
        self.findPrevButton.clicked.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

        self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._openFind)

        self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor)
        self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findNextScut.activated.connect(self._findNext)

        self.findPreviousScut = QShortcut(QKeySequence.FindPrevious, self.widgetEditor)
        self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findPreviousScut.activated.connect(self._findPrev)

        # Escape on editor hides the find bar
        self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._closeFind)

    def _toggleFind(self):
        self.tabEditorWidget.currentWidget().newEditor.toggleFindWidget()

    def _openFind(self):
        self.tabEditorWidget.currentWidget().newEditor.openFindWidget()

    def _closeFind(self):
        self.tabEditorWidget.currentWidget().newEditor.closeFindWidget()

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
            self.tabEditorWidget.currentWidget().newEditor.findText(True, showMessage=False, findFirst=True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(objName, linenr)

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFileExtEditor(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        path = tabWidget.path
        import subprocess
        try:
            subprocess.Popen([os.environ['EDITOR'], path])
        except KeyError:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.homePath())
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList, selected_filter = QFileDialog.getOpenFileNames(
            self, openFileTr, lastDirPath, "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError) as error:
            msgText = QCoreApplication.translate('PythonConsole',
                                                 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                              error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)

    def saveAsScriptFile(self, index=None):
        tabWidget = self.tabEditorWidget.currentWidget()
        if not index:
            index = self.tabEditorWidget.currentIndex()
        if not tabWidget.path:
            fileName = self.tabEditorWidget.tabText(index) + '.py'
            folder = self.settings.value("pythonConsole/lastDirPath", QDir.home())
            pathFileName = os.path.join(folder, fileName)
            fileNone = True
        else:
            pathFileName = tabWidget.path
            fileNone = False
        saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As")
        filename, filter = QFileDialog.getSaveFileName(self,
                                                       saveAsFileTr,
                                                       pathFileName, "Script file (*.py)")
        if filename:
            try:
                tabWidget.save(filename)
            except (IOError, OSError) as error:
                msgText = QCoreApplication.translate('PythonConsole',
                                                     'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                                  error.strerror)
                self.callWidgetMessageBarEditor(msgText, 2, False)
                if fileNone:
                    tabWidget.path = None
                else:
                    tabWidget.path = pathFileName
                return

            if not fileNone:
                self.updateTabListScript(pathFileName, action='remove')

    def openHelp(self):
        QgsContextHelp.run("PythonConsole")

    def openSettings(self):
        if optionsDialog(self).exec_():
            self.shell.refreshSettingsShell()
            self.shellOut.refreshSettingsOutput()
            self.tabEditorWidget.refreshSettingsEditor()

    def callWidgetMessageBar(self, text):
        self.shellOut.widgetMessageBar(iface, text)

    def callWidgetMessageBarEditor(self, text, level, timed):
        self.tabEditorWidget.widgetMessageBar(iface, text, level, timed)

    def updateTabListScript(self, script, action=None):
        if action == 'remove':
            self.tabListScript.remove(script)
        elif action == 'append':
            if not self.tabListScript:
                self.tabListScript = []
            if script not in self.tabListScript:
                self.tabListScript.append(script)
        else:
            self.tabListScript = []
        self.settings.setValue("pythonConsole/tabScripts",
                               self.tabListScript)

    def saveSettingsConsole(self):
        self.settings.setValue("pythonConsole/splitterConsole", self.splitter.saveState())
        self.settings.setValue("pythonConsole/splitterObj", self.splitterObj.saveState())
        self.settings.setValue("pythonConsole/splitterEditor", self.splitterEditor.saveState())

        self.shell.writeHistoryFile(True)

    def restoreSettingsConsole(self):
        storedTabScripts = self.settings.value("pythonConsole/tabScripts", [])
        self.tabListScript = storedTabScripts
        self.splitter.restoreState(self.settings.value("pythonConsole/splitterConsole", QByteArray()))
        self.splitterEditor.restoreState(self.settings.value("pythonConsole/splitterEditor", QByteArray()))
        self.splitterObj.restoreState(self.settings.value("pythonConsole/splitterObj", QByteArray()))
コード例 #55
0
ファイル: wrappers.py プロジェクト: ashokdahal/QGIS
    def createWidget(self):
        if self.dialogType == DIALOG_STANDARD:
            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            self.combo = QgsMapLayerComboBox()
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)

            widget.setLayout(layout)

            filters = QgsMapLayerProxyModel.Filters()
            if self.param.datatype == [-1] or -1 in self.param.datatype:
                filters = QgsMapLayerProxyModel.HasGeometry
            if QgsWkbTypes.PointGeometry in self.param.datatype:
                filters |= QgsMapLayerProxyModel.PointLayer
            if QgsWkbTypes.LineGeometry in self.param.datatype:
                filters |= QgsMapLayerProxyModel.LineLayer
            if QgsWkbTypes.PolygonGeometry in self.param.datatype:
                filters |= QgsMapLayerProxyModel.PolygonLayer

            try:
                if iface.activeLayer().type() == QgsMapLayer.VectorLayer:
                    self.combo.setLayer(iface.activeLayer())
            except:
                pass

            if self.param.optional:
                self.combo.setAllowEmptyLayer(True)
            if ProcessingConfig.getSetting(ProcessingConfig.SHOW_CRS_DEF):
                self.combo.setShowCrs(True)

            self.combo.setFilters(filters)
            self.combo.setExcludedProviders(['grass'])

            self.combo.currentIndexChanged.connect(
                lambda: self.widgetValueHasChanged.emit(self))
            self.combo.currentTextChanged.connect(
                lambda: self.widgetValueHasChanged.emit(self))
            return widget

        elif self.dialogType == DIALOG_BATCH:
            widget = BatchInputSelectionPanel(self.param, self.row, self.col,
                                              self.dialog)
            widget.valueChanged.connect(
                lambda: self.widgetValueHasChanged.emit(self))
            return widget
        else:
            self.combo = QComboBox()
            layers = self.dialog.getAvailableValuesOfType(
                ParameterVector, OutputVector)
            self.combo.setEditable(True)
            for layer in layers:
                self.combo.addItem(self.dialog.resolveValueDescription(layer),
                                   layer)
            if self.param.optional:
                self.combo.setEditText("")

            widget = QWidget()
            layout = QHBoxLayout()
            layout.setMargin(0)
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(2)
            layout.addWidget(self.combo)
            btn = QToolButton()
            btn.setText('...')
            btn.setToolTip(self.tr("Select file"))
            btn.clicked.connect(self.selectFile)
            layout.addWidget(btn)
            widget.setLayout(layout)
            return widget
コード例 #56
0
    def __init__(self, alg):
        super(AlgorithmDialogBase,
              self).__init__(iface.mainWindow() if iface else None)
        self.setupUi(self)

        # don't collapse parameters panel
        self.splitter.setCollapsible(0, False)

        # add collapse button to splitter
        splitterHandle = self.splitter.handle(1)
        handleLayout = QVBoxLayout()
        handleLayout.setContentsMargins(0, 0, 0, 0)
        self.btnCollapse = QToolButton(splitterHandle)
        self.btnCollapse.setAutoRaise(True)
        self.btnCollapse.setFixedSize(12, 12)
        self.btnCollapse.setCursor(Qt.ArrowCursor)
        handleLayout.addWidget(self.btnCollapse)
        handleLayout.addStretch()
        splitterHandle.setLayout(handleLayout)

        self.settings = QgsSettings()
        self.splitter.restoreState(
            self.settings.value("/Processing/dialogBaseSplitter",
                                QByteArray()))
        self.restoreGeometry(
            self.settings.value("/Processing/dialogBase", QByteArray()))
        self.splitterState = self.splitter.saveState()
        self.splitterChanged(0, 0)

        self.executed = False
        self.mainWidget = None
        self.alg = alg

        self.setWindowTitle(self.alg.displayName())

        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)

        # Rename OK button to Run
        self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok)
        self.btnRun.setText(self.tr('Run'))

        self.buttonCancel.setEnabled(False)

        self.btnClose = self.buttonBox.button(QDialogButtonBox.Close)

        self.buttonBox.helpRequested.connect(self.openHelp)

        self.btnCollapse.clicked.connect(self.toggleCollapsed)
        self.splitter.splitterMoved.connect(self.splitterChanged)

        # desktop = QDesktopWidget()
        # if desktop.physicalDpiX() > 96:
        # self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96)

        algHelp = self.formatHelp(self.alg)
        if algHelp is None:
            self.textShortHelp.hide()
        else:
            self.textShortHelp.document().setDefaultStyleSheet(
                '''.summary { margin-left: 10px; margin-right: 10px; }
                                                    h2 { color: #555555; padding-bottom: 15px; }
                                                    a { text-decoration: none; color: #3498db; font-weight: bold; }
                                                    p { color: #666666; }
                                                    b { color: #333333; }
                                                    dl dd { margin-bottom: 5px; }'''
            )
            self.textShortHelp.setHtml(algHelp)

        def linkClicked(url):
            webbrowser.open(url.toString())

        self.textShortHelp.anchorClicked.connect(linkClicked)

        self.showDebug = ProcessingConfig.getSetting(
            ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
コード例 #57
0
ファイル: ProcessingToolbox.py プロジェクト: tomkralidis/QGIS
    def addProviderActions(self, provider):
        if provider.id() in ProviderActions.actions:
            toolbarButton = QToolButton()
            toolbarButton.setObjectName('provideraction_' + provider.id())
            toolbarButton.setIcon(provider.icon())
            toolbarButton.setToolTip(provider.name())
            toolbarButton.setPopupMode(QToolButton.InstantPopup)

            actions = ProviderActions.actions[provider.id()]
            menu = QMenu(provider.name(), self)
            for action in actions:
                action.setData(self)
                act = QAction(action.name, menu)
                act.triggered.connect(action.execute)
                menu.addAction(act)
            toolbarButton.setMenu(menu)
            self.processingToolbar.addWidget(toolbarButton)
コード例 #58
0
ファイル: ModelerDialog.py プロジェクト: ceholden/QGIS
class ModelerDialog(BASE, WIDGET):
    ALG_ITEM = 'ALG_ITEM'
    PROVIDER_ITEM = 'PROVIDER_ITEM'
    GROUP_ITEM = 'GROUP_ITEM'

    NAME_ROLE = Qt.UserRole
    TAG_ROLE = Qt.UserRole + 1
    TYPE_ROLE = Qt.UserRole + 2

    CANVAS_SIZE = 4000

    update_model = pyqtSignal()

    def __init__(self, model=None):
        super().__init__(None)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.setupUi(self)

        self._variables_scope = None

        # LOTS of bug reports when we include the dock creation in the UI file
        # see e.g. #16428, #19068
        # So just roll it all by hand......!
        self.propertiesDock = QgsDockWidget(self)
        self.propertiesDock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.propertiesDock.setObjectName("propertiesDock")
        propertiesDockContents = QWidget()
        self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents)
        self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0)
        self.verticalDockLayout_1.setSpacing(0)
        self.scrollArea_1 = QgsScrollArea(propertiesDockContents)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.scrollArea_1.sizePolicy().hasHeightForWidth())
        self.scrollArea_1.setSizePolicy(sizePolicy)
        self.scrollArea_1.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_1.setFrameShape(QFrame.NoFrame)
        self.scrollArea_1.setFrameShadow(QFrame.Plain)
        self.scrollArea_1.setWidgetResizable(True)
        self.scrollAreaWidgetContents_1 = QWidget()
        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1)
        self.gridLayout.setContentsMargins(6, 6, 6, 6)
        self.gridLayout.setSpacing(4)
        self.label_1 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
        self.textName = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textName, 0, 1, 1, 1)
        self.label_2 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1)
        self.label_1.setText(self.tr("Name"))
        self.textName.setToolTip(self.tr("Enter model name here"))
        self.label_2.setText(self.tr("Group"))
        self.textGroup.setToolTip(self.tr("Enter group name here"))
        self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1)
        self.verticalDockLayout_1.addWidget(self.scrollArea_1)
        self.propertiesDock.setWidget(propertiesDockContents)
        self.propertiesDock.setWindowTitle(self.tr("Model Properties"))

        self.inputsDock = QgsDockWidget(self)
        self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable
                                    | QDockWidget.DockWidgetMovable)
        self.inputsDock.setObjectName("inputsDock")
        self.inputsDockContents = QWidget()
        self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_2 = QgsScrollArea(self.inputsDockContents)
        sizePolicy.setHeightForWidth(
            self.scrollArea_2.sizePolicy().hasHeightForWidth())
        self.scrollArea_2.setSizePolicy(sizePolicy)
        self.scrollArea_2.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_2.setFrameShape(QFrame.NoFrame)
        self.scrollArea_2.setFrameShadow(QFrame.Plain)
        self.scrollArea_2.setWidgetResizable(True)
        self.scrollAreaWidgetContents_2 = QWidget()
        self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.inputsTree = QTreeWidget(self.scrollAreaWidgetContents_2)
        self.inputsTree.setAlternatingRowColors(True)
        self.inputsTree.header().setVisible(False)
        self.verticalLayout.addWidget(self.inputsTree)
        self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
        self.verticalLayout_3.addWidget(self.scrollArea_2)
        self.inputsDock.setWidget(self.inputsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock)
        self.inputsDock.setWindowTitle(self.tr("Inputs"))

        self.algorithmsDock = QgsDockWidget(self)
        self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.algorithmsDock.setObjectName("algorithmsDock")
        self.algorithmsDockContents = QWidget()
        self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents)
        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents)
        sizePolicy.setHeightForWidth(
            self.scrollArea_3.sizePolicy().hasHeightForWidth())
        self.scrollArea_3.setSizePolicy(sizePolicy)
        self.scrollArea_3.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_3.setFrameShape(QFrame.NoFrame)
        self.scrollArea_3.setFrameShadow(QFrame.Plain)
        self.scrollArea_3.setWidgetResizable(True)
        self.scrollAreaWidgetContents_3 = QWidget()
        self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setSpacing(4)
        self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.addWidget(self.searchBox)
        self.algorithmTree = QgsProcessingToolboxTreeView(
            None, QgsApplication.processingRegistry())
        self.algorithmTree.setAlternatingRowColors(True)
        self.algorithmTree.header().setVisible(False)
        self.verticalLayout_2.addWidget(self.algorithmTree)
        self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
        self.verticalLayout_4.addWidget(self.scrollArea_3)
        self.algorithmsDock.setWidget(self.algorithmsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock)
        self.algorithmsDock.setWindowTitle(self.tr("Algorithms"))
        self.searchBox.setToolTip(
            self.tr("Enter algorithm name to filter list"))
        self.searchBox.setShowSearchIcon(True)

        self.variables_dock = QgsDockWidget(self)
        self.variables_dock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.variables_dock.setObjectName("variablesDock")
        self.variables_dock_contents = QWidget()
        vl_v = QVBoxLayout()
        vl_v.setContentsMargins(0, 0, 0, 0)
        self.variables_editor = QgsVariableEditorWidget()
        vl_v.addWidget(self.variables_editor)
        self.variables_dock_contents.setLayout(vl_v)
        self.variables_dock.setWidget(self.variables_dock_contents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.variables_dock)
        self.variables_dock.setWindowTitle(self.tr("Variables"))
        self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock)
        self.tabifyDockWidget(self.propertiesDock, self.variables_dock)
        self.variables_editor.scopeChanged.connect(self.variables_changed)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.centralWidget().layout().insertWidget(0, self.bar)

        try:
            self.setDockOptions(self.dockOptions()
                                | QMainWindow.GroupedDragging)
        except:
            pass

        if iface is not None:
            self.mToolbar.setIconSize(iface.iconSize())
            self.setStyleSheet(iface.mainWindow().styleSheet())

        self.toolbutton_export_to_script = QToolButton()
        self.toolbutton_export_to_script.setPopupMode(QToolButton.InstantPopup)
        self.export_to_script_algorithm_action = QAction(
            QCoreApplication.translate('ModelerDialog',
                                       'Export as Script Algorithm…'))
        self.toolbutton_export_to_script.addActions(
            [self.export_to_script_algorithm_action])
        self.mToolbar.insertWidget(self.mActionExportImage,
                                   self.toolbutton_export_to_script)
        self.export_to_script_algorithm_action.triggered.connect(
            self.export_as_script_algorithm)

        self.mActionOpen.setIcon(
            QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
        self.mActionSave.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSave.svg'))
        self.mActionSaveAs.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSaveAs.svg'))
        self.mActionSaveInProject.setIcon(
            QgsApplication.getThemeIcon('/mAddToProject.svg'))
        self.mActionZoomActual.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomActual.svg'))
        self.mActionZoomIn.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomIn.svg'))
        self.mActionZoomOut.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomOut.svg'))
        self.mActionExportImage.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg'))
        self.mActionZoomToItems.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg'))
        self.mActionExportPdf.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg'))
        self.mActionExportSvg.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg'))
        self.toolbutton_export_to_script.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPython.svg'))
        self.mActionEditHelp.setIcon(
            QgsApplication.getThemeIcon('/mActionEditHelpContent.svg'))
        self.mActionRun.setIcon(
            QgsApplication.getThemeIcon('/mActionStart.svg'))

        self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock)
        self.tabifyDockWidget(self.inputsDock, self.algorithmsDock)
        self.inputsDock.raise_()

        self.setWindowFlags(Qt.WindowMinimizeButtonHint
                            | Qt.WindowMaximizeButtonHint
                            | Qt.WindowCloseButtonHint)

        settings = QgsSettings()
        self.restoreState(
            settings.value("/Processing/stateModeler", QByteArray()))
        self.restoreGeometry(
            settings.value("/Processing/geometryModeler", QByteArray()))

        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(
            QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))

        self.view.setScene(self.scene)
        self.view.setAcceptDrops(True)
        self.view.ensureVisible(0, 0, 10, 10)
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96,
                        QgsApplication.desktop().logicalDpiX() / 96)

        def _dragEnterEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                event.acceptProposedAction()
            else:
                event.ignore()

        def _dropEvent(event):
            def alg_dropped(algorithm_id, pos):
                alg = QgsApplication.processingRegistry().createAlgorithmById(
                    algorithm_id)
                if alg is not None:
                    self._addAlgorithm(alg, pos)
                else:
                    assert False, algorithm_id

            def input_dropped(id, pos):
                if id in [
                        param.id() for param in QgsApplication.instance().
                        processingRegistry().parameterTypes()
                ]:
                    self.addInputOfType(itemId, pos)

            if event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                data = event.mimeData().data(
                    'application/x-vnd.qgis.qgis.algorithmid')
                stream = QDataStream(data, QIODevice.ReadOnly)
                algorithm_id = stream.readQString()
                QTimer.singleShot(
                    0,
                    lambda id=algorithm_id, pos=self.view.mapToScene(event.pos(
                    )): alg_dropped(id, pos))
                event.accept()
            elif event.mimeData().hasText():
                itemId = event.mimeData().text()
                QTimer.singleShot(0,
                                  lambda id=itemId, pos=self.view.mapToScene(
                                      event.pos()): input_dropped(id, pos))
                event.accept()
            else:
                event.ignore()

        def _dragMoveEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                event.accept()
            else:
                event.ignore()

        def _wheelEvent(event):
            self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

            settings = QgsSettings()
            factor = settings.value('/qgis/zoom_favor', 2.0)

            # "Normal" mouse has an angle delta of 120, precision mouses provide data
            # faster, in smaller steps
            factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y())

            if (event.modifiers() == Qt.ControlModifier):
                factor = 1.0 + (factor - 1.0) / 20.0

            if event.angleDelta().y() < 0:
                factor = 1 / factor

            self.view.scale(factor, factor)

        def _enterEvent(e):
            QGraphicsView.enterEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mouseReleaseEvent(e):
            QGraphicsView.mouseReleaseEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mousePressEvent(e):
            if e.button() == Qt.MidButton:
                self.previousMousePos = e.pos()
            else:
                QGraphicsView.mousePressEvent(self.view, e)

        def _mouseMoveEvent(e):
            if e.buttons() == Qt.MidButton:
                offset = self.previousMousePos - e.pos()
                self.previousMousePos = e.pos()

                self.view.verticalScrollBar().setValue(
                    self.view.verticalScrollBar().value() + offset.y())
                self.view.horizontalScrollBar().setValue(
                    self.view.horizontalScrollBar().value() + offset.x())
            else:
                QGraphicsView.mouseMoveEvent(self.view, e)

        self.view.setDragMode(QGraphicsView.ScrollHandDrag)
        self.view.dragEnterEvent = _dragEnterEvent
        self.view.dropEvent = _dropEvent
        self.view.dragMoveEvent = _dragMoveEvent
        self.view.wheelEvent = _wheelEvent
        self.view.enterEvent = _enterEvent
        self.view.mousePressEvent = _mousePressEvent
        self.view.mouseMoveEvent = _mouseMoveEvent

        def _mimeDataInput(items):
            mimeData = QMimeData()
            text = items[0].data(0, Qt.UserRole)
            mimeData.setText(text)
            return mimeData

        self.inputsTree.mimeData = _mimeDataInput

        self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
        self.inputsTree.setDropIndicatorShown(True)

        self.algorithms_model = ModelerToolboxModel(
            self, QgsApplication.processingRegistry())
        self.algorithmTree.setToolboxProxyModel(self.algorithms_model)
        self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly)
        self.algorithmTree.setDropIndicatorShown(True)

        filters = QgsProcessingToolboxProxyModel.Filters(
            QgsProcessingToolboxProxyModel.FilterModeler)
        if ProcessingConfig.getSetting(
                ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES):
            filters |= QgsProcessingToolboxProxyModel.FilterShowKnownIssues
        self.algorithmTree.setFilters(filters)

        if hasattr(self.searchBox, 'setPlaceholderText'):
            self.searchBox.setPlaceholderText(
                QCoreApplication.translate('ModelerDialog', 'Search…'))
        if hasattr(self.textName, 'setPlaceholderText'):
            self.textName.setPlaceholderText(self.tr('Enter model name here'))
        if hasattr(self.textGroup, 'setPlaceholderText'):
            self.textGroup.setPlaceholderText(self.tr('Enter group name here'))

        # Connect signals and slots
        self.inputsTree.doubleClicked.connect(self.addInput)
        self.searchBox.textChanged.connect(self.algorithmTree.setFilterString)
        self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

        # Ctrl+= should also trigger a zoom in action
        ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self)
        ctrlEquals.activated.connect(self.zoomIn)

        self.mActionOpen.triggered.connect(self.openModel)
        self.mActionSave.triggered.connect(self.save)
        self.mActionSaveAs.triggered.connect(self.saveAs)
        self.mActionSaveInProject.triggered.connect(self.saveInProject)
        self.mActionZoomIn.triggered.connect(self.zoomIn)
        self.mActionZoomOut.triggered.connect(self.zoomOut)
        self.mActionZoomActual.triggered.connect(self.zoomActual)
        self.mActionZoomToItems.triggered.connect(self.zoomToItems)
        self.mActionExportImage.triggered.connect(self.exportAsImage)
        self.mActionExportPdf.triggered.connect(self.exportAsPdf)
        self.mActionExportSvg.triggered.connect(self.exportAsSvg)
        #self.mActionExportPython.triggered.connect(self.exportAsPython)
        self.mActionEditHelp.triggered.connect(self.editHelp)
        self.mActionRun.triggered.connect(self.runModel)

        if model is not None:
            self.model = model.create()
            self.model.setSourceFilePath(model.sourceFilePath())
            self.textGroup.setText(self.model.group())
            self.textName.setText(self.model.displayName())
            self.repaintModel()

        else:
            self.model = QgsProcessingModelAlgorithm()
            self.model.setProvider(
                QgsApplication.processingRegistry().providerById('model'))
        self.update_variables_gui()

        self.fillInputsTree()

        self.view.centerOn(0, 0)
        self.help = None

        self.hasChanged = False

    def closeEvent(self, evt):
        settings = QgsSettings()
        settings.setValue("/Processing/stateModeler", self.saveState())
        settings.setValue("/Processing/geometryModeler", self.saveGeometry())

        if self.hasChanged:
            ret = QMessageBox.question(
                self, self.tr('Save Model?'),
                self.
                tr('There are unsaved changes in this model. Do you want to keep those?'
                   ),
                QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard,
                QMessageBox.Cancel)

            if ret == QMessageBox.Save:
                self.saveModel(False)
                evt.accept()
            elif ret == QMessageBox.Discard:
                evt.accept()
            else:
                evt.ignore()
        else:
            evt.accept()

    def editHelp(self):
        alg = self.model
        dlg = HelpEditionDialog(alg)
        dlg.exec_()
        if dlg.descriptions:
            self.model.setHelpContent(dlg.descriptions)
            self.hasChanged = True

    def update_variables_gui(self):
        variables_scope = QgsExpressionContextScope(self.tr('Model Variables'))
        for k, v in self.model.variables().items():
            variables_scope.setVariable(k, v)
        variables_context = QgsExpressionContext()
        variables_context.appendScope(variables_scope)
        self.variables_editor.setContext(variables_context)
        self.variables_editor.setEditableScopeIndex(0)

    def variables_changed(self):
        self.model.setVariables(self.variables_editor.variablesInActiveScope())

    def runModel(self):
        if len(self.model.childAlgorithms()) == 0:
            self.bar.pushMessage(
                "",
                self.
                tr("Model doesn't contain any algorithm and/or parameter and can't be executed"
                   ),
                level=Qgis.Warning,
                duration=5)
            return

        dlg = AlgorithmDialog(self.model.create(), parent=iface.mainWindow())
        dlg.exec_()

    def save(self):
        self.saveModel(False)

    def saveAs(self):
        self.saveModel(True)

    def saveInProject(self):
        if not self.can_save():
            return

        self.model.setName(str(self.textName.text()))
        self.model.setGroup(str(self.textGroup.text()))
        self.model.setSourceFilePath(None)

        project_provider = QgsApplication.processingRegistry().providerById(
            PROJECT_PROVIDER_ID)
        project_provider.add_model(self.model)

        self.update_model.emit()
        self.bar.pushMessage("",
                             self.tr("Model was saved inside current project"),
                             level=Qgis.Success,
                             duration=5)

        self.hasChanged = False
        QgsProject.instance().setDirty(True)

    def zoomIn(self):
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        point = self.view.mapToScene(
            QPoint(self.view.viewport().width() / 2,
                   self.view.viewport().height() / 2))

        settings = QgsSettings()
        factor = settings.value('/qgis/zoom_favor', 2.0)

        self.view.scale(factor, factor)
        self.view.centerOn(point)
        self.repaintModel()

    def zoomOut(self):
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        point = self.view.mapToScene(
            QPoint(self.view.viewport().width() / 2,
                   self.view.viewport().height() / 2))

        settings = QgsSettings()
        factor = settings.value('/qgis/zoom_favor', 2.0)
        factor = 1 / factor

        self.view.scale(factor, factor)
        self.view.centerOn(point)
        self.repaintModel()

    def zoomActual(self):
        point = self.view.mapToScene(
            QPoint(self.view.viewport().width() / 2,
                   self.view.viewport().height() / 2))
        self.view.resetTransform()
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96,
                        QgsApplication.desktop().logicalDpiX() / 96)
        self.view.centerOn(point)

    def zoomToItems(self):
        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        self.view.fitInView(totalRect, Qt.KeepAspectRatio)

    def exportAsImage(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As Image'), '',
            self.tr('PNG files (*.png *.PNG)'))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        imgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, imgRect, totalRect)
        painter.end()

        img.save(filename)

        self.bar.pushMessage(
            "",
            self.tr(
                "Successfully exported model as image to <a href=\"{}\">{}</a>"
            ).format(
                QUrl.fromLocalFile(filename).toString(),
                QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)
        self.repaintModel(controls=True)

    def exportAsPdf(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As PDF'), '',
            self.tr('PDF files (*.pdf *.PDF)'))
        if not filename:
            return

        if not filename.lower().endswith('.pdf'):
            filename += '.pdf'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(filename)
        printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()),
                             QPrinter.DevicePixel)
        printer.setFullPage(True)

        painter = QPainter(printer)
        self.scene.render(painter, printerRect, totalRect)
        painter.end()

        self.bar.pushMessage(
            "",
            self.tr(
                "Successfully exported model as PDF to <a href=\"{}\">{}</a>").
            format(
                QUrl.fromLocalFile(filename).toString(),
                QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)
        self.repaintModel(controls=True)

    def exportAsSvg(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As SVG'), '',
            self.tr('SVG files (*.svg *.SVG)'))
        if not filename:
            return

        if not filename.lower().endswith('.svg'):
            filename += '.svg'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        svgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        svg = QSvgGenerator()
        svg.setFileName(filename)
        svg.setSize(QSize(totalRect.width(), totalRect.height()))
        svg.setViewBox(svgRect)
        svg.setTitle(self.model.displayName())

        painter = QPainter(svg)
        self.scene.render(painter, svgRect, totalRect)
        painter.end()

        self.bar.pushMessage(
            "",
            self.tr(
                "Successfully exported model as SVG to <a href=\"{}\">{}</a>").
            format(
                QUrl.fromLocalFile(filename).toString(),
                QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)
        self.repaintModel(controls=True)

    def exportAsPython(self):
        filename, filter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As Python Script'), '',
            self.tr('Processing scripts (*.py *.PY)'))
        if not filename:
            return

        if not filename.lower().endswith('.py'):
            filename += '.py'

        text = self.model.asPythonCode()
        with codecs.open(filename, 'w', encoding='utf-8') as fout:
            fout.write(text)

        self.bar.pushMessage(
            "",
            self.
            tr("Successfully exported model as python script to <a href=\"{}\">{}</a>"
               ).format(
                   QUrl.fromLocalFile(filename).toString(),
                   QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)

    def can_save(self):
        """
        Tests whether a model can be saved, or if it is not yet valid
        :return: bool
        """
        if str(self.textName.text()).strip() == '':
            self.bar.pushWarning(
                "", self.tr('Please a enter model name before saving'))
            return False

        return True

    def saveModel(self, saveAs):
        if not self.can_save():
            return
        self.model.setName(str(self.textName.text()))
        self.model.setGroup(str(self.textGroup.text()))
        if self.model.sourceFilePath() and not saveAs:
            filename = self.model.sourceFilePath()
        else:
            filename, filter = QFileDialog.getSaveFileName(
                self, self.tr('Save Model'),
                ModelerUtils.modelsFolders()[0],
                self.tr('Processing models (*.model3 *.MODEL3)'))
            if filename:
                if not filename.endswith('.model3'):
                    filename += '.model3'
                self.model.setSourceFilePath(filename)
        if filename:
            if not self.model.toFile(filename):
                if saveAs:
                    QMessageBox.warning(
                        self, self.tr('I/O error'),
                        self.tr('Unable to save edits. Reason:\n {0}').format(
                            str(sys.exc_info()[1])))
                else:
                    QMessageBox.warning(
                        self, self.tr("Can't save model"),
                        QCoreApplication.
                        translate('QgsPluginInstallerInstallingDialog', (
                            "This model can't be saved in its original location (probably you do not "
                            "have permission to do it). Please, use the 'Save as…' option."
                        )))
                return
            self.update_model.emit()
            if saveAs:
                self.bar.pushMessage(
                    "",
                    self.tr(
                        "Model was correctly saved to <a href=\"{}\">{}</a>").
                    format(
                        QUrl.fromLocalFile(filename).toString(),
                        QDir.toNativeSeparators(filename)),
                    level=Qgis.Success,
                    duration=5)
            else:
                self.bar.pushMessage("",
                                     self.tr("Model was correctly saved"),
                                     level=Qgis.Success,
                                     duration=5)

            self.hasChanged = False

    def openModel(self):
        filename, selected_filter = QFileDialog.getOpenFileName(
            self, self.tr('Open Model'),
            ModelerUtils.modelsFolders()[0],
            self.tr('Processing models (*.model3 *.MODEL3)'))
        if filename:
            self.loadModel(filename)

    def loadModel(self, filename):
        alg = QgsProcessingModelAlgorithm()
        if alg.fromFile(filename):
            self.model = alg
            self.model.setProvider(
                QgsApplication.processingRegistry().providerById('model'))
            self.textGroup.setText(alg.group())
            self.textName.setText(alg.name())
            self.repaintModel()

            self.update_variables_gui()

            self.view.centerOn(0, 0)
            self.hasChanged = False
        else:
            QgsMessageLog.logMessage(
                self.tr('Could not load model {0}').format(filename),
                self.tr('Processing'), Qgis.Critical)
            QMessageBox.critical(
                self, self.tr('Open Model'),
                self.tr('The selected model could not be loaded.\n'
                        'See the log for more information.'))

    def repaintModel(self, controls=True):
        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(
            QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))
        self.scene.paintModel(self.model, controls)
        self.view.setScene(self.scene)

    def addInput(self):
        item = self.inputsTree.currentItem()
        param = item.data(0, Qt.UserRole)
        self.addInputOfType(param)

    def addInputOfType(self, paramType, pos=None):
        dlg = ModelerParameterDefinitionDialog(self.model, paramType)
        dlg.exec_()
        if dlg.param is not None:
            if pos is None:
                pos = self.getPositionForParameterItem()
            if isinstance(pos, QPoint):
                pos = QPointF(pos)
            component = QgsProcessingModelParameter(dlg.param.name())
            component.setDescription(dlg.param.name())
            component.setPosition(pos)
            self.model.addModelParameter(dlg.param, component)
            self.repaintModel()
            # self.view.ensureVisible(self.scene.getLastParameterItem())
            self.hasChanged = True

    def getPositionForParameterItem(self):
        MARGIN = 20
        BOX_WIDTH = 200
        BOX_HEIGHT = 80
        if len(self.model.parameterComponents()) > 0:
            maxX = max([
                i.position().x()
                for i in list(self.model.parameterComponents().values())
            ])
            newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
        else:
            newX = MARGIN + BOX_WIDTH / 2
        return QPointF(newX, MARGIN + BOX_HEIGHT / 2)

    def fillInputsTree(self):
        icon = QIcon(os.path.join(pluginPath, 'images', 'input.svg'))
        parametersItem = QTreeWidgetItem()
        parametersItem.setText(0, self.tr('Parameters'))
        sortedParams = sorted(
            QgsApplication.instance().processingRegistry().parameterTypes(),
            key=lambda pt: pt.name())
        for param in sortedParams:
            if param.flags() & QgsProcessingParameterType.ExposeToModeler:
                paramItem = QTreeWidgetItem()
                paramItem.setText(0, param.name())
                paramItem.setData(0, Qt.UserRole, param.id())
                paramItem.setIcon(0, icon)
                paramItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable
                                   | Qt.ItemIsDragEnabled)
                paramItem.setToolTip(0, param.description())
                parametersItem.addChild(paramItem)
        self.inputsTree.addTopLevelItem(parametersItem)
        parametersItem.setExpanded(True)

    def addAlgorithm(self):
        algorithm = self.algorithmTree.selectedAlgorithm()
        if algorithm is not None:
            alg = QgsApplication.processingRegistry().createAlgorithmById(
                algorithm.id())
            self._addAlgorithm(alg)

    def _addAlgorithm(self, alg, pos=None):
        dlg = ModelerParametersDialog(alg, self.model)
        if dlg.exec_():
            alg = dlg.createAlgorithm()
            if pos is None:
                alg.setPosition(self.getPositionForAlgorithmItem())
            else:
                alg.setPosition(pos)
            from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
            for i, out in enumerate(alg.modelOutputs()):
                alg.modelOutput(out).setPosition(
                    alg.position() +
                    QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
                            ModelerGraphicItem.BOX_HEIGHT))
            self.model.addChildAlgorithm(alg)
            self.repaintModel()
            self.hasChanged = True

    def getPositionForAlgorithmItem(self):
        MARGIN = 20
        BOX_WIDTH = 200
        BOX_HEIGHT = 80
        if self.model.childAlgorithms():
            maxX = max([
                alg.position().x()
                for alg in list(self.model.childAlgorithms().values())
            ])
            maxY = max([
                alg.position().y()
                for alg in list(self.model.childAlgorithms().values())
            ])
            newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
            newY = min(MARGIN + BOX_HEIGHT + maxY,
                       self.CANVAS_SIZE - BOX_HEIGHT)
        else:
            newX = MARGIN + BOX_WIDTH / 2
            newY = MARGIN * 2 + BOX_HEIGHT + BOX_HEIGHT / 2
        return QPointF(newX, newY)

    def export_as_script_algorithm(self):
        dlg = ScriptEditorDialog(None)

        dlg.editor.setText('\n'.join(
            self.model.asPythonCode(
                QgsProcessing.PythonQgsProcessingAlgorithmSubclass, 4)))
        dlg.show()
コード例 #59
0
ファイル: ModelerDialog.py プロジェクト: ceholden/QGIS
    def __init__(self, model=None):
        super().__init__(None)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.setupUi(self)

        self._variables_scope = None

        # LOTS of bug reports when we include the dock creation in the UI file
        # see e.g. #16428, #19068
        # So just roll it all by hand......!
        self.propertiesDock = QgsDockWidget(self)
        self.propertiesDock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.propertiesDock.setObjectName("propertiesDock")
        propertiesDockContents = QWidget()
        self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents)
        self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0)
        self.verticalDockLayout_1.setSpacing(0)
        self.scrollArea_1 = QgsScrollArea(propertiesDockContents)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.scrollArea_1.sizePolicy().hasHeightForWidth())
        self.scrollArea_1.setSizePolicy(sizePolicy)
        self.scrollArea_1.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_1.setFrameShape(QFrame.NoFrame)
        self.scrollArea_1.setFrameShadow(QFrame.Plain)
        self.scrollArea_1.setWidgetResizable(True)
        self.scrollAreaWidgetContents_1 = QWidget()
        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1)
        self.gridLayout.setContentsMargins(6, 6, 6, 6)
        self.gridLayout.setSpacing(4)
        self.label_1 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
        self.textName = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textName, 0, 1, 1, 1)
        self.label_2 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1)
        self.label_1.setText(self.tr("Name"))
        self.textName.setToolTip(self.tr("Enter model name here"))
        self.label_2.setText(self.tr("Group"))
        self.textGroup.setToolTip(self.tr("Enter group name here"))
        self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1)
        self.verticalDockLayout_1.addWidget(self.scrollArea_1)
        self.propertiesDock.setWidget(propertiesDockContents)
        self.propertiesDock.setWindowTitle(self.tr("Model Properties"))

        self.inputsDock = QgsDockWidget(self)
        self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable
                                    | QDockWidget.DockWidgetMovable)
        self.inputsDock.setObjectName("inputsDock")
        self.inputsDockContents = QWidget()
        self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_2 = QgsScrollArea(self.inputsDockContents)
        sizePolicy.setHeightForWidth(
            self.scrollArea_2.sizePolicy().hasHeightForWidth())
        self.scrollArea_2.setSizePolicy(sizePolicy)
        self.scrollArea_2.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_2.setFrameShape(QFrame.NoFrame)
        self.scrollArea_2.setFrameShadow(QFrame.Plain)
        self.scrollArea_2.setWidgetResizable(True)
        self.scrollAreaWidgetContents_2 = QWidget()
        self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.inputsTree = QTreeWidget(self.scrollAreaWidgetContents_2)
        self.inputsTree.setAlternatingRowColors(True)
        self.inputsTree.header().setVisible(False)
        self.verticalLayout.addWidget(self.inputsTree)
        self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
        self.verticalLayout_3.addWidget(self.scrollArea_2)
        self.inputsDock.setWidget(self.inputsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock)
        self.inputsDock.setWindowTitle(self.tr("Inputs"))

        self.algorithmsDock = QgsDockWidget(self)
        self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.algorithmsDock.setObjectName("algorithmsDock")
        self.algorithmsDockContents = QWidget()
        self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents)
        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents)
        sizePolicy.setHeightForWidth(
            self.scrollArea_3.sizePolicy().hasHeightForWidth())
        self.scrollArea_3.setSizePolicy(sizePolicy)
        self.scrollArea_3.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_3.setFrameShape(QFrame.NoFrame)
        self.scrollArea_3.setFrameShadow(QFrame.Plain)
        self.scrollArea_3.setWidgetResizable(True)
        self.scrollAreaWidgetContents_3 = QWidget()
        self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setSpacing(4)
        self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.addWidget(self.searchBox)
        self.algorithmTree = QgsProcessingToolboxTreeView(
            None, QgsApplication.processingRegistry())
        self.algorithmTree.setAlternatingRowColors(True)
        self.algorithmTree.header().setVisible(False)
        self.verticalLayout_2.addWidget(self.algorithmTree)
        self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
        self.verticalLayout_4.addWidget(self.scrollArea_3)
        self.algorithmsDock.setWidget(self.algorithmsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock)
        self.algorithmsDock.setWindowTitle(self.tr("Algorithms"))
        self.searchBox.setToolTip(
            self.tr("Enter algorithm name to filter list"))
        self.searchBox.setShowSearchIcon(True)

        self.variables_dock = QgsDockWidget(self)
        self.variables_dock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.variables_dock.setObjectName("variablesDock")
        self.variables_dock_contents = QWidget()
        vl_v = QVBoxLayout()
        vl_v.setContentsMargins(0, 0, 0, 0)
        self.variables_editor = QgsVariableEditorWidget()
        vl_v.addWidget(self.variables_editor)
        self.variables_dock_contents.setLayout(vl_v)
        self.variables_dock.setWidget(self.variables_dock_contents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.variables_dock)
        self.variables_dock.setWindowTitle(self.tr("Variables"))
        self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock)
        self.tabifyDockWidget(self.propertiesDock, self.variables_dock)
        self.variables_editor.scopeChanged.connect(self.variables_changed)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.centralWidget().layout().insertWidget(0, self.bar)

        try:
            self.setDockOptions(self.dockOptions()
                                | QMainWindow.GroupedDragging)
        except:
            pass

        if iface is not None:
            self.mToolbar.setIconSize(iface.iconSize())
            self.setStyleSheet(iface.mainWindow().styleSheet())

        self.toolbutton_export_to_script = QToolButton()
        self.toolbutton_export_to_script.setPopupMode(QToolButton.InstantPopup)
        self.export_to_script_algorithm_action = QAction(
            QCoreApplication.translate('ModelerDialog',
                                       'Export as Script Algorithm…'))
        self.toolbutton_export_to_script.addActions(
            [self.export_to_script_algorithm_action])
        self.mToolbar.insertWidget(self.mActionExportImage,
                                   self.toolbutton_export_to_script)
        self.export_to_script_algorithm_action.triggered.connect(
            self.export_as_script_algorithm)

        self.mActionOpen.setIcon(
            QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
        self.mActionSave.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSave.svg'))
        self.mActionSaveAs.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSaveAs.svg'))
        self.mActionSaveInProject.setIcon(
            QgsApplication.getThemeIcon('/mAddToProject.svg'))
        self.mActionZoomActual.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomActual.svg'))
        self.mActionZoomIn.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomIn.svg'))
        self.mActionZoomOut.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomOut.svg'))
        self.mActionExportImage.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg'))
        self.mActionZoomToItems.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg'))
        self.mActionExportPdf.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg'))
        self.mActionExportSvg.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg'))
        self.toolbutton_export_to_script.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPython.svg'))
        self.mActionEditHelp.setIcon(
            QgsApplication.getThemeIcon('/mActionEditHelpContent.svg'))
        self.mActionRun.setIcon(
            QgsApplication.getThemeIcon('/mActionStart.svg'))

        self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock)
        self.tabifyDockWidget(self.inputsDock, self.algorithmsDock)
        self.inputsDock.raise_()

        self.setWindowFlags(Qt.WindowMinimizeButtonHint
                            | Qt.WindowMaximizeButtonHint
                            | Qt.WindowCloseButtonHint)

        settings = QgsSettings()
        self.restoreState(
            settings.value("/Processing/stateModeler", QByteArray()))
        self.restoreGeometry(
            settings.value("/Processing/geometryModeler", QByteArray()))

        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(
            QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))

        self.view.setScene(self.scene)
        self.view.setAcceptDrops(True)
        self.view.ensureVisible(0, 0, 10, 10)
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96,
                        QgsApplication.desktop().logicalDpiX() / 96)

        def _dragEnterEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                event.acceptProposedAction()
            else:
                event.ignore()

        def _dropEvent(event):
            def alg_dropped(algorithm_id, pos):
                alg = QgsApplication.processingRegistry().createAlgorithmById(
                    algorithm_id)
                if alg is not None:
                    self._addAlgorithm(alg, pos)
                else:
                    assert False, algorithm_id

            def input_dropped(id, pos):
                if id in [
                        param.id() for param in QgsApplication.instance().
                        processingRegistry().parameterTypes()
                ]:
                    self.addInputOfType(itemId, pos)

            if event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                data = event.mimeData().data(
                    'application/x-vnd.qgis.qgis.algorithmid')
                stream = QDataStream(data, QIODevice.ReadOnly)
                algorithm_id = stream.readQString()
                QTimer.singleShot(
                    0,
                    lambda id=algorithm_id, pos=self.view.mapToScene(event.pos(
                    )): alg_dropped(id, pos))
                event.accept()
            elif event.mimeData().hasText():
                itemId = event.mimeData().text()
                QTimer.singleShot(0,
                                  lambda id=itemId, pos=self.view.mapToScene(
                                      event.pos()): input_dropped(id, pos))
                event.accept()
            else:
                event.ignore()

        def _dragMoveEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                event.accept()
            else:
                event.ignore()

        def _wheelEvent(event):
            self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

            settings = QgsSettings()
            factor = settings.value('/qgis/zoom_favor', 2.0)

            # "Normal" mouse has an angle delta of 120, precision mouses provide data
            # faster, in smaller steps
            factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y())

            if (event.modifiers() == Qt.ControlModifier):
                factor = 1.0 + (factor - 1.0) / 20.0

            if event.angleDelta().y() < 0:
                factor = 1 / factor

            self.view.scale(factor, factor)

        def _enterEvent(e):
            QGraphicsView.enterEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mouseReleaseEvent(e):
            QGraphicsView.mouseReleaseEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mousePressEvent(e):
            if e.button() == Qt.MidButton:
                self.previousMousePos = e.pos()
            else:
                QGraphicsView.mousePressEvent(self.view, e)

        def _mouseMoveEvent(e):
            if e.buttons() == Qt.MidButton:
                offset = self.previousMousePos - e.pos()
                self.previousMousePos = e.pos()

                self.view.verticalScrollBar().setValue(
                    self.view.verticalScrollBar().value() + offset.y())
                self.view.horizontalScrollBar().setValue(
                    self.view.horizontalScrollBar().value() + offset.x())
            else:
                QGraphicsView.mouseMoveEvent(self.view, e)

        self.view.setDragMode(QGraphicsView.ScrollHandDrag)
        self.view.dragEnterEvent = _dragEnterEvent
        self.view.dropEvent = _dropEvent
        self.view.dragMoveEvent = _dragMoveEvent
        self.view.wheelEvent = _wheelEvent
        self.view.enterEvent = _enterEvent
        self.view.mousePressEvent = _mousePressEvent
        self.view.mouseMoveEvent = _mouseMoveEvent

        def _mimeDataInput(items):
            mimeData = QMimeData()
            text = items[0].data(0, Qt.UserRole)
            mimeData.setText(text)
            return mimeData

        self.inputsTree.mimeData = _mimeDataInput

        self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
        self.inputsTree.setDropIndicatorShown(True)

        self.algorithms_model = ModelerToolboxModel(
            self, QgsApplication.processingRegistry())
        self.algorithmTree.setToolboxProxyModel(self.algorithms_model)
        self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly)
        self.algorithmTree.setDropIndicatorShown(True)

        filters = QgsProcessingToolboxProxyModel.Filters(
            QgsProcessingToolboxProxyModel.FilterModeler)
        if ProcessingConfig.getSetting(
                ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES):
            filters |= QgsProcessingToolboxProxyModel.FilterShowKnownIssues
        self.algorithmTree.setFilters(filters)

        if hasattr(self.searchBox, 'setPlaceholderText'):
            self.searchBox.setPlaceholderText(
                QCoreApplication.translate('ModelerDialog', 'Search…'))
        if hasattr(self.textName, 'setPlaceholderText'):
            self.textName.setPlaceholderText(self.tr('Enter model name here'))
        if hasattr(self.textGroup, 'setPlaceholderText'):
            self.textGroup.setPlaceholderText(self.tr('Enter group name here'))

        # Connect signals and slots
        self.inputsTree.doubleClicked.connect(self.addInput)
        self.searchBox.textChanged.connect(self.algorithmTree.setFilterString)
        self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

        # Ctrl+= should also trigger a zoom in action
        ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self)
        ctrlEquals.activated.connect(self.zoomIn)

        self.mActionOpen.triggered.connect(self.openModel)
        self.mActionSave.triggered.connect(self.save)
        self.mActionSaveAs.triggered.connect(self.saveAs)
        self.mActionSaveInProject.triggered.connect(self.saveInProject)
        self.mActionZoomIn.triggered.connect(self.zoomIn)
        self.mActionZoomOut.triggered.connect(self.zoomOut)
        self.mActionZoomActual.triggered.connect(self.zoomActual)
        self.mActionZoomToItems.triggered.connect(self.zoomToItems)
        self.mActionExportImage.triggered.connect(self.exportAsImage)
        self.mActionExportPdf.triggered.connect(self.exportAsPdf)
        self.mActionExportSvg.triggered.connect(self.exportAsSvg)
        #self.mActionExportPython.triggered.connect(self.exportAsPython)
        self.mActionEditHelp.triggered.connect(self.editHelp)
        self.mActionRun.triggered.connect(self.runModel)

        if model is not None:
            self.model = model.create()
            self.model.setSourceFilePath(model.sourceFilePath())
            self.textGroup.setText(self.model.group())
            self.textName.setText(self.model.displayName())
            self.repaintModel()

        else:
            self.model = QgsProcessingModelAlgorithm()
            self.model.setProvider(
                QgsApplication.processingRegistry().providerById('model'))
        self.update_variables_gui()

        self.fillInputsTree()

        self.view.centerOn(0, 0)
        self.help = None

        self.hasChanged = False
コード例 #60
0
    def initGui(self):
        # Create action that will start plugin configuration
        self.runIcon = QIcon(
            os.path.join(self.plugin_dir, 'icon_add_service.svg'))

        self.run_action = QAction(self.runIcon, "PDOK Services plugin",
                                  self.iface.mainWindow())

        self.run_button = QToolButton()
        self.run_button.setMenu(QMenu())
        self.run_button.setPopupMode(QToolButton.MenuButtonPopup)
        self.run_button.setDefaultAction(self.run_action)

        self.servicesLoaded = False
        # connect the action to the run method
        self.run_action.triggered.connect(self.run)
        self.setupfq()

        # Add toolbar button and menu item
        #self.iface.addToolBarIcon(self.action)

        self.toolbar = self.iface.addToolBar("PDOK services plugin")
        self.toolbar.setObjectName("PDOK services plugin")
        #self.toolbar.addAction(self.run_action)
        self.toolbar.addWidget(self.run_button)

        #self.run_button.menu().addSection('Favorieten')

        self.favourite_1_action = QAction('Favoriet 1',
                                          self.iface.mainWindow())
        self.favourite_1_action.setIcon(self.runIcon)
        self.favourite_1_action.triggered.connect(
            lambda: self.load_favourite(1))
        self.set_favourite_action(self.favourite_1_action, 1)
        self.run_button.menu().addAction(self.favourite_1_action)

        self.favourite_2_action = QAction('Favoriet 2',
                                          self.iface.mainWindow())
        self.favourite_2_action.setIcon(self.runIcon)
        self.favourite_2_action.triggered.connect(
            lambda: self.load_favourite(2))
        self.set_favourite_action(self.favourite_2_action, 2)
        self.run_button.menu().addAction(self.favourite_2_action)

        # TODO :-)
        #self.run_button.menu().addSection('Meest Recent')
        #self.run_button.menu().addSeparator()

        self.toolbarSearch = QLineEdit()
        self.toolbarSearch.setMaximumWidth(200)
        self.toolbarSearch.setAlignment(Qt.AlignLeft)
        self.toolbarSearch.setPlaceholderText("PDOK Locatieserver zoek")
        self.toolbar.addWidget(self.toolbarSearch)
        self.toolbarSearch.returnPressed.connect(self.searchAddressFromToolbar)
        # address/point cleanup
        eraserIcon = QIcon(
            os.path.join(self.plugin_dir, 'icon_remove_cross.svg'))
        self.clean_action = QAction(eraserIcon, "Cleanup", self.eraseAddress())
        self.toolbar.addAction(self.clean_action)
        self.clean_action.triggered.connect(self.eraseAddress)
        self.clean_action.setEnabled(False)

        self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.run_action)

        # about
        self.aboutAction = QAction(QIcon(":/plugins/pdokservicesplugin/icon_help.png"), \
                            "About", self.iface.mainWindow())
        self.aboutAction.setWhatsThis("Pdok Services Plugin About")
        self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.aboutAction)

        self.aboutAction.triggered.connect(self.about)
        self.dlg.ui.btnLoadLayer.clicked.connect(self.loadService)

        self.dlg.geocoderSearch.returnPressed.connect(self.searchAddress)

        self.dlg.geocoderSearch.textEdited.connect(self.searchAddress)
        self.dlg.geocoderSearch.setPlaceholderText(
            "PDOK Locatieserver zoek, bv postcode of postcode huisnummer")

        self.dlg.geocoderResultSearch.textChanged.connect(
            self.filterGeocoderResult)
        self.dlg.geocoderResultSearch.setPlaceholderText(
            "een of meer zoekwoorden uit resultaat")
        #self.iface.mapCanvas().renderStarting.connect(self.extentsChanged)

        ui = self.dlg.ui
        cbxs = [
            ui.cbx_gem, ui.cbx_wpl, ui.cbx_weg, ui.cbx_pcd, ui.cbx_adr,
            ui.cbx_pcl, ui.cbx_hmp
        ]
        # connect all fq checkboxes with suggest, so upon a change in fq filter we re-search
        for cbx in cbxs:
            cbx.stateChanged.connect(self.searchAddress)

        self.run(True)