Example #1
0
    def __init__(self, options, multiple, columns=2, parent=None):
        super(CheckboxesPanel, self).__init__(parent)

        self._options = []
        for i, option in enumerate(options):
            if isinstance(option, str):
                self._options.append((i, option))
            else:
                self.options.append(option)
        self._multiple = multiple
        self._buttons = []
        rows = len(options) / columns

        self._buttonGroup = QButtonGroup()
        self._buttonGroup.setExclusive(not multiple)
        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setMargin(0)
        for i, (v, t) in enumerate(self._options):
            if multiple:
                button = QCheckBox(t)
            else:
                button = QRadioButton(t)
            self._buttons.append((v, button))
            self._buttonGroup.addButton(button, i)
            layout.addWidget(button, i % rows, i / rows)
        layout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum), 0,
            columns)
        self.setLayout(layout)

        if multiple:
            self.setContextMenuPolicy(Qt.CustomContextMenu)
            self.customContextMenuRequested.connect(self.showPopupMenu)
Example #2
0
    def __init__(self, options, multiple, columns=2, parent=None):
        super(CheckboxesPanel, self).__init__(parent)

        self._options = []
        for i, option in enumerate(options):
            if isinstance(option, str):
                self._options.append((i, option))
            else:
                self.options.append(option)
        self._multiple = multiple
        self._buttons = []
        rows = len(options) / columns

        self._buttonGroup = QButtonGroup()
        self._buttonGroup.setExclusive(not multiple)
        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setMargin(0)
        for i, (v, t) in enumerate(self._options):
            if multiple:
                button = QCheckBox(t)
            else:
                button = QRadioButton(t)
            self._buttons.append((v, button))
            self._buttonGroup.addButton(button, i)
            layout.addWidget(button, i % rows, i / rows)
        layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
                       0, columns)
        self.setLayout(layout)

        if multiple:
            self.setContextMenuPolicy(Qt.CustomContextMenu)
            self.customContextMenuRequested.connect(self.showPopupMenu)
Example #3
0
    def api_search(self):

        # Dialog
        self.dlg_search = ApiSearchUi()
        self.load_settings(self.dlg_search)
        self.dlg_search.lbl_msg.setStyleSheet("QLabel{color:red;}")
        self.dlg_search.lbl_msg.setVisible(False)

        # Make it dockable in left dock widget area
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dlg_search)

        body = self.create_body()
        function_name = "gw_api_getsearch"
        row = self.controller.execute_api_function(function_name, body)
        if not row:
            return False

        complet_list = [json.loads(row[0], object_pairs_hook=OrderedDict)]

        main_tab = self.dlg_search.findChild(QTabWidget, 'main_tab')
        first_tab = None
        self.lineedit_list = []
        for tab in complet_list[0]["form"]:
            if first_tab is None:
                first_tab = tab['tabName']
            tab_widget = QWidget(main_tab)
            tab_widget.setObjectName(tab['tabName'])
            main_tab.addTab(tab_widget, tab['tabtext'])
            gridlayout = QGridLayout()
            tab_widget.setLayout(gridlayout)
            x = 0

            for field in tab['fields']:
                label = QLabel()
                label.setObjectName('lbl_' + field['label'])
                label.setText(field['label'].capitalize())
                if field['widgettype'] == 'typeahead':
                    completer = QCompleter()
                    widget = self.add_lineedit(field)
                    widget = self.set_completer(widget, completer)
                    self.lineedit_list.append(widget)
                elif field['widgettype'] == 'combo':
                    widget = self.add_combobox(field)

                gridlayout.addWidget(label, x, 0)
                gridlayout.addWidget(widget, x, 1)
                x += 1

            vertical_spacer1 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                           QSizePolicy.Expanding)
            gridlayout.addItem(vertical_spacer1)

        self.dlg_search.dlg_closed.connect(self.rubber_polygon.reset)
Example #4
0
class DBManager(QMainWindow):

    def __init__(self, iface, parent=None):
        QMainWindow.__init__(self, parent)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setupUi()
        self.iface = iface

        # restore the window state
        settings = QgsSettings()
        self.restoreGeometry(settings.value("/DB_Manager/mainWindow/geometry", QByteArray(), type=QByteArray))
        self.restoreState(settings.value("/DB_Manager/mainWindow/windowState", QByteArray(), type=QByteArray))

        self.tabs.currentChanged.connect(self.tabChanged)
        self.tree.selectedItemChanged.connect(self.itemChanged)
        self.itemChanged(None)

    def closeEvent(self, e):
        self.unregisterAllActions()
        # clear preview, this will delete the layer in preview tab
        self.preview.loadPreview(None)

        # save the window state
        settings = QgsSettings()
        settings.setValue("/DB_Manager/mainWindow/windowState", self.saveState())
        settings.setValue("/DB_Manager/mainWindow/geometry", self.saveGeometry())

        QMainWindow.closeEvent(self, e)

    def refreshItem(self, item=None):
        with OverrideCursor(Qt.WaitCursor):
            try:
                if item is None:
                    item = self.tree.currentItem()
                self.tree.refreshItem(item)  # refresh item children in the db tree
            except BaseError as e:
                DlgDbError.showError(e, self)

    def itemChanged(self, item):
        with OverrideCursor(Qt.WaitCursor):
            try:
                self.reloadButtons()
                # clear preview, this will delete the layer in preview tab
                self.preview.loadPreview(None)
                self.refreshTabs()
            except BaseError as e:
                DlgDbError.showError(e, self)

    def reloadButtons(self):
        db = self.tree.currentDatabase()
        if not hasattr(self, '_lastDb'):
            self._lastDb = db

        elif db == self._lastDb:
            return

        # remove old actions
        if self._lastDb is not None:
            self.unregisterAllActions()

        # add actions of the selected database
        self._lastDb = db
        if self._lastDb is not None:
            self._lastDb.registerAllActions(self)

    def tabChanged(self, index):
        with OverrideCursor(Qt.WaitCursor):
            try:
                self.refreshTabs()
            except BaseError as e:
                DlgDbError.showError(e, self)

    def refreshTabs(self):
        index = self.tabs.currentIndex()
        item = self.tree.currentItem()
        table = self.tree.currentTable()

        # enable/disable tabs
        self.tabs.setTabEnabled(self.tabs.indexOf(self.table), table is not None)
        self.tabs.setTabEnabled(self.tabs.indexOf(self.preview), table is not None and table.type in [table.VectorType,
                                                                                                      table.RasterType] and table.geomColumn is not None)
        # show the info tab if the current tab is disabled
        if not self.tabs.isTabEnabled(index):
            self.tabs.setCurrentWidget(self.info)

        current_tab = self.tabs.currentWidget()
        if current_tab == self.info:
            self.info.showInfo(item)
        elif current_tab == self.table:
            self.table.loadData(item)
        elif current_tab == self.preview:
            self.preview.loadPreview(item)

    def refreshActionSlot(self):
        self.info.setDirty()
        self.table.setDirty()
        self.preview.setDirty()
        self.refreshItem()

    def importActionSlot(self):
        db = self.tree.currentDatabase()
        if db is None:
            self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."),
                                     QgsMessageBar.INFO, self.iface.messageTimeout())
            return

        outUri = db.uri()
        schema = self.tree.currentSchema()
        if schema:
            outUri.setDataSource(schema.name, "", "", "")

        from .dlg_import_vector import DlgImportVector

        dlg = DlgImportVector(None, db, outUri, self)
        dlg.exec_()

    def exportActionSlot(self):
        table = self.tree.currentTable()
        if table is None:
            self.infoBar.pushMessage(self.tr("Select the table you want export to file."), QgsMessageBar.INFO,
                                     self.iface.messageTimeout())
            return

        inLayer = table.toMapLayer()
        if inLayer.type() != QgsMapLayer.VectorLayer:
            self.infoBar.pushMessage(
                self.tr("Select a vector or a tabular layer you want export."),
                QgsMessageBar.WARNING, self.iface.messageTimeout())
            return

        from .dlg_export_vector import DlgExportVector

        dlg = DlgExportVector(inLayer, table.database(), self)
        dlg.exec_()

        inLayer.deleteLater()

    def runSqlWindow(self):
        db = self.tree.currentDatabase()
        if db is None:
            self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."),
                                     QgsMessageBar.INFO, self.iface.messageTimeout())
            # force displaying of the message, it appears on the first tab (i.e. Info)
            self.tabs.setCurrentIndex(0)
            return

        from .dlg_sql_window import DlgSqlWindow

        query = DlgSqlWindow(self.iface, db, self)
        dbname = db.connection().connectionName()
        tabname = self.tr("Query ({0})").format(dbname)
        index = self.tabs.addTab(query, tabname)
        self.tabs.setTabIcon(index, db.connection().icon())
        self.tabs.setCurrentIndex(index)
        query.nameChanged.connect(functools.partial(self.update_query_tab_name, index, dbname))

    def runSqlLayerWindow(self, layer):
        from .dlg_sql_layer_window import DlgSqlLayerWindow
        query = DlgSqlLayerWindow(self.iface, layer, self)
        lname = layer.name()
        tabname = self.tr("Layer ({0})").format(lname)
        index = self.tabs.addTab(query, tabname)
        # self.tabs.setTabIcon(index, db.connection().icon())
        self.tabs.setCurrentIndex(index)

    def update_query_tab_name(self, index, dbname, queryname):
        if not queryname:
            queryname = self.tr("Query")
        tabname = u"%s (%s)" % (queryname, dbname)
        self.tabs.setTabText(index, tabname)

    def showSystemTables(self):
        self.tree.showSystemTables(self.actionShowSystemTables.isChecked())

    def registerAction(self, action, menuName, callback=None):
        """ register an action to the manager's main menu """
        if not hasattr(self, '_registeredDbActions'):
            self._registeredDbActions = {}

        if callback is not None:
            def invoke_callback(x):
                return self.invokeCallback(callback)

        if menuName is None or menuName == "":
            self.addAction(action)

            if menuName not in self._registeredDbActions:
                self._registeredDbActions[menuName] = list()
            self._registeredDbActions[menuName].append(action)

            if callback is not None:
                action.triggered.connect(invoke_callback)
            return True

        # search for the menu
        actionMenu = None
        helpMenuAction = None
        for a in self.menuBar.actions():
            if not a.menu() or a.menu().title() != menuName:
                continue
            if a.menu() != self.menuHelp:
                helpMenuAction = a

            actionMenu = a
            break

        # not found, add a new menu before the help menu
        if actionMenu is None:
            menu = QMenu(menuName, self)
            if helpMenuAction is not None:
                actionMenu = self.menuBar.insertMenu(helpMenuAction, menu)
            else:
                actionMenu = self.menuBar.addMenu(menu)

        menu = actionMenu.menu()
        menuActions = menu.actions()

        # get the placeholder's position to insert before it
        pos = 0
        for pos in range(len(menuActions)):
            if menuActions[pos].isSeparator() and menuActions[pos].objectName().endswith("_placeholder"):
                menuActions[pos].setVisible(True)
                break

        if pos < len(menuActions):
            before = menuActions[pos]
            menu.insertAction(before, action)
        else:
            menu.addAction(action)

        actionMenu.setVisible(True)  # show the menu

        if menuName not in self._registeredDbActions:
            self._registeredDbActions[menuName] = list()
        self._registeredDbActions[menuName].append(action)

        if callback is not None:
            action.triggered.connect(invoke_callback)

        return True

    def invokeCallback(self, callback, *params):
        """ Call a method passing the selected item in the database tree,
                the sender (usually a QAction), the plugin mainWindow and
                optionally additional parameters.

                This method takes care to override and restore the cursor,
                but also catches exceptions and displays the error dialog.
        """
        with OverrideCursor(Qt.WaitCursor):
            try:
                callback(self.tree.currentItem(), self.sender(), self, *params)
            except BaseError as e:
                # catch database errors and display the error dialog
                DlgDbError.showError(e, self)

    def unregisterAction(self, action, menuName):
        if not hasattr(self, '_registeredDbActions'):
            return

        if menuName is None or menuName == "":
            self.removeAction(action)

            if menuName in self._registeredDbActions:
                if self._registeredDbActions[menuName].count(action) > 0:
                    self._registeredDbActions[menuName].remove(action)

            action.deleteLater()
            return True

        for a in self.menuBar.actions():
            if not a.menu() or a.menu().title() != menuName:
                continue

            menu = a.menu()
            menuActions = menu.actions()

            menu.removeAction(action)
            if menu.isEmpty():  # hide the menu
                a.setVisible(False)

            if menuName in self._registeredDbActions:
                if self._registeredDbActions[menuName].count(action) > 0:
                    self._registeredDbActions[menuName].remove(action)

                # hide the placeholder if there're no other registered actions
                if len(self._registeredDbActions[menuName]) <= 0:
                    for i in range(len(menuActions)):
                        if menuActions[i].isSeparator() and menuActions[i].objectName().endswith("_placeholder"):
                            menuActions[i].setVisible(False)
                            break

            action.deleteLater()
            return True

        return False

    def unregisterAllActions(self):
        if not hasattr(self, '_registeredDbActions'):
            return

        for menuName in self._registeredDbActions:
            for action in list(self._registeredDbActions[menuName]):
                self.unregisterAction(action, menuName)
        del self._registeredDbActions

    def close_tab(self, index):
        widget = self.tabs.widget(index)
        if widget not in [self.info, self.table, self.preview]:
            self.tabs.removeTab(index)
            widget.deleteLater()

    def setupUi(self):
        self.setWindowTitle(self.tr("DB Manager"))
        self.setWindowIcon(QIcon(":/db_manager/icon"))
        self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint()))

        # create central tab widget and add the first 3 tabs: info, table and preview
        self.tabs = QTabWidget()
        self.info = InfoViewer(self)
        self.tabs.addTab(self.info, self.tr("Info"))
        self.table = TableViewer(self)
        self.tabs.addTab(self.table, self.tr("Table"))
        self.preview = LayerPreview(self)
        self.tabs.addTab(self.preview, self.tr("Preview"))
        self.setCentralWidget(self.tabs)

        # display close button for all tabs but the first 3 ones, i.e.
        # HACK: just hide the close button where not needed (GS)
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.close_tab)
        tabbar = self.tabs.tabBar()
        for i in range(3):
            btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide)
            btn.resize(0, 0)
            btn.hide()

        # Creates layout for message bar
        self.layout = QGridLayout(self.info)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # init messageBar instance
        self.infoBar = QgsMessageBar(self.info)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        # create database tree
        self.dock = QDockWidget("Tree", self)
        self.dock.setObjectName("DB_Manager_DBView")
        self.dock.setFeatures(QDockWidget.DockWidgetMovable)
        self.tree = DBTree(self)
        self.dock.setWidget(self.tree)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock)

        # create status bar
        self.statusBar = QStatusBar(self)
        self.setStatusBar(self.statusBar)

        # create menus
        self.menuBar = QMenuBar(self)
        self.menuDb = QMenu(self.tr("&Database"), self)
        self.menuBar.addMenu(self.menuDb)
        self.menuSchema = QMenu(self.tr("&Schema"), self)
        actionMenuSchema = self.menuBar.addMenu(self.menuSchema)
        self.menuTable = QMenu(self.tr("&Table"), self)
        actionMenuTable = self.menuBar.addMenu(self.menuTable)
        self.menuHelp = None  # QMenu(self.tr("&Help"), self)
        # actionMenuHelp = self.menuBar.addMenu(self.menuHelp)

        self.setMenuBar(self.menuBar)

        # create toolbar
        self.toolBar = QToolBar("Default", self)
        self.toolBar.setObjectName("DB_Manager_ToolBar")
        self.addToolBar(self.toolBar)

        # create menus' actions

        # menu DATABASE
        sep = self.menuDb.addSeparator()
        sep.setObjectName("DB_Manager_DbMenu_placeholder")
        sep.setVisible(False)

        self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"),
                                                   self.refreshActionSlot, QKeySequence("F5"))
        self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"),
                                                     self.runSqlWindow, QKeySequence("F2"))
        self.menuDb.addSeparator()
        self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q"))

        # menu SCHEMA
        sep = self.menuSchema.addSeparator()
        sep.setObjectName("DB_Manager_SchemaMenu_placeholder")
        sep.setVisible(False)

        actionMenuSchema.setVisible(False)

        # menu TABLE
        sep = self.menuTable.addSeparator()
        sep.setObjectName("DB_Manager_TableMenu_placeholder")
        sep.setVisible(False)

        self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"),
                                                     self.tr("&Import layer/file"), self.importActionSlot)
        self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"),
                                                     self.exportActionSlot)
        self.menuTable.addSeparator()
        #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables)
        #self.actionShowSystemTables.setCheckable(True)
        #self.actionShowSystemTables.setChecked(True)
        actionMenuTable.setVisible(False)

        # add actions to the toolbar
        self.toolBar.addAction(self.actionRefresh)
        self.toolBar.addAction(self.actionSqlWindow)
        self.toolBar.addAction(self.actionImport)
        self.toolBar.addAction(self.actionExport)
Example #5
0
class ShellOutputScintilla(QgsPythonConsoleBase):
    def __init__(self, parent=None):
        super(ShellOutputScintilla, self).__init__(parent)
        self.parent = parent
        self.shell = self.parent.shell

        self.settings = QgsSettings()

        # Creates layout for message bar
        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # messageBar instance
        self.infoBar = QgsMessageBar()
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        sys.stdout = writeOut(self, sys.stdout)
        sys.stderr = writeOut(self, sys.stderr, "_traceback")

        self.insertInitText()
        self.refreshSettingsOutput()
        self.setReadOnly(True)

        self.setCaretWidth(0)  # NO (blinking) caret in the output

        self.setMinimumHeight(120)

        self.setWrapMode(QsciScintilla.WrapCharacter)
        self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)

        self.runScut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_E), self)
        self.runScut.setContext(Qt.WidgetShortcut)
        self.runScut.activated.connect(self.enteredSelected)
        # Reimplemented copy action to prevent paste prompt (>>>,...) in command view
        self.copyShortcut = QShortcut(QKeySequence.Copy, self)
        self.copyShortcut.setContext(Qt.WidgetWithChildrenShortcut)
        self.copyShortcut.activated.connect(self.copy)
        self.selectAllShortcut = QShortcut(QKeySequence.SelectAll, self)
        self.selectAllShortcut.setContext(Qt.WidgetWithChildrenShortcut)
        self.selectAllShortcut.activated.connect(self.selectAll)

    def insertInitText(self):
        txtInit = QCoreApplication.translate(
            "PythonConsole", "Python Console\n"
            "Use iface to access QGIS API interface or Type help(iface) for more info\n"
            "Security warning: typing commands from an untrusted source can harm your computer"
        )

        # some translation string for the console header ends without '\n'
        # and the first command in console will be appended at the header text.
        # The following code add a '\n' at the end of the string if not present.
        if txtInit.endswith('\n'):
            self.setText(txtInit)
        else:
            self.setText(txtInit + '\n')

    def refreshSettingsOutput(self):
        # Set Python lexer
        self.setLexers()
        self.setSelectionForegroundColor(
            QColor(
                self.settings.value("pythonConsole/selectionForegroundColor",
                                    QColor(self.SELECTION_FOREGROUND_COLOR))))
        self.setSelectionBackgroundColor(
            QColor(
                self.settings.value("pythonConsole/selectionBackgroundColor",
                                    QColor(self.SELECTION_BACKGROUND_COLOR))))
        self.setMarginsForegroundColor(
            QColor(
                self.settings.value("pythonConsole/marginForegroundColor",
                                    QColor(self.MARGIN_FOREGROUND_COLOR))))
        self.setMarginsBackgroundColor(
            QColor(
                self.settings.value("pythonConsole/marginBackgroundColor",
                                    QColor(self.MARGIN_BACKGROUND_COLOR))))
        caretLineColor = self.settings.value("pythonConsole/caretLineColor",
                                             QColor(self.CARET_LINE_COLOR))
        cursorColor = self.settings.value("pythonConsole/cursorColor",
                                          QColor(self.CURSOR_COLOR))
        self.setCaretLineBackgroundColor(caretLineColor)
        self.setCaretForegroundColor(cursorColor)

    def clearConsole(self):
        self.setText('')
        self.insertInitText()
        self.shell.setFocus()

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        menu.addAction(
            self.iconHideTool,
            QCoreApplication.translate("PythonConsole", "Hide/Show Toolbar"),
            self.hideToolBar)
        menu.addSeparator()
        showEditorAction = menu.addAction(
            self.iconShowEditor,
            QCoreApplication.translate("PythonConsole", "Show Editor"),
            self.showEditor)
        menu.addSeparator()
        runAction = menu.addAction(
            self.iconRun,
            QCoreApplication.translate("PythonConsole", "Enter Selected"),
            self.enteredSelected, QKeySequence(Qt.CTRL + Qt.Key_E))
        clearAction = menu.addAction(
            self.iconClear,
            QCoreApplication.translate("PythonConsole", "Clear Console"),
            self.clearConsole)
        pyQGISHelpAction = menu.addAction(
            self.iconPyQGISHelp,
            QCoreApplication.translate("PythonConsole",
                                       "Search Selected in PyQGIS docs"),
            self.searchPyQGIS)
        menu.addSeparator()
        copyAction = menu.addAction(
            self.iconCopy, QCoreApplication.translate("PythonConsole", "Copy"),
            self.copy, QKeySequence.Copy)
        selectAllAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Select All"),
            self.selectAll, QKeySequence.SelectAll)
        menu.addSeparator()
        menu.addAction(self.iconSettings,
                       QCoreApplication.translate("PythonConsole", "Options…"),
                       self.parent.openSettings)
        runAction.setEnabled(False)
        clearAction.setEnabled(False)
        copyAction.setEnabled(False)
        pyQGISHelpAction.setEnabled(False)
        selectAllAction.setEnabled(False)
        showEditorAction.setEnabled(True)
        if self.hasSelectedText():
            runAction.setEnabled(True)
            copyAction.setEnabled(True)
            pyQGISHelpAction.setEnabled(True)
        if not self.text(3) == '':
            selectAllAction.setEnabled(True)
            clearAction.setEnabled(True)
        if self.parent.tabEditorWidget.isVisible():
            showEditorAction.setEnabled(False)
        menu.exec_(self.mapToGlobal(e.pos()))

    def hideToolBar(self):
        tB = self.parent.toolBar
        tB.hide() if tB.isVisible() else tB.show()
        self.shell.setFocus()

    def showEditor(self):
        Ed = self.parent.splitterObj
        if not Ed.isVisible():
            Ed.show()
            self.parent.showEditorButton.setChecked(True)
        self.shell.setFocus()

    def copy(self):
        """Copy text to clipboard... or keyboard interrupt"""
        if self.hasSelectedText():
            text = self.selectedText()
            text = text.replace('>>> ',
                                '').replace('... ',
                                            '').strip()  # removing prompts
            QApplication.clipboard().setText(text)
        else:
            raise KeyboardInterrupt

    def enteredSelected(self):
        cmd = self.selectedText()
        self.shell.insertFromDropPaste(cmd)
        self.shell.entered()

    def keyPressEvent(self, e):
        # empty text indicates possible shortcut key sequence so stay in output
        txt = e.text()
        if len(txt) and txt >= " ":
            self.shell.append(txt)
            self.shell.move_cursor_to_end()
            self.shell.setFocus()
            e.ignore()
        else:
            # possible shortcut key sequence, accept it
            e.accept()

    def widgetMessageBar(self, iface, text):
        timeout = iface.messageTimeout()
        self.infoBar.pushMessage(text, Qgis.Info, timeout)
Example #6
0
class ShellOutputScintilla(QsciScintilla):
    def __init__(self, parent=None):
        super(ShellOutputScintilla, self).__init__(parent)
        self.parent = parent
        self.shell = self.parent.shell

        self.settings = QgsSettings()

        # Creates layout for message bar
        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # messageBar instance
        self.infoBar = QgsMessageBar()
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        # Enable non-ascii chars for editor
        self.setUtf8(True)

        sys.stdout = writeOut(self, sys.stdout)
        sys.stderr = writeOut(self, sys.stderr, "_traceback")

        self.insertInitText()
        self.refreshSettingsOutput()
        self.setReadOnly(True)

        # Set the default font
        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        self.setFont(font)
        self.setMarginsFont(font)
        # Margin 0 is used for line numbers
        self.setMarginWidth(0, 0)
        self.setMarginWidth(1, 0)
        self.setMarginWidth(2, 0)
        #fm = QFontMetrics(font)
        self.setMarginsFont(font)
        self.setMarginWidth(1, "00000")
        self.setMarginLineNumbers(1, True)
        self.setMarginsForegroundColor(QColor("#3E3EE3"))
        self.setMarginsBackgroundColor(QColor("#f9f9f9"))
        self.setCaretLineVisible(True)
        self.setCaretWidth(0)

        self.setMinimumHeight(120)

        self.setWrapMode(QsciScintilla.WrapCharacter)
        self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)

        self.runScut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_E), self)
        self.runScut.setContext(Qt.WidgetShortcut)
        self.runScut.activated.connect(self.enteredSelected)
        # Reimplemented copy action to prevent paste prompt (>>>,...) in command view
        self.copyShortcut = QShortcut(QKeySequence.Copy, self)
        self.copyShortcut.activated.connect(self.copy)
        self.selectAllShortcut = QShortcut(QKeySequence.SelectAll, self)
        self.selectAllShortcut.activated.connect(self.selectAll)

    def insertInitText(self):
        txtInit = QCoreApplication.translate(
            "PythonConsole", "Python Console \n"
            "Use iface to access QGIS API interface or Type help(iface) for more info"
        )

        # some translation string for the console header ends without '\n'
        # and the first command in console will be appended at the header text.
        # The following code add a '\n' at the end of the string if not present.
        if txtInit.endswith('\n'):
            self.setText(txtInit)
        else:
            self.setText(txtInit + '\n')

    def refreshSettingsOutput(self):
        # Set Python lexer
        self.setLexers()
        caretLineColor = self.settings.value("pythonConsole/caretLineColor",
                                             QColor("#fcf3ed"))
        cursorColor = self.settings.value("pythonConsole/cursorColor",
                                          QColor(Qt.black))
        self.setCaretLineBackgroundColor(caretLineColor)
        self.setCaretForegroundColor(cursorColor)

    def setLexers(self):
        self.lexer = QsciLexerPython()

        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)

        loadFont = self.settings.value("pythonConsole/fontfamilytext")
        if loadFont:
            font.setFamily(loadFont)
        fontSize = self.settings.value("pythonConsole/fontsize", type=int)
        if fontSize:
            font.setPointSize(fontSize)

        self.lexer.setDefaultFont(font)
        self.lexer.setDefaultColor(
            QColor(
                self.settings.value("pythonConsole/defaultFontColor",
                                    QColor(Qt.black))))
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/commentFontColor",
                                    QColor(Qt.gray))), 1)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/keywordFontColor",
                                    QColor(Qt.darkGreen))), 5)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/classFontColor",
                                    QColor(Qt.blue))), 8)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/methodFontColor",
                                    QColor(Qt.darkGray))), 9)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/decorFontColor",
                                    QColor(Qt.darkBlue))), 15)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/commentBlockFontColor",
                                    QColor(Qt.gray))), 12)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/singleQuoteFontColor",
                                    QColor(Qt.blue))), 4)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/doubleQuoteFontColor",
                                    QColor(Qt.blue))), 3)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/tripleSingleQuoteFontColor",
                                    QColor(Qt.blue))), 6)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/tripleDoubleQuoteFontColor",
                                    QColor(Qt.blue))), 7)
        self.lexer.setColor(QColor(Qt.red), 14)
        self.lexer.setFont(font, 1)
        self.lexer.setFont(font, 2)
        self.lexer.setFont(font, 3)
        self.lexer.setFont(font, 4)

        for style in range(0, 33):
            paperColor = QColor(
                self.settings.value("pythonConsole/paperBackgroundColor",
                                    QColor(Qt.white)))
            self.lexer.setPaper(paperColor, style)

        self.setLexer(self.lexer)

    def clearConsole(self):
        self.setText('')
        self.insertInitText()
        self.shell.setFocus()

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        iconRun = QgsApplication.getThemeIcon("console/mIconRunConsole.svg")
        iconClear = QgsApplication.getThemeIcon("console/iconClearConsole.png")
        iconHideTool = QgsApplication.getThemeIcon(
            "console/iconHideToolConsole.png")
        iconSettings = QgsApplication.getThemeIcon(
            "console/iconSettingsConsole.png")
        menu.addAction(
            iconHideTool,
            QCoreApplication.translate("PythonConsole", "Hide/Show Toolbar"),
            self.hideToolBar)
        menu.addSeparator()
        showEditorAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Show Editor"),
            self.showEditor)
        menu.addSeparator()
        runAction = menu.addAction(
            iconRun,
            QCoreApplication.translate("PythonConsole", "Enter Selected"),
            self.enteredSelected, QKeySequence(Qt.CTRL + Qt.Key_E))
        clearAction = menu.addAction(
            iconClear,
            QCoreApplication.translate("PythonConsole", "Clear Console"),
            self.clearConsole)
        menu.addSeparator()
        copyAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Copy"), self.copy,
            QKeySequence.Copy)
        selectAllAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Select All"),
            self.selectAll, QKeySequence.SelectAll)
        menu.addSeparator()
        menu.addAction(
            iconSettings,
            QCoreApplication.translate("PythonConsole", "Options..."),
            self.parent.openSettings)
        runAction.setEnabled(False)
        clearAction.setEnabled(False)
        copyAction.setEnabled(False)
        selectAllAction.setEnabled(False)
        showEditorAction.setEnabled(True)
        if self.hasSelectedText():
            runAction.setEnabled(True)
            copyAction.setEnabled(True)
        if not self.text(3) == '':
            selectAllAction.setEnabled(True)
            clearAction.setEnabled(True)
        if self.parent.tabEditorWidget.isVisible():
            showEditorAction.setEnabled(False)
        menu.exec_(self.mapToGlobal(e.pos()))

    def hideToolBar(self):
        tB = self.parent.toolBar
        tB.hide() if tB.isVisible() else tB.show()
        self.shell.setFocus()

    def showEditor(self):
        Ed = self.parent.splitterObj
        if not Ed.isVisible():
            Ed.show()
            self.parent.showEditorButton.setChecked(True)
        self.shell.setFocus()

    def copy(self):
        """Copy text to clipboard... or keyboard interrupt"""
        if self.hasSelectedText():
            text = self.selectedText()
            text = text.replace('>>> ',
                                '').replace('... ',
                                            '').strip()  # removing prompts
            QApplication.clipboard().setText(text)
        else:
            raise KeyboardInterrupt

    def enteredSelected(self):
        cmd = self.selectedText()
        self.shell.insertFromDropPaste(cmd)
        self.shell.entered()

    def keyPressEvent(self, e):
        # empty text indicates possible shortcut key sequence so stay in output
        txt = e.text()
        if len(txt) and txt >= " ":
            self.shell.append(txt)
            self.shell.move_cursor_to_end()
            self.shell.setFocus()
            e.ignore()
        else:
            # possible shortcut key sequence, accept it
            e.accept()

    def widgetMessageBar(self, iface, text):
        timeout = iface.messageTimeout()
        self.infoBar.pushMessage(text, QgsMessageBar.INFO, timeout)
    def api_search(self, dlg_mincut=None):
        form = ""
        if self.dlg_search is None and dlg_mincut is None:
            self.init_dialog()
        if dlg_mincut:
            self.dlg_search = dlg_mincut
            self.is_mincut = True
            form = f'"singleTab":"tab_address"'

        self.dlg_search.lbl_msg.setStyleSheet("QLabel{color:red;}")
        self.dlg_search.lbl_msg.setVisible(False)
        project_vars = global_vars.project_vars
        qgis_project_add_schema = project_vars['add_schema']
        self.controller.set_user_settings_value('open_search', 'true')

        if qgis_project_add_schema is None:
            body = create_body(form=form)
        else:
            extras = f'"addSchema":"{qgis_project_add_schema}"'
            body = create_body(form=form, extras=extras)
        function_name = "gw_fct_getsearch"
        complet_list = self.controller.get_json(function_name, body)
        if not complet_list:
            return False

        main_tab = self.dlg_search.findChild(QTabWidget, 'main_tab')
        if dlg_mincut and len(complet_list["form"]) == 1:
            main_tab = self.dlg_search.findChild(QTabWidget, 'main_tab')
            main_tab.setStyleSheet(
                "QTabBar::tab { background-color: transparent; text-align:left;"
                "border: 1px solid transparent;}"
                "QTabWidget::pane { background-color: #fcfcfc; border: 1 solid #dadada;}"
            )

        first_tab = None
        self.lineedit_list = []
        for tab in complet_list["form"]:
            if first_tab is None:
                first_tab = tab['tabName']
            tab_widget = QWidget(main_tab)
            tab_widget.setObjectName(tab['tabName'])
            main_tab.addTab(tab_widget, tab['tabLabel'])
            gridlayout = QGridLayout()
            tab_widget.setLayout(gridlayout)
            x = 0

            for field in tab['fields']:
                label = QLabel()
                label.setObjectName('lbl_' + field['label'])
                label.setText(field['label'].capitalize())
                widget = None
                if field['widgettype'] == 'typeahead':
                    completer = QCompleter()
                    widget = add_lineedit(field)
                    widget = self.set_typeahead_completer(widget, completer)
                    self.lineedit_list.append(widget)
                elif field['widgettype'] == 'combo':
                    widget = self.add_combobox(field)
                gridlayout.addWidget(label, x, 0)
                gridlayout.addWidget(widget, x, 1)
                x += 1

            vertical_spacer1 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                           QSizePolicy.Expanding)
            gridlayout.addItem(vertical_spacer1)

        if self.is_mincut is False:
            self.controller.manage_translation('search', self.dlg_search)
Example #8
0
class ShellOutputScintilla(QsciScintilla):

    DEFAULT_COLOR = "#4d4d4c"
    KEYWORD_COLOR = "#8959a8"
    CLASS_COLOR = "#4271ae"
    METHOD_COLOR = "#4271ae"
    DECORATION_COLOR = "#3e999f"
    NUMBER_COLOR = "#c82829"
    COMMENT_COLOR = "#8e908c"
    COMMENT_BLOCK_COLOR = "#8e908c"
    BACKGROUND_COLOR = "#ffffff"
    CURSOR_COLOR = "#636363"
    CARET_LINE_COLOR = "#efefef"
    SINGLE_QUOTE_COLOR = "#718c00"
    DOUBLE_QUOTE_COLOR = "#718c00"
    TRIPLE_SINGLE_QUOTE_COLOR = "#eab700"
    TRIPLE_DOUBLE_QUOTE_COLOR = "#eab700"
    MARGIN_BACKGROUND_COLOR = "#efefef"
    MARGIN_FOREGROUND_COLOR = "#636363"
    SELECTION_BACKGROUND_COLOR = "#d7d7d7"
    SELECTION_FOREGROUND_COLOR = "#303030"
    MATCHED_BRACE_BACKGROUND_COLOR = "#b7f907"
    MATCHED_BRACE_FOREGROUND_COLOR = "#303030"

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

        self.settings = QgsSettings()

        # Creates layout for message bar
        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # messageBar instance
        self.infoBar = QgsMessageBar()
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        # Enable non-ascii chars for editor
        self.setUtf8(True)

        sys.stdout = writeOut(self, sys.stdout)
        sys.stderr = writeOut(self, sys.stderr, "_traceback")

        self.insertInitText()
        self.refreshSettingsOutput()
        self.setReadOnly(True)

        # Set the default font
        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        self.setFont(font)
        self.setMarginsFont(font)
        # Margin 0 is used for line numbers
        self.setMarginWidth(0, 0)
        self.setMarginWidth(1, 0)
        self.setMarginWidth(2, 0)
        #fm = QFontMetrics(font)
        self.setMarginsFont(font)
        self.setMarginWidth(1, "00000")
        self.setMarginLineNumbers(1, True)
        self.setCaretLineVisible(True)
        self.setCaretWidth(0)

        self.setMinimumHeight(120)

        self.setWrapMode(QsciScintilla.WrapCharacter)
        self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)

        self.runScut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_E), self)
        self.runScut.setContext(Qt.WidgetShortcut)
        self.runScut.activated.connect(self.enteredSelected)
        # Reimplemented copy action to prevent paste prompt (>>>,...) in command view
        self.copyShortcut = QShortcut(QKeySequence.Copy, self)
        self.copyShortcut.activated.connect(self.copy)
        self.selectAllShortcut = QShortcut(QKeySequence.SelectAll, self)
        self.selectAllShortcut.activated.connect(self.selectAll)

    def insertInitText(self):
        txtInit = QCoreApplication.translate("PythonConsole",
                                             "Python Console\n"
                                             "Use iface to access QGIS API interface or Type help(iface) for more info\n"
                                             "Security warning: typing commands from an untrusted source can lead to data loss and/or leak")

        # some translation string for the console header ends without '\n'
        # and the first command in console will be appended at the header text.
        # The following code add a '\n' at the end of the string if not present.
        if txtInit.endswith('\n'):
            self.setText(txtInit)
        else:
            self.setText(txtInit + '\n')

    def refreshSettingsOutput(self):
        # Set Python lexer
        self.setLexers()
        self.setSelectionForegroundColor(QColor(self.settings.value("pythonConsole/selectionForegroundColor", QColor(self.SELECTION_FOREGROUND_COLOR))))
        self.setSelectionBackgroundColor(QColor(self.settings.value("pythonConsole/selectionBackgroundColor", QColor(self.SELECTION_BACKGROUND_COLOR))))
        self.setMarginsForegroundColor(QColor(self.settings.value("pythonConsole/marginForegroundColor", QColor(self.MARGIN_FOREGROUND_COLOR))))
        self.setMarginsBackgroundColor(QColor(self.settings.value("pythonConsole/marginBackgroundColor", QColor(self.MARGIN_BACKGROUND_COLOR))))
        caretLineColor = self.settings.value("pythonConsole/caretLineColor", QColor(self.CARET_LINE_COLOR))
        cursorColor = self.settings.value("pythonConsole/cursorColor", QColor(self.CURSOR_COLOR))
        self.setCaretLineBackgroundColor(caretLineColor)
        self.setCaretForegroundColor(cursorColor)

    def setLexers(self):
        self.lexer = QsciLexerPython()

        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)

        loadFont = self.settings.value("pythonConsole/fontfamilytext")
        if loadFont:
            font.setFamily(loadFont)
        fontSize = self.settings.value("pythonConsole/fontsize", type=int)
        if fontSize:
            font.setPointSize(fontSize)

        self.lexer.setDefaultFont(font)
        self.lexer.setDefaultColor(QColor(self.settings.value("pythonConsole/defaultFontColor", QColor(self.DEFAULT_COLOR))))
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/commentFontColor", QColor(self.COMMENT_COLOR))), 1)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/numberFontColor", QColor(self.NUMBER_COLOR))), 2)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/keywordFontColor", QColor(self.KEYWORD_COLOR))), 5)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/classFontColor", QColor(self.CLASS_COLOR))), 8)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/methodFontColor", QColor(self.METHOD_COLOR))), 9)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/decorFontColor", QColor(self.DECORATION_COLOR))), 15)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/commentBlockFontColor", QColor(self.COMMENT_BLOCK_COLOR))), 12)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/singleQuoteFontColor", QColor(self.SINGLE_QUOTE_COLOR))), 4)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/doubleQuoteFontColor", QColor(self.DOUBLE_QUOTE_COLOR))), 3)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/tripleSingleQuoteFontColor", QColor(self.TRIPLE_SINGLE_QUOTE_COLOR))), 6)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/tripleDoubleQuoteFontColor", QColor(self.TRIPLE_DOUBLE_QUOTE_COLOR))), 7)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/defaultFontColorEditor", QColor(self.DEFAULT_COLOR))), 13)
        self.lexer.setColor(QColor(Qt.red), 14)
        self.lexer.setFont(font, 1)
        self.lexer.setFont(font, 2)
        self.lexer.setFont(font, 3)
        self.lexer.setFont(font, 4)
        self.lexer.setFont(font, QsciLexerPython.UnclosedString)

        for style in range(0, 33):
            paperColor = QColor(self.settings.value("pythonConsole/paperBackgroundColor", QColor(self.BACKGROUND_COLOR)))
            self.lexer.setPaper(paperColor, style)

        self.setLexer(self.lexer)

    def clearConsole(self):
        self.setText('')
        self.insertInitText()
        self.shell.setFocus()

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        iconRun = QgsApplication.getThemeIcon("console/mIconRunConsole.svg")
        iconClear = QgsApplication.getThemeIcon("console/iconClearConsole.svg")
        iconHideTool = QgsApplication.getThemeIcon("console/iconHideToolConsole.svg")
        iconSettings = QgsApplication.getThemeIcon("console/iconSettingsConsole.svg")
        menu.addAction(iconHideTool,
                       QCoreApplication.translate("PythonConsole", "Hide/Show Toolbar"),
                       self.hideToolBar)
        menu.addSeparator()
        showEditorAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Show Editor"),
            self.showEditor)
        menu.addSeparator()
        runAction = menu.addAction(iconRun,
                                   QCoreApplication.translate("PythonConsole", "Enter Selected"),
                                   self.enteredSelected,
                                   QKeySequence(Qt.CTRL + Qt.Key_E))
        clearAction = menu.addAction(iconClear,
                                     QCoreApplication.translate("PythonConsole", "Clear Console"),
                                     self.clearConsole)
        menu.addSeparator()
        copyAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Copy"),
            self.copy, QKeySequence.Copy)
        selectAllAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Select All"),
            self.selectAll, QKeySequence.SelectAll)
        menu.addSeparator()
        menu.addAction(iconSettings,
                       QCoreApplication.translate("PythonConsole", "Options…"),
                       self.parent.openSettings)
        runAction.setEnabled(False)
        clearAction.setEnabled(False)
        copyAction.setEnabled(False)
        selectAllAction.setEnabled(False)
        showEditorAction.setEnabled(True)
        if self.hasSelectedText():
            runAction.setEnabled(True)
            copyAction.setEnabled(True)
        if not self.text(3) == '':
            selectAllAction.setEnabled(True)
            clearAction.setEnabled(True)
        if self.parent.tabEditorWidget.isVisible():
            showEditorAction.setEnabled(False)
        menu.exec_(self.mapToGlobal(e.pos()))

    def hideToolBar(self):
        tB = self.parent.toolBar
        tB.hide() if tB.isVisible() else tB.show()
        self.shell.setFocus()

    def showEditor(self):
        Ed = self.parent.splitterObj
        if not Ed.isVisible():
            Ed.show()
            self.parent.showEditorButton.setChecked(True)
        self.shell.setFocus()

    def copy(self):
        """Copy text to clipboard... or keyboard interrupt"""
        if self.hasSelectedText():
            text = self.selectedText()
            text = text.replace('>>> ', '').replace('... ', '').strip()  # removing prompts
            QApplication.clipboard().setText(text)
        else:
            raise KeyboardInterrupt

    def enteredSelected(self):
        cmd = self.selectedText()
        self.shell.insertFromDropPaste(cmd)
        self.shell.entered()

    def keyPressEvent(self, e):
        # empty text indicates possible shortcut key sequence so stay in output
        txt = e.text()
        if len(txt) and txt >= " ":
            self.shell.append(txt)
            self.shell.move_cursor_to_end()
            self.shell.setFocus()
            e.ignore()
        else:
            # possible shortcut key sequence, accept it
            e.accept()

    def widgetMessageBar(self, iface, text):
        timeout = iface.messageTimeout()
        self.infoBar.pushMessage(text, Qgis.Info, timeout)
Example #9
0
class ShellOutputScintilla(QsciScintilla):
    DEFAULT_COLOR = "#4d4d4c"
    KEYWORD_COLOR = "#8959a8"
    CLASS_COLOR = "#4271ae"
    METHOD_COLOR = "#4271ae"
    DECORATION_COLOR = "#3e999f"
    NUMBER_COLOR = "#c82829"
    COMMENT_COLOR = "#8e908c"
    COMMENT_BLOCK_COLOR = "#8e908c"
    BACKGROUND_COLOR = "#ffffff"
    CURSOR_COLOR = "#636363"
    CARET_LINE_COLOR = "#efefef"
    SINGLE_QUOTE_COLOR = "#718c00"
    DOUBLE_QUOTE_COLOR = "#718c00"
    TRIPLE_SINGLE_QUOTE_COLOR = "#eab700"
    TRIPLE_DOUBLE_QUOTE_COLOR = "#eab700"
    MARGIN_BACKGROUND_COLOR = "#efefef"
    MARGIN_FOREGROUND_COLOR = "#636363"
    SELECTION_BACKGROUND_COLOR = "#d7d7d7"
    SELECTION_FOREGROUND_COLOR = "#303030"
    MATCHED_BRACE_BACKGROUND_COLOR = "#b7f907"
    MATCHED_BRACE_FOREGROUND_COLOR = "#303030"

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

        self.settings = QgsSettings()

        # Creates layout for message bar
        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # messageBar instance
        self.infoBar = QgsMessageBar()
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        # Enable non-ascii chars for editor
        self.setUtf8(True)

        sys.stdout = writeOut(self, sys.stdout)
        sys.stderr = writeOut(self, sys.stderr, "_traceback")

        self.insertInitText()
        self.refreshSettingsOutput()
        self.setReadOnly(True)

        # Set the default font
        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        self.setFont(font)
        self.setMarginsFont(font)
        # Margin 0 is used for line numbers
        self.setMarginWidth(0, 0)
        self.setMarginWidth(1, 0)
        self.setMarginWidth(2, 0)
        self.setMarginsFont(font)
        self.setMarginWidth(1, "00000")
        self.setMarginLineNumbers(1, True)
        self.setCaretLineVisible(True)
        self.setCaretWidth(0)

        self.setMinimumHeight(120)

        self.setWrapMode(QsciScintilla.WrapCharacter)
        self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)

        self.runScut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_E), self)
        self.runScut.setContext(Qt.WidgetShortcut)
        self.runScut.activated.connect(self.enteredSelected)
        # Reimplemented copy action to prevent paste prompt (>>>,...) in command view
        self.copyShortcut = QShortcut(QKeySequence.Copy, self)
        self.copyShortcut.setContext(Qt.WidgetWithChildrenShortcut)
        self.copyShortcut.activated.connect(self.copy)
        self.selectAllShortcut = QShortcut(QKeySequence.SelectAll, self)
        self.selectAllShortcut.setContext(Qt.WidgetWithChildrenShortcut)
        self.selectAllShortcut.activated.connect(self.selectAll)

    def insertInitText(self):
        txtInit = QCoreApplication.translate(
            "PythonConsole", "Python Console\n"
            "Use iface to access QGIS API interface or Type help(iface) for more info\n"
            "Security warning: typing commands from an untrusted source can lead to data loss and/or leak"
        )

        # some translation string for the console header ends without '\n'
        # and the first command in console will be appended at the header text.
        # The following code add a '\n' at the end of the string if not present.
        if txtInit.endswith('\n'):
            self.setText(txtInit)
        else:
            self.setText(txtInit + '\n')

    def refreshSettingsOutput(self):
        # Set Python lexer
        self.setLexers()
        self.setSelectionForegroundColor(
            QColor(
                self.settings.value("pythonConsole/selectionForegroundColor",
                                    QColor(self.SELECTION_FOREGROUND_COLOR))))
        self.setSelectionBackgroundColor(
            QColor(
                self.settings.value("pythonConsole/selectionBackgroundColor",
                                    QColor(self.SELECTION_BACKGROUND_COLOR))))
        self.setMarginsForegroundColor(
            QColor(
                self.settings.value("pythonConsole/marginForegroundColor",
                                    QColor(self.MARGIN_FOREGROUND_COLOR))))
        self.setMarginsBackgroundColor(
            QColor(
                self.settings.value("pythonConsole/marginBackgroundColor",
                                    QColor(self.MARGIN_BACKGROUND_COLOR))))
        caretLineColor = self.settings.value("pythonConsole/caretLineColor",
                                             QColor(self.CARET_LINE_COLOR))
        cursorColor = self.settings.value("pythonConsole/cursorColor",
                                          QColor(self.CURSOR_COLOR))
        self.setCaretLineBackgroundColor(caretLineColor)
        self.setCaretForegroundColor(cursorColor)

    def setLexers(self):
        self.lexer = QsciLexerPython()

        font = QFontDatabase.systemFont(QFontDatabase.FixedFont)

        loadFont = self.settings.value("pythonConsole/fontfamilytext")
        if loadFont:
            font.setFamily(loadFont)
        fontSize = self.settings.value("pythonConsole/fontsize", type=int)
        if fontSize:
            font.setPointSize(fontSize)

        self.lexer.setDefaultFont(font)
        self.lexer.setDefaultColor(
            QColor(
                self.settings.value("pythonConsole/defaultFontColor",
                                    QColor(self.DEFAULT_COLOR))))
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/commentFontColor",
                                    QColor(self.COMMENT_COLOR))), 1)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/numberFontColor",
                                    QColor(self.NUMBER_COLOR))), 2)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/keywordFontColor",
                                    QColor(self.KEYWORD_COLOR))), 5)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/classFontColor",
                                    QColor(self.CLASS_COLOR))), 8)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/methodFontColor",
                                    QColor(self.METHOD_COLOR))), 9)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/decorFontColor",
                                    QColor(self.DECORATION_COLOR))), 15)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/commentBlockFontColor",
                                    QColor(self.COMMENT_BLOCK_COLOR))), 12)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/singleQuoteFontColor",
                                    QColor(self.SINGLE_QUOTE_COLOR))), 4)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/doubleQuoteFontColor",
                                    QColor(self.DOUBLE_QUOTE_COLOR))), 3)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/tripleSingleQuoteFontColor",
                                    QColor(self.TRIPLE_SINGLE_QUOTE_COLOR))),
            6)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/tripleDoubleQuoteFontColor",
                                    QColor(self.TRIPLE_DOUBLE_QUOTE_COLOR))),
            7)
        self.lexer.setColor(
            QColor(
                self.settings.value("pythonConsole/defaultFontColorEditor",
                                    QColor(self.DEFAULT_COLOR))), 13)
        self.lexer.setColor(QColor(Qt.red), 14)
        self.lexer.setFont(font, 1)
        self.lexer.setFont(font, 2)
        self.lexer.setFont(font, 3)
        self.lexer.setFont(font, 4)
        self.lexer.setFont(font, QsciLexerPython.UnclosedString)

        for style in range(0, 33):
            paperColor = QColor(
                self.settings.value("pythonConsole/paperBackgroundColor",
                                    QColor(self.BACKGROUND_COLOR)))
            self.lexer.setPaper(paperColor, style)

        self.setLexer(self.lexer)

    def clearConsole(self):
        self.setText('')
        self.insertInitText()
        self.shell.setFocus()

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        iconRun = QgsApplication.getThemeIcon("console/mIconRunConsole.svg")
        iconClear = QgsApplication.getThemeIcon("console/iconClearConsole.svg")
        iconHideTool = QgsApplication.getThemeIcon(
            "console/iconHideToolConsole.svg")
        iconSettings = QgsApplication.getThemeIcon(
            "console/iconSettingsConsole.svg")
        menu.addAction(
            iconHideTool,
            QCoreApplication.translate("PythonConsole", "Hide/Show Toolbar"),
            self.hideToolBar)
        menu.addSeparator()
        showEditorAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Show Editor"),
            self.showEditor)
        menu.addSeparator()
        runAction = menu.addAction(
            iconRun,
            QCoreApplication.translate("PythonConsole", "Enter Selected"),
            self.enteredSelected, QKeySequence(Qt.CTRL + Qt.Key_E))
        clearAction = menu.addAction(
            iconClear,
            QCoreApplication.translate("PythonConsole", "Clear Console"),
            self.clearConsole)
        menu.addSeparator()
        copyAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Copy"), self.copy,
            QKeySequence.Copy)
        selectAllAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Select All"),
            self.selectAll, QKeySequence.SelectAll)
        menu.addSeparator()
        menu.addAction(iconSettings,
                       QCoreApplication.translate("PythonConsole", "Options…"),
                       self.parent.openSettings)
        runAction.setEnabled(False)
        clearAction.setEnabled(False)
        copyAction.setEnabled(False)
        selectAllAction.setEnabled(False)
        showEditorAction.setEnabled(True)
        if self.hasSelectedText():
            runAction.setEnabled(True)
            copyAction.setEnabled(True)
        if not self.text(3) == '':
            selectAllAction.setEnabled(True)
            clearAction.setEnabled(True)
        if self.parent.tabEditorWidget.isVisible():
            showEditorAction.setEnabled(False)
        menu.exec_(self.mapToGlobal(e.pos()))

    def hideToolBar(self):
        tB = self.parent.toolBar
        tB.hide() if tB.isVisible() else tB.show()
        self.shell.setFocus()

    def showEditor(self):
        Ed = self.parent.splitterObj
        if not Ed.isVisible():
            Ed.show()
            self.parent.showEditorButton.setChecked(True)
        self.shell.setFocus()

    def copy(self):
        """Copy text to clipboard... or keyboard interrupt"""
        if self.hasSelectedText():
            text = self.selectedText()
            text = text.replace('>>> ',
                                '').replace('... ',
                                            '').strip()  # removing prompts
            QApplication.clipboard().setText(text)
        else:
            raise KeyboardInterrupt

    def enteredSelected(self):
        cmd = self.selectedText()
        self.shell.insertFromDropPaste(cmd)
        self.shell.entered()

    def keyPressEvent(self, e):
        # empty text indicates possible shortcut key sequence so stay in output
        txt = e.text()
        if len(txt) and txt >= " ":
            self.shell.append(txt)
            self.shell.move_cursor_to_end()
            self.shell.setFocus()
            e.ignore()
        else:
            # possible shortcut key sequence, accept it
            e.accept()

    def widgetMessageBar(self, iface, text):
        timeout = iface.messageTimeout()
        self.infoBar.pushMessage(text, Qgis.Info, timeout)
Example #10
0
class DBManager(QMainWindow):

    def __init__(self, iface, parent=None):
        QMainWindow.__init__(self, parent)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setupUi()
        self.iface = iface

        # restore the window state
        settings = QgsSettings()
        self.restoreGeometry(settings.value("/DB_Manager/mainWindow/geometry", QByteArray(), type=QByteArray))
        self.restoreState(settings.value("/DB_Manager/mainWindow/windowState", QByteArray(), type=QByteArray))

        self.tabs.currentChanged.connect(self.tabChanged)
        self.tree.selectedItemChanged.connect(self.itemChanged)
        self.tree.model().dataChanged.connect(self.iface.reloadConnections)
        self.itemChanged(None)

    def closeEvent(self, e):
        self.unregisterAllActions()
        # clear preview, this will delete the layer in preview tab
        self.preview.loadPreview(None)

        # save the window state
        settings = QgsSettings()
        settings.setValue("/DB_Manager/mainWindow/windowState", self.saveState())
        settings.setValue("/DB_Manager/mainWindow/geometry", self.saveGeometry())

        QMainWindow.closeEvent(self, e)

    def refreshItem(self, item=None):
        with OverrideCursor(Qt.WaitCursor):
            try:
                if item is None:
                    item = self.tree.currentItem()
                self.tree.refreshItem(item)  # refresh item children in the db tree
            except BaseError as e:
                DlgDbError.showError(e, self)

    def itemChanged(self, item):
        with OverrideCursor(Qt.WaitCursor):
            try:
                self.reloadButtons()
                # clear preview, this will delete the layer in preview tab
                self.preview.loadPreview(None)
                self.refreshTabs()
            except BaseError as e:
                DlgDbError.showError(e, self)

    def reloadButtons(self):
        db = self.tree.currentDatabase()
        if not hasattr(self, '_lastDb'):
            self._lastDb = db

        elif db == self._lastDb:
            return

        # remove old actions
        if self._lastDb is not None:
            self.unregisterAllActions()

        # add actions of the selected database
        self._lastDb = db
        if self._lastDb is not None:
            self._lastDb.registerAllActions(self)

    def tabChanged(self, index):
        with OverrideCursor(Qt.WaitCursor):
            try:
                self.refreshTabs()
            except BaseError as e:
                DlgDbError.showError(e, self)

    def refreshTabs(self):
        index = self.tabs.currentIndex()
        item = self.tree.currentItem()
        table = self.tree.currentTable()

        # enable/disable tabs
        self.tabs.setTabEnabled(self.tabs.indexOf(self.table), table is not None)
        self.tabs.setTabEnabled(self.tabs.indexOf(self.preview), table is not None and table.type in [table.VectorType,
                                                                                                      table.RasterType] and table.geomColumn is not None)
        # show the info tab if the current tab is disabled
        if not self.tabs.isTabEnabled(index):
            self.tabs.setCurrentWidget(self.info)

        current_tab = self.tabs.currentWidget()
        if current_tab == self.info:
            self.info.showInfo(item)
        elif current_tab == self.table:
            self.table.loadData(item)
        elif current_tab == self.preview:
            self.preview.loadPreview(item)

    def refreshActionSlot(self):
        self.info.setDirty()
        self.table.setDirty()
        self.preview.setDirty()
        self.refreshItem()

    def importActionSlot(self):
        db = self.tree.currentDatabase()
        if db is None:
            self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."),
                                     Qgis.Info, self.iface.messageTimeout())
            return

        outUri = db.uri()
        schema = self.tree.currentSchema()
        if schema:
            outUri.setDataSource(schema.name, "", "", "")

        from .dlg_import_vector import DlgImportVector

        dlg = DlgImportVector(None, db, outUri, self)
        dlg.exec_()

    def exportActionSlot(self):
        table = self.tree.currentTable()
        if table is None:
            self.infoBar.pushMessage(self.tr("Select the table you want export to file."), Qgis.Info,
                                     self.iface.messageTimeout())
            return

        inLayer = table.toMapLayer()
        if inLayer.type() != QgsMapLayer.VectorLayer:
            self.infoBar.pushMessage(
                self.tr("Select a vector or a tabular layer you want export."),
                Qgis.Warning, self.iface.messageTimeout())
            return

        from .dlg_export_vector import DlgExportVector

        dlg = DlgExportVector(inLayer, table.database(), self)
        dlg.exec_()

        inLayer.deleteLater()

    def runSqlWindow(self):
        db = self.tree.currentDatabase()
        if db is None:
            self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."),
                                     Qgis.Info, self.iface.messageTimeout())
            # force displaying of the message, it appears on the first tab (i.e. Info)
            self.tabs.setCurrentIndex(0)
            return

        from .dlg_sql_window import DlgSqlWindow

        query = DlgSqlWindow(self.iface, db, self)
        dbname = db.connection().connectionName()
        tabname = self.tr("Query ({0})").format(dbname)
        index = self.tabs.addTab(query, tabname)
        self.tabs.setTabIcon(index, db.connection().icon())
        self.tabs.setCurrentIndex(index)
        query.nameChanged.connect(functools.partial(self.update_query_tab_name, index, dbname))

    def runSqlLayerWindow(self, layer):
        from .dlg_sql_layer_window import DlgSqlLayerWindow
        query = DlgSqlLayerWindow(self.iface, layer, self)
        lname = layer.name()
        tabname = self.tr("Layer ({0})").format(lname)
        index = self.tabs.addTab(query, tabname)
        # self.tabs.setTabIcon(index, db.connection().icon())
        self.tabs.setCurrentIndex(index)

    def update_query_tab_name(self, index, dbname, queryname):
        if not queryname:
            queryname = self.tr("Query")
        tabname = u"%s (%s)" % (queryname, dbname)
        self.tabs.setTabText(index, tabname)

    def showSystemTables(self):
        self.tree.showSystemTables(self.actionShowSystemTables.isChecked())

    def registerAction(self, action, menuName, callback=None):
        """ register an action to the manager's main menu """
        if not hasattr(self, '_registeredDbActions'):
            self._registeredDbActions = {}

        if callback is not None:
            def invoke_callback(x):
                return self.invokeCallback(callback)

        if menuName is None or menuName == "":
            self.addAction(action)

            if menuName not in self._registeredDbActions:
                self._registeredDbActions[menuName] = list()
            self._registeredDbActions[menuName].append(action)

            if callback is not None:
                action.triggered.connect(invoke_callback)
            return True

        # search for the menu
        actionMenu = None
        helpMenuAction = None
        for a in self.menuBar.actions():
            if not a.menu() or a.menu().title() != menuName:
                continue
            if a.menu() != self.menuHelp:
                helpMenuAction = a

            actionMenu = a
            break

        # not found, add a new menu before the help menu
        if actionMenu is None:
            menu = QMenu(menuName, self)
            if helpMenuAction is not None:
                actionMenu = self.menuBar.insertMenu(helpMenuAction, menu)
            else:
                actionMenu = self.menuBar.addMenu(menu)

        menu = actionMenu.menu()
        menuActions = menu.actions()

        # get the placeholder's position to insert before it
        pos = 0
        for pos in range(len(menuActions)):
            if menuActions[pos].isSeparator() and menuActions[pos].objectName().endswith("_placeholder"):
                menuActions[pos].setVisible(True)
                break

        if pos < len(menuActions):
            before = menuActions[pos]
            menu.insertAction(before, action)
        else:
            menu.addAction(action)

        actionMenu.setVisible(True)  # show the menu

        if menuName not in self._registeredDbActions:
            self._registeredDbActions[menuName] = list()
        self._registeredDbActions[menuName].append(action)

        if callback is not None:
            action.triggered.connect(invoke_callback)

        return True

    def invokeCallback(self, callback, *params):
        """ Call a method passing the selected item in the database tree,
                the sender (usually a QAction), the plugin mainWindow and
                optionally additional parameters.

                This method takes care to override and restore the cursor,
                but also catches exceptions and displays the error dialog.
        """
        with OverrideCursor(Qt.WaitCursor):
            try:
                callback(self.tree.currentItem(), self.sender(), self, *params)
            except BaseError as e:
                # catch database errors and display the error dialog
                DlgDbError.showError(e, self)

    def unregisterAction(self, action, menuName):
        if not hasattr(self, '_registeredDbActions'):
            return

        if menuName is None or menuName == "":
            self.removeAction(action)

            if menuName in self._registeredDbActions:
                if self._registeredDbActions[menuName].count(action) > 0:
                    self._registeredDbActions[menuName].remove(action)

            action.deleteLater()
            return True

        for a in self.menuBar.actions():
            if not a.menu() or a.menu().title() != menuName:
                continue

            menu = a.menu()
            menuActions = menu.actions()

            menu.removeAction(action)
            if menu.isEmpty():  # hide the menu
                a.setVisible(False)

            if menuName in self._registeredDbActions:
                if self._registeredDbActions[menuName].count(action) > 0:
                    self._registeredDbActions[menuName].remove(action)

                # hide the placeholder if there're no other registered actions
                if len(self._registeredDbActions[menuName]) <= 0:
                    for i in range(len(menuActions)):
                        if menuActions[i].isSeparator() and menuActions[i].objectName().endswith("_placeholder"):
                            menuActions[i].setVisible(False)
                            break

            action.deleteLater()
            return True

        return False

    def unregisterAllActions(self):
        if not hasattr(self, '_registeredDbActions'):
            return

        for menuName in self._registeredDbActions:
            for action in list(self._registeredDbActions[menuName]):
                self.unregisterAction(action, menuName)
        del self._registeredDbActions

    def close_tab(self, index):
        widget = self.tabs.widget(index)
        if widget not in [self.info, self.table, self.preview]:
            self.tabs.removeTab(index)
            widget.deleteLater()

    def setupUi(self):
        self.setWindowTitle(self.tr("DB Manager"))
        self.setWindowIcon(QIcon(":/db_manager/icon"))
        self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint()))

        # create central tab widget and add the first 3 tabs: info, table and preview
        self.tabs = QTabWidget()
        self.info = InfoViewer(self)
        self.tabs.addTab(self.info, self.tr("Info"))
        self.table = TableViewer(self)
        self.tabs.addTab(self.table, self.tr("Table"))
        self.preview = LayerPreview(self)
        self.tabs.addTab(self.preview, self.tr("Preview"))
        self.setCentralWidget(self.tabs)

        # display close button for all tabs but the first 3 ones, i.e.
        # HACK: just hide the close button where not needed (GS)
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.close_tab)
        tabbar = self.tabs.tabBar()
        for i in range(3):
            btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide)
            btn.resize(0, 0)
            btn.hide()

        # Creates layout for message bar
        self.layout = QGridLayout(self.info)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # init messageBar instance
        self.infoBar = QgsMessageBar(self.info)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        # create database tree
        self.dock = QDockWidget("Tree", self)
        self.dock.setObjectName("DB_Manager_DBView")
        self.dock.setFeatures(QDockWidget.DockWidgetMovable)
        self.tree = DBTree(self)
        self.dock.setWidget(self.tree)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock)

        # create status bar
        self.statusBar = QStatusBar(self)
        self.setStatusBar(self.statusBar)

        # create menus
        self.menuBar = QMenuBar(self)
        self.menuDb = QMenu(self.tr("&Database"), self)
        self.menuBar.addMenu(self.menuDb)
        self.menuSchema = QMenu(self.tr("&Schema"), self)
        actionMenuSchema = self.menuBar.addMenu(self.menuSchema)
        self.menuTable = QMenu(self.tr("&Table"), self)
        actionMenuTable = self.menuBar.addMenu(self.menuTable)
        self.menuHelp = None  # QMenu(self.tr("&Help"), self)
        # actionMenuHelp = self.menuBar.addMenu(self.menuHelp)

        self.setMenuBar(self.menuBar)

        # create toolbar
        self.toolBar = QToolBar("Default", self)
        self.toolBar.setObjectName("DB_Manager_ToolBar")
        self.addToolBar(self.toolBar)

        # create menus' actions

        # menu DATABASE
        sep = self.menuDb.addSeparator()
        sep.setObjectName("DB_Manager_DbMenu_placeholder")
        sep.setVisible(False)

        self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"),
                                                   self.refreshActionSlot, QKeySequence("F5"))
        self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"),
                                                     self.runSqlWindow, QKeySequence("F2"))
        self.menuDb.addSeparator()
        self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q"))

        # menu SCHEMA
        sep = self.menuSchema.addSeparator()
        sep.setObjectName("DB_Manager_SchemaMenu_placeholder")
        sep.setVisible(False)

        actionMenuSchema.setVisible(False)

        # menu TABLE
        sep = self.menuTable.addSeparator()
        sep.setObjectName("DB_Manager_TableMenu_placeholder")
        sep.setVisible(False)

        self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"),
                                                     self.tr("&Import layer/file"), self.importActionSlot)
        self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"),
                                                     self.exportActionSlot)
        self.menuTable.addSeparator()
        #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables)
        #self.actionShowSystemTables.setCheckable(True)
        #self.actionShowSystemTables.setChecked(True)
        actionMenuTable.setVisible(False)

        # add actions to the toolbar
        self.toolBar.addAction(self.actionRefresh)
        self.toolBar.addAction(self.actionSqlWindow)
        self.toolBar.addAction(self.actionImport)
        self.toolBar.addAction(self.actionExport)
Example #11
0
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(
            QtCore.QSize(QtCore.QRect(0, 0, 440, 660).size()).expandedTo(
                Dialog.minimumSizeHint()))

        self.gridlayout = QGridLayout(Dialog)
        self.gridlayout.setObjectName("gridlayout")

        font = QFont()
        font.setPointSize(15)
        font.setWeight(50)
        font.setBold(True)

        self.label_2 = QLabel(Dialog)
        self.label_2.setFont(font)
        self.label_2.setTextFormat(QtCore.Qt.RichText)
        self.label_2.setObjectName("label_2")
        self.gridlayout.addWidget(self.label_2, 1, 1, 1, 2)

        self.textEdit = QTextEdit(Dialog)

        palette = QPalette()

        brush = QBrush(QColor(0, 0, 0, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QPalette.Active, QPalette.Base, brush)

        brush = QBrush(QColor(0, 0, 0, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QPalette.Inactive, QPalette.Base, brush)

        brush = QBrush(QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QPalette.Disabled, QPalette.Base, brush)
        self.textEdit.setPalette(palette)
        self.textEdit.setAutoFillBackground(True)
        self.textEdit.width = 320
        self.textEdit.height = 360
        self.textEdit.setFrameShape(QFrame.NoFrame)
        self.textEdit.setFrameShadow(QFrame.Plain)
        self.textEdit.setReadOnly(True)
        self.textEdit.setObjectName("textEdit")
        self.textEdit.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction)

        self.gridlayout.addWidget(self.textEdit, 2, 1, 5, 2)

        self.pushButton = QPushButton(Dialog)
        self.pushButton.setObjectName("pushButton")
        self.gridlayout.addWidget(self.pushButton, 4, 2, 1, 1)

        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        self.gridlayout.addItem(spacerItem, 3, 1, 1, 1)

        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(
            QApplication.translate("Dialog", "GroupPointsWithinDistance",
                                   None))
        self.label_2.setText(
            QApplication.translate("Dialog", "GroupPointsWithinDistance 0.2",
                                   None))
        self.textEdit.setHtml(
            QApplication.translate(
                "Dialog",
                "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                "p, li { white-space: pre-wrap; }\n"
                "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:8pt; font-weight:400; font-style:normal;\">\n"
                "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'MS Shell Dlg 2\'; font-size:8pt;\"><span style=\" font-weight:600;\">"
                " GroupPointsWithinDistance 0.2 :</span>"
                "  A little QGIS plugin to find and group/aggregate points of a points' layer if they are at a given distance of one another.</b>\n"
                +
                "                                                                                                                                                                                           \n"
                +
                " <br><b>WARNING:</b><br><b> Work with projected datas only, in other words do not use geographical (long-lat type) reference systems !</b>\n "
                +
                "                                                                                                                                             \n"
                + "             \n" +
                "This plugin is meant to deal with points datas (not multipoints, convert first to points) (for instance faunistic or floristic observations), nearby from one another, that the user wants to be regrouped/aggregated as a station.\n"
                + "\n" +
                "                                                                                                                                                                                                                    \n"
                +
                "The user should appreciate and cheack which distance to use, and - may be - keep the distance chosen as small as possible in order to avoid '"
                'chains effect'
                "' and producing too widespread groups .\n" +
                "                                                                                                                                          \n"
                + "The plugin produces a layer of point called '"
                'input_layer_name_aggregated_with_Distance'
                "' with 3 mores attributes:                                                          \n"
                +
                "                                                                                                                                                                                                                    \n"
                +
                " - Point_id: the point id,                                                                                                                                                              \n"
                +
                "                                                                                                                                                                                                                    \n"
                + " - NumAggreg: the '"
                'aggregates id number'
                "'                                                                                                                                                              \n"
                +
                "                                                                                                                                                                                                                    \n"
                +
                " - Nb_Pts: the number of regrouped points,                                              \n "
                + "\n" +
                "                                                                                                                                                                                                                    \n"
                +
                " - List_Pts: the list of the points ids in the aggregate.                                                                                                                     \n"
                + "\n" +
                "                                                                                                                                          \n"
                +
                "                                                                                                                                                          \n"
                + "\n" +
                " The plugin also produce a line layer, with not all lines connecting points of a same aggregate but showing only the very one of the connections that were made to link the points as part of a same aggregate."
                " the plugin also produces a layer of polygons overlaping the regrouped points within distance with an attribute table with also NumAggreg,Nb_Pts,List_Pts attributes.    \n "
                + "\n" +
                "                                                                                                                                                                \n"
                +
                "  The polygons are buffers (D/100) of the convex hull polygons of the aggregated points \n "
                +
                "                                                                                                                                                          \n"
                + "\n" +
                "<br><b>WARNING 2:</b><br> The polygons are meant - as the lines - only to show the aggregates but they overlap often points that are not part of the aggregate. The lines can be used for that matter  \n"
                +
                "<br><b>In order to select point of an aggregate only consider the point table attribute !</b><br>"
                "                                                                                                                                                          \n"
                + "\n" +
                " <br><b><i>NOTA BENE: all rasters should be unchecked in layer panel or the plugin won't work !</i></b></br>"
                " This plugin is not a part of Qgis engine and any problems should be reported only to the author. </p></td></tr></table>"
                "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
                "<p style=\"margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">"
                "                   "
                "<br><b>[email protected]</b><br>"
                "<br><br><i>code 0.2 (26 march 2019).</i></p></body></html>",
                None))
        self.pushButton.setText(QApplication.translate("Dialog", "OK", None))
Example #12
0
class CustomFeatureForm(QDialog, FORM_CLASS):
    """
    Customized form tailor made for reclassification mode of DSGTools: Custom
    Feature Tool Box. This form was copied from `Ferramentas de Produção` and
    modified for the DSGTools plugin.
    """
    def __init__(self, layer, layerMap, attributeMap=None, valueMaps=None):
        """
        Class constructor.
        :param layer: (QgsVectorLayer) layer that will receive the reclassified
                      features.
        :param layerMap: (dict) a map from vector layer to feature list to be
                         reclassified (allocated to another layer).
        :param attributeMap: (dict) a map from attribute name to its
                             (reclassified) value.
        :param valueMaps: (dict) map of all value/relations maps set to layer's
                          fields. These maps will be used for domain checking
                          operations. 
        """
        super(CustomFeatureForm, self).__init__()
        self.setupUi(self)
        self._layer = layer
        self.layerMap = layerMap
        self.valueMaps = valueMaps or LayerHandler().valueMaps(layer)
        self.attributeMap = attributeMap or dict()
        self._layersWidgets = dict()
        self.setupReclassifiedLayers()
        self.widgetsLayout = QGridLayout(self.scrollAreaWidgetContents)
        self._fieldsWidgets = dict()
        self.setupFields()
        self.setWindowTitle(self.tr("DSGTools Feature Reclassification Form"))
        self.messageBar = QgsMessageBar(self)

    def resizeEvent(self, e):
        """
        Just make sure if any alert box is being displayed, it matches the
        dialog size. Method reimplementation.
        :param e: (QResizeEvent) resize event related to this widget resizing.
        """
        self.messageBar.resize(
            QSize(
                self.geometry().size().width(),
                40  # this felt nicer than the original height (30)
            ))

    def setupReclassifiedLayers(self):
        """
        Fills GUI with the data for reclassified data. Dialog should allow user
        to choose whether he wants to reclassify all identified layers or just
        part of it.
        """
        layout = self.vLayout
        for l, fl in self.layerMap.items():
            cb = QCheckBox()
            size = len(fl)
            fCount = self.tr("features") if size > 1 else self.tr("feature")
            cb.setText("{0} ({1} {2})".format(l.name(), size, fCount))
            cb.setChecked(True)
            # just to avoid reading the layout when reading the form
            self._layersWidgets[l.name()] = cb
            layout.addWidget(cb)

    def fieldHasDomainMap(self, field):
        """
        Identifies whether a given field has a value/relations map.
        :param field: (QgsField) field to be checked.
        :return: (bool) whether field has a value/relations map set.
        """
        return field.name() in self.valueMaps

    def getFieldComboBox(self, field):
        """
        Provides a combo box containing all values possible for a field set to
        have value/relations map value. This method also set a getValue and
        setValue proxy that handles value management through its 'real' value.
        E.G. a given domain {"Not available": 1, "Available": 2} shall have its
        values set and read as '1' and '2', instead of either combo box's text
        and index usually used. This also handles setting invalid value setting
        attempts.
        :param field: (QgsField) field to have its field's values exposed.
        :return: (QComboBox) combo box widget filled with all possible values.
        """
        cb = QComboBox()
        # this methods assumes that if a field is used, than it has a value map
        domain = self.valueMaps.get(field.name(), None)
        inverseDomain = {v: k for k, v in domain.items()}
        if not domain:
            raise ValueError(
                self.tr("Field {0} does not have a value/relations map")\
                    .format(field.name())
            )
        cb.addItems(list(domain.keys()))

        def setValue(val):
            """val: field's real value"""
            if val not in domain.values():
                return
            cb.setCurrentText(inverseDomain[val])

        def value():
            return domain[cb.currentText()]

        cb.setValue = setValue
        cb.value = value
        return cb

    def layer(self):
        """
        Retrieves layer set to receive the reclassified features from the
        other layers.
        :return: (QgsVectorLayer) layer to get the newly reclassified features.
        """
        return self._layer

    def setupFields(self):
        """
        Sets up all fields and fill up with available data on the attribute
        map.
        """
        utils = Utils()
        row = 0  # in case no fields are provided
        for row, f in enumerate(self.layer().fields()):
            fName = f.name()
            fMap = self.attributeMap.get(fName, None)
            if fName in self.attributeMap:
                fMap = self.attributeMap[fName]
                if fMap["ignored"]:
                    w = QLineEdit()
                    w.setText(self.tr("Field is set to be ignored"))
                    value = None
                    enabled = False
                else:
                    value = fMap["value"]
                    enabled = fMap["editable"]
                if fMap["isPk"]:
                    # visually identify primary key attributes
                    text = '<p>{0} <img src=":/plugins/DsgTools/icons/key.png" '\
                           'width="16" height="16"></p>'.format(fName)
                else:
                    text = fName
            else:
                value = None
                enabled = True
                text = fName
            if fName in self.attributeMap and self.attributeMap[fName][
                    "ignored"]:
                pass
            if self.fieldHasDomainMap(f):
                # this will provide the combo box already filled with the
                # possible values for the provided field
                w = self.getFieldComboBox(f)
                # proxy method added on customized qcombobox
                w.setValue(value)
            elif utils.fieldIsBool(f):
                w = QCheckBox()
                w.setChecked(False if value is None else value)
            elif utils.fieldIsFloat(f):
                w = QDoubleSpinBox()
                w.setValue(0 if value is None else value)
            elif utils.fieldIsInt(f):
                w = QSpinBox()
                w.setValue(0 if value is None else value)
            else:
                w = QLineEdit()
                w.setText("" if value is None else value)
            w.setEnabled(enabled)
            # also to make easier to read data
            self._fieldsWidgets[fName] = w
            label = QLabel(text)
            label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
            w.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
            self.widgetsLayout.addWidget(label, row, 0)
            self.widgetsLayout.addWidget(w, row, 1)
        self.widgetsLayout.addItem(
            QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding),
            row + 1, 1, 1, 2)  # row, col, rowSpan, colSpan

    def updateAttributeMap(self):
        """
        Reads all filled data and updated attribute map with such values.
        """
        for fName, w in self._fieldsWidgets.items():
            if not fName in self.attributeMap:
                self.attributeMap[fName] = dict()
                self.attributeMap[fName]["ignored"] = False
                self.attributeMap[fName]["editable"] = True
            if self.attributeMap[fName]["ignored"]:
                continue
            w = self._fieldsWidgets[fName]
            if isinstance(w, QSpinBox) or isinstance(w, QDoubleSpinBox):
                self.attributeMap[fName]["value"] = w.value()
            elif isinstance(w, QCheckBox):
                self.attributeMap[fName]["value"] = w.isChecked()
            elif isinstance(w, QComboBox):
                self.attributeMap[fName]["value"] = w.value()
            else:
                self.attributeMap[fName]["value"] = w.text()

    def readSelectedLayers(self):
        """
        Applies a filter over the layer/feature list map based on user
        selection.
        :return: (dict) filtered layer-feature list map.
        """
        filtered = dict()
        for l, fl in self.layerMap.items():
            if self._layersWidgets[l.name()].isChecked():
                filtered[l] = fl
        return filtered

    def readFieldMap(self):
        """
        Reads filled data into the form and sets it to a map from field name to
        field value to be set. Only fields allowed to be reclassified shall be
        exported in this method.
        :return: (dict) a map from field name to its output value.
        """
        fMap = dict()
        for fName, w in self._fieldsWidgets.items():
            if not fName in self.attributeMap:
                continue
            w = self._fieldsWidgets[fName]
            if isinstance(w, QSpinBox) or isinstance(w, QDoubleSpinBox):
                fMap[fName] = w.value()
            elif isinstance(w, QCheckBox):
                fMap[fName] = w.isChecked()
            elif isinstance(w, QComboBox):
                fMap[fName] = w.value()
            else:
                fMap[fName] = w.text()
        return fMap

    @pyqtSlot()
    def on_okPushButton_clicked(self):
        """
        Verifies if at least one layer is selected and either warn user to
        select one, or closes with status 1 ("OK").
        """
        if len(self.readSelectedLayers()) > 0:
            self.updateAttributeMap()
            self.done(1)
        else:
            self.messageBar.pushMessage(
                self.tr('Invalid layer selection'),
                self.tr("select at least one layer for reclassification!"),
                level=Qgis.Warning,
                duration=5)
Example #13
0
class CustomFeatureForm(QDialog, FORM_CLASS):
    """
    Customized form tailor made for reclassification mode of DSGTools: Custom
    Feature Tool Box. This form was copied from `Ferramentas de Produção` and
    modified for the DSGTools plugin.
    """
    def __init__(self, fields, layerMap, attributeMap=None):
        """
        Class constructor.
        :param fields: (QgsFields) set of fields that will be applied to new
                       feature(s).
        :param layerMap: (dict) a map from vector layer to feature list to be
                         reclassified (allocated to another layer).
        :param attributeMap: (dict) a map from attribute name to its
                             (reclassified) value.
        """
        super(CustomFeatureForm, self).__init__()
        self.setupUi(self)
        self.fields = fields
        self.layerMap = layerMap
        self.attributeMap = attributeMap or dict()
        self._layersWidgets = dict()
        self.setupReclassifiedLayers()
        self.widgetsLayout = QGridLayout(self.scrollAreaWidgetContents)
        self._fieldsWidgets = dict()
        self.setupFields()
        self.setWindowTitle(self.tr("DSGTools Feature Reclassification Form"))
        self.messageBar = QgsMessageBar(self)

    def resizeEvent(self, e):
        """
        Just make sure if any alert box is being displayed, it matches the
        dialog size. Method reimplementation.
        :param e: (QResizeEvent) resize event related to this widget resizing.
        """
        self.messageBar.resize(
            QSize(
                self.geometry().size().width(),
                40  # this felt nicer than the original height (30)
            ))

    def setupReclassifiedLayers(self):
        """
        Fills GUI with the data for reclassified data. Dialog should allow user
        to choose whether he wants to reclassify all identified layers or just
        part of it.
        """
        layout = self.vLayout
        for l, fl in self.layerMap.items():
            cb = QCheckBox()
            size = len(fl)
            fCount = self.tr("features") if size > 1 else self.tr("feature")
            cb.setText("{0} ({1} {2})".format(l.name(), size, fCount))
            cb.setChecked(True)
            # just to avoid reading the layout when reading the form
            self._layersWidgets[l.name()] = cb
            layout.addWidget(cb)

    def setupFields(self):
        """
        Setups up all fields and fill up with available data on the attribute
        map.
        """
        utils = Utils()
        row = 0  # in case no fields are provided
        for row, f in enumerate(self.fields):
            fName = f.name()
            fMap = self.attributeMap[fName] if fName in self.attributeMap \
                        else None
            if fName in self.attributeMap:
                fMap = self.attributeMap[fName]
                if fMap["ignored"]:
                    w = QLineEdit()
                    w.setText(self.tr("Field is set to be ignored"))
                    value = None
                    enabled = False
                else:
                    value = fMap["value"]
                    enabled = fMap["editable"]
                if fMap["isPk"]:
                    # visually identify primary key attributes
                    text = '<p>{0} <img src=":/plugins/DsgTools/icons/key.png" '\
                           'width="16" height="16"></p>'.format(fName)
                else:
                    text = fName
            else:
                value = None
                enabled = True
                text = fName
            if fName in self.attributeMap and self.attributeMap[fName][
                    "ignored"]:
                pass
            elif utils.fieldIsFloat(f):
                w = QDoubleSpinBox()
                w.setValue(0 if value is None else value)
            elif utils.fieldIsInt(f):
                w = QSpinBox()
                w.setValue(0 if value is None else value)
            else:
                w = QLineEdit()
                w.setText("" if value is None else value)
            w.setEnabled(enabled)
            # also to make easier to read data
            self._fieldsWidgets[fName] = w
            label = QLabel(text)
            label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
            w.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
            self.widgetsLayout.addWidget(label, row, 0)
            self.widgetsLayout.addWidget(w, row, 1)
        self.widgetsLayout.addItem(
            QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding),
            row + 1, 1, 1, 2)  # row, col, rowSpan, colSpan

    def updateAttributeMap(self):
        """
        Reads all filled data and updated attribute map with such values.
        """
        for fName, w in self._fieldsWidgets.items():
            if not fName in self.attributeMap:
                self.attributeMap[fName] = dict()
                self.attributeMap[fName]["ignored"] = False
                self.attributeMap[fName]["editable"] = True
            if self.attributeMap[fName]["ignored"]:
                continue
            w = self._fieldsWidgets[fName]
            if isinstance(w, QSpinBox) or isinstance(w, QDoubleSpinBox):
                self.attributeMap[fName]["value"] = w.value()
            else:
                self.attributeMap[fName]["value"] = w.text()

    def readSelectedLayers(self):
        """
        Applies a filter over the layer/feature list map based on user
        selection.
        :return: (dict) filtered layer-feature list map.
        """
        filtered = dict()
        for l, fl in self.layerMap.items():
            if self._layersWidgets[l.name()].isChecked():
                filtered[l] = fl
        return filtered

    def readFieldMap(self):
        """
        Reads filled data into the form and sets it to a map from field name to
        field value to be set. Only fields allowed to be reclassified shall be
        exported in this method.
        :return: (dict) a map from field name to its output value.
        """
        fMap = dict()
        for fName, w in self._fieldsWidgets.items():
            if not fName in self.attributeMap:
                continue
            w = self._fieldsWidgets[fName]
            if isinstance(w, QSpinBox) or isinstance(w, QDoubleSpinBox):
                fMap[fName] = w.value()
            else:
                fMap[fName] = w.text()
        return fMap

    @pyqtSlot()
    def on_okPushButton_clicked(self):
        """
        Verifies if at least one layer is selected and either warn user to
        select one, or closes with status 1 ("OK").
        """
        if len(self.readSelectedLayers()) > 0:
            self.updateAttributeMap()
            self.done(1)
        else:
            self.messageBar.pushMessage(
                self.tr('Invalid layer selection'),
                self.tr("select at least one layer for reclassification!"),
                level=Qgis.Warning,
                duration=5)
Example #14
0
class ShellOutputScintilla(QsciScintilla):

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

        self.settings = QSettings()

        # Creates layout for message bar
        self.layout = QGridLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.layout.addItem(spacerItem, 1, 0, 1, 1)
        # messageBar instance
        self.infoBar = QgsMessageBar()
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.infoBar.setSizePolicy(sizePolicy)
        self.layout.addWidget(self.infoBar, 0, 0, 1, 1)

        # Enable non-ascii chars for editor
        self.setUtf8(True)

        sys.stdout = writeOut(self, sys.stdout)
        sys.stderr = writeOut(self, sys.stderr, "_traceback")

        self.insertInitText()
        self.refreshSettingsOutput()
        self.setReadOnly(True)

        # Set the default font
        font = QFont()
        font.setFamily('Courier')
        font.setFixedPitch(True)
        font.setPointSize(10)
        self.setFont(font)
        self.setMarginsFont(font)
        # Margin 0 is used for line numbers
        self.setMarginWidth(0, 0)
        self.setMarginWidth(1, 0)
        self.setMarginWidth(2, 0)
        #fm = QFontMetrics(font)
        self.setMarginsFont(font)
        self.setMarginWidth(1, "00000")
        self.setMarginLineNumbers(1, True)
        self.setMarginsForegroundColor(QColor("#3E3EE3"))
        self.setMarginsBackgroundColor(QColor("#f9f9f9"))
        self.setCaretLineVisible(True)
        self.setCaretWidth(0)

        self.setMinimumHeight(120)

        self.setWrapMode(QsciScintilla.WrapCharacter)
        self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)

        self.runScut = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_E), self)
        self.runScut.setContext(Qt.WidgetShortcut)
        self.runScut.activated.connect(self.enteredSelected)
        # Reimplemeted copy action to prevent paste prompt (>>>,...) in command view
        self.copyShortcut = QShortcut(QKeySequence.Copy, self)
        self.copyShortcut.activated.connect(self.copy)
        self.selectAllShortcut = QShortcut(QKeySequence.SelectAll, self)
        self.selectAllShortcut.activated.connect(self.selectAll)

    def insertInitText(self):
        txtInit = QCoreApplication.translate("PythonConsole",
                                             "Python Console \n"
                                             "Use iface to access QGIS API interface or Type help(iface) for more info")

        ## some translation string for the console header ends without '\n'
        ## and the first command in console will be appended at the header text.
        ## The following code add a '\n' at the end of the string if not present.
        if txtInit.endswith('\n'):
            self.setText(txtInit)
        else:
            self.setText(txtInit + '\n')

    def refreshSettingsOutput(self):
        # Set Python lexer
        self.setLexers()
        caretLineColor = self.settings.value("pythonConsole/caretLineColor", QColor("#fcf3ed"))
        cursorColor = self.settings.value("pythonConsole/cursorColor", QColor(Qt.black))
        self.setCaretLineBackgroundColor(caretLineColor)
        self.setCaretForegroundColor(cursorColor)

    def setLexers(self):
        self.lexer = QsciLexerPython()

        loadFont = self.settings.value("pythonConsole/fontfamilytext", "Monospace")
        fontSize = self.settings.value("pythonConsole/fontsize", 10, type=int)
        font = QFont(loadFont)
        font.setFixedPitch(True)
        font.setPointSize(fontSize)
        font.setStyleHint(QFont.TypeWriter)
        font.setStretch(QFont.SemiCondensed)
        font.setLetterSpacing(QFont.PercentageSpacing, 87.0)
        font.setBold(False)

        self.lexer.setDefaultFont(font)
        self.lexer.setDefaultColor(QColor(self.settings.value("pythonConsole/defaultFontColor", QColor(Qt.black))))
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/commentFontColor", QColor(Qt.gray))), 1)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/keywordFontColor", QColor(Qt.darkGreen))), 5)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/classFontColor", QColor(Qt.blue))), 8)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/methodFontColor", QColor(Qt.darkGray))), 9)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/decorFontColor", QColor(Qt.darkBlue))), 15)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/commentBlockFontColor", QColor(Qt.gray))), 12)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/singleQuoteFontColor", QColor(Qt.blue))), 4)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/doubleQuoteFontColor", QColor(Qt.blue))), 3)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/tripleSingleQuoteFontColor", QColor(Qt.blue))), 6)
        self.lexer.setColor(QColor(self.settings.value("pythonConsole/tripleDoubleQuoteFontColor", QColor(Qt.blue))), 7)
        self.lexer.setColor(QColor(Qt.red), 14)
        self.lexer.setFont(font, 1)
        self.lexer.setFont(font, 2)
        self.lexer.setFont(font, 3)
        self.lexer.setFont(font, 4)

        for style in range(0, 33):
            paperColor = QColor(self.settings.value("pythonConsole/paperBackgroundColor", QColor(Qt.white)))
            self.lexer.setPaper(paperColor, style)

        self.setLexer(self.lexer)

    def clearConsole(self):
        self.setText('')
        self.insertInitText()
        self.shell.setFocus()

    def contextMenuEvent(self, e):
        menu = QMenu(self)
        iconRun = QgsApplication.getThemeIcon("console/iconRunConsole.png")
        iconClear = QgsApplication.getThemeIcon("console/iconClearConsole.png")
        iconHideTool = QgsApplication.getThemeIcon("console/iconHideToolConsole.png")
        iconSettings = QgsApplication.getThemeIcon("console/iconSettingsConsole.png")
        menu.addAction(iconHideTool,
                       QCoreApplication.translate("PythonConsole", "Hide/Show Toolbar"),
                       self.hideToolBar)
        menu.addSeparator()
        showEditorAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Show Editor"),
            self.showEditor)
        menu.addSeparator()
        runAction = menu.addAction(iconRun,
                                   QCoreApplication.translate("PythonConsole", "Enter Selected"),
                                   self.enteredSelected,
                                   QKeySequence(Qt.CTRL + Qt.Key_E))
        clearAction = menu.addAction(iconClear,
                                     QCoreApplication.translate("PythonConsole", "Clear Console"),
                                     self.clearConsole)
        menu.addSeparator()
        copyAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Copy"),
            self.copy, QKeySequence.Copy)
        selectAllAction = menu.addAction(
            QCoreApplication.translate("PythonConsole", "Select All"),
            self.selectAll, QKeySequence.SelectAll)
        menu.addSeparator()
        menu.addAction(iconSettings,
                       QCoreApplication.translate("PythonConsole", "Options..."),
                       self.parent.openSettings)
        runAction.setEnabled(False)
        clearAction.setEnabled(False)
        copyAction.setEnabled(False)
        selectAllAction.setEnabled(False)
        showEditorAction.setEnabled(True)
        if self.hasSelectedText():
            runAction.setEnabled(True)
            copyAction.setEnabled(True)
        if not self.text(3) == '':
            selectAllAction.setEnabled(True)
            clearAction.setEnabled(True)
        if self.parent.tabEditorWidget.isVisible():
            showEditorAction.setEnabled(False)
        menu.exec_(self.mapToGlobal(e.pos()))

    def hideToolBar(self):
        tB = self.parent.toolBar
        tB.hide() if tB.isVisible() else tB.show()
        self.shell.setFocus()

    def showEditor(self):
        Ed = self.parent.splitterObj
        if not Ed.isVisible():
            Ed.show()
            self.parent.showEditorButton.setChecked(True)
        self.shell.setFocus()

    def copy(self):
        """Copy text to clipboard... or keyboard interrupt"""
        if self.hasSelectedText():
            text = self.selectedText()
            text = text.replace('>>> ', '').replace('... ', '').strip()  # removing prompts
            QApplication.clipboard().setText(text)
        else:
            raise KeyboardInterrupt

    def enteredSelected(self):
        cmd = self.selectedText()
        self.shell.insertFromDropPaste(cmd)
        self.shell.entered()

    def keyPressEvent(self, e):
        # empty text indicates possible shortcut key sequence so stay in output
        txt = e.text()
        if len(txt) and txt >= " ":
            self.shell.append(txt)
            self.shell.move_cursor_to_end()
            self.shell.setFocus()
            e.ignore()
        else:
            # possible shortcut key sequence, accept it
            e.accept()

    def widgetMessageBar(self, iface, text):
        timeout = iface.messageTimeout()
        self.infoBar.pushMessage(text, QgsMessageBar.INFO, timeout)
Example #15
0
    def get_selector(self,
                     dialog,
                     selector_type,
                     filter=False,
                     widget=None,
                     text_filter=None,
                     current_tab=None):
        """
        Ask to DB for selectors and make dialog
            :param dialog: Is a standard dialog, from file selector.ui, where put widgets
            :param selector_type: List of selectors to ask DB ['exploitation', 'state', ...]
        """

        index = 0
        main_tab = dialog.findChild(QTabWidget, 'main_tab')

        # Set filter
        if filter is not False:
            main_tab = dialog.findChild(QTabWidget, 'main_tab')
            text_filter = tools_qt.get_text(dialog, widget)
            if text_filter in ('null', None):
                text_filter = ''

            # Set current_tab
            index = dialog.main_tab.currentIndex()
            current_tab = dialog.main_tab.widget(index).objectName()

        # Profilactic control of nones
        if text_filter is None:
            text_filter = ''
        # Built querytext
        form = f'"currentTab":"{current_tab}"'
        extras = f'"selectorType":{selector_type}, "filterText":"{text_filter}"'
        body = tools_gw.create_body(form=form, extras=extras)
        json_result = tools_gw.execute_procedure('gw_fct_getselectors', body)

        if not json_result or json_result['status'] == 'Failed':
            return False

        # Get styles
        stylesheet = json_result['body']['form'][
            'style'] if 'style' in json_result['body']['form'] else None
        color_rows = False
        if stylesheet:
            # Color selectors zebra-styled
            if 'rowsColor' in stylesheet and stylesheet[
                    'rowsColor'] is not None:
                color_rows = tools_os.set_boolean(stylesheet['rowsColor'],
                                                  False)

        for form_tab in json_result['body']['form']['formTabs']:

            if filter and form_tab['tabName'] != str(current_tab):
                continue

            selection_mode = form_tab['selectionMode']

            # Create one tab for each form_tab and add to QTabWidget
            tab_widget = QWidget(main_tab)
            tab_widget.setObjectName(form_tab['tabName'])
            tab_widget.setProperty('selector_type', form_tab['selectorType'])
            if filter:
                main_tab.removeTab(index)
                main_tab.insertTab(index, tab_widget, form_tab['tabLabel'])
            else:
                main_tab.addTab(tab_widget, form_tab['tabLabel'])
            if 'typeaheadForced' in form_tab and form_tab[
                    'typeaheadForced'] is not None:
                tab_widget.setProperty('typeahead_forced',
                                       form_tab['typeaheadForced'])

            # Create a new QGridLayout and put it into tab
            gridlayout = QGridLayout()
            gridlayout.setObjectName("lyt" + form_tab['tabName'])
            tab_widget.setLayout(gridlayout)
            field = {}
            i = 0

            if 'typeaheadFilter' in form_tab:
                label = QLabel()
                label.setObjectName('lbl_filter')
                label.setText('Filter:')
                if tools_qt.get_widget(
                        dialog,
                        'txt_filter_' + str(form_tab['tabName'])) is None:
                    widget = QLineEdit()
                    widget.setObjectName('txt_filter_' +
                                         str(form_tab['tabName']))
                    widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
                    widget.textChanged.connect(
                        partial(self.get_selector,
                                dialog,
                                selector_type,
                                filter=True,
                                widget=widget,
                                current_tab=current_tab))
                    widget.setLayoutDirection(Qt.RightToLeft)

                else:
                    widget = tools_qt.get_widget(
                        dialog, 'txt_filter_' + str(form_tab['tabName']))

                field['layoutname'] = gridlayout.objectName()
                field['layoutorder'] = i
                i = i + 1
                gridlayout.addWidget(label, int(field['layoutorder']), 0)
                gridlayout.addWidget(widget, int(field['layoutorder']), 2)
                widget.setFocus()

            if 'manageAll' in form_tab:
                if (form_tab['manageAll']).lower() == 'true':
                    if tools_qt.get_widget(
                            dialog, f"chk_all_{form_tab['tabName']}") is None:
                        widget = QCheckBox()
                        widget.setObjectName('chk_all_' +
                                             str(form_tab['tabName']))
                        widget.stateChanged.connect(
                            partial(self._manage_all, dialog, widget))
                        widget.setLayoutDirection(Qt.LeftToRight)
                    else:
                        widget = tools_qt.get_widget(
                            dialog, f"chk_all_{form_tab['tabName']}")
                    widget.setText('Check all')
                    field['layoutname'] = gridlayout.objectName()
                    field['layoutorder'] = i
                    i = i + 1
                    gridlayout.addWidget(widget, int(field['layoutorder']), 0,
                                         1, -1)

            for order, field in enumerate(form_tab['fields']):
                try:
                    # Create checkbox
                    widget = tools_gw.add_checkbox(field)
                    widget.setText(field['label'])
                    widget.stateChanged.connect(
                        partial(self._set_selection_mode, dialog, widget,
                                selection_mode))
                    widget.setLayoutDirection(Qt.LeftToRight)

                    # Set background color every other item (if enabled)
                    if color_rows and order % 2 == 0:
                        widget.setStyleSheet(f"background-color: #E9E7E3")

                    # Add widget to layout
                    field['layoutname'] = gridlayout.objectName()
                    field['layoutorder'] = order + i + 1
                    gridlayout.addWidget(widget, int(field['layoutorder']), 0,
                                         1, -1)
                except Exception:
                    msg = f"key 'comboIds' or/and comboNames not found WHERE columname='{field['columnname']}' AND " \
                          f"widgetname='{field['widgetname']}'"
                    tools_qgis.show_message(msg, 2)

            vertical_spacer1 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                           QSizePolicy.Expanding)
            gridlayout.addItem(vertical_spacer1)

        # Set last tab used by user as current tab
        tabname = json_result['body']['form']['currentTab']
        tab = main_tab.findChild(QWidget, tabname)

        if tab:
            main_tab.setCurrentWidget(tab)