示例#1
0
    def testRegisterAction(self):
        """ test registering actions """
        QSettings().clear()

        s = QgsShortcutsManager(None)

        action1 = QAction("action1", None)
        action1.setShortcut("x")
        self.assertTrue(s.registerAction(action1, "A"))
        action2 = QAction("action2", None)
        action2.setShortcut("y")
        self.assertTrue(s.registerAction(action2, "B"))

        # actions should have been set to default sequences
        self.assertEqual(action1.shortcut().toString(), "A")
        self.assertEqual(action2.shortcut().toString(), "B")

        # test that adding an action should set its shortcut automatically
        s.setKeySequence("action1", "C")
        s.setKeySequence("action2", "D")

        s = QgsShortcutsManager(None)
        self.assertTrue(s.registerAction(action1, "A"))
        self.assertTrue(s.registerAction(action2, "B"))

        # actions should have been set to previous shortcuts
        self.assertEqual(action1.shortcut().toString(), "C")
        self.assertEqual(action2.shortcut().toString(), "D")

        # test registering an action containing '&' in name
        s = QgsShortcutsManager(None)
        action = QAction("&action1", None)
        self.assertTrue(s.registerAction(action))
        self.assertEqual(action1.shortcut().toString(), "C")
示例#2
0
    def testRegisterAction(self):
        """ test registering actions """
        QSettings().clear()

        s = QgsShortcutsManager(None)

        action1 = QAction('action1', None)
        action1.setShortcut('x')
        self.assertTrue(s.registerAction(action1, 'A'))
        action2 = QAction('action2', None)
        action2.setShortcut('y')
        self.assertTrue(s.registerAction(action2, 'B'))

        # actions should have been set to default sequences
        self.assertEqual(action1.shortcut().toString(), 'A')
        self.assertEqual(action2.shortcut().toString(), 'B')

        # test that adding an action should set its shortcut automatically
        s.setKeySequence('action1', 'C')
        s.setKeySequence('action2', 'D')

        s = QgsShortcutsManager(None)
        self.assertTrue(s.registerAction(action1, 'A'))
        self.assertTrue(s.registerAction(action2, 'B'))

        # actions should have been set to previous shortcuts
        self.assertEqual(action1.shortcut().toString(), 'C')
        self.assertEqual(action2.shortcut().toString(), 'D')

        # test registering an action containing '&' in name
        s = QgsShortcutsManager(None)
        action = QAction('&action1', None)
        self.assertTrue(s.registerAction(action))
        self.assertEqual(action1.shortcut().toString(), 'C')
示例#3
0
    def testUnregister(self):
        """ test unregistering from manager """

        QSettings().clear()

        s = QgsShortcutsManager(None)

        shortcut1 = QShortcut(None)
        shortcut1.setKey('x')
        shortcut1.setObjectName('shortcut1')
        shortcut2 = QShortcut(None)
        shortcut2.setKey('y')
        shortcut2.setObjectName('shortcut2')

        action1 = QAction('action1', None)
        action1.setShortcut('x')
        action2 = QAction('action2', None)
        action2.setShortcut('y')

        # try unregistering objects not registered in manager
        self.assertFalse(s.unregisterShortcut(shortcut1))
        self.assertFalse(s.unregisterAction(action1))

        # try unregistering objects from manager
        s.registerShortcut(shortcut1)
        s.registerShortcut(shortcut2)
        s.registerAction(action1)
        s.registerAction(action2)

        self.assertEqual(set(s.listActions()), set([action1, action2]))
        self.assertEqual(set(s.listShortcuts()), set([shortcut1, shortcut2]))

        self.assertTrue(s.unregisterAction(action1))
        self.assertTrue(s.unregisterShortcut(shortcut1))

        self.assertEqual(set(s.listActions()), set([action2]))
        self.assertEqual(set(s.listShortcuts()), set([shortcut2]))

        self.assertTrue(s.unregisterAction(action2))
        self.assertTrue(s.unregisterShortcut(shortcut2))
示例#4
0
    def testUnregister(self):
        """ test unregistering from manager """

        QgsSettings().clear()

        s = QgsShortcutsManager(None)

        shortcut1 = QShortcut(None)
        shortcut1.setKey('x')
        shortcut1.setObjectName('shortcut1')
        shortcut2 = QShortcut(None)
        shortcut2.setKey('y')
        shortcut2.setObjectName('shortcut2')

        action1 = QAction('action1', None)
        action1.setShortcut('x')
        action2 = QAction('action2', None)
        action2.setShortcut('y')

        # try unregistering objects not registered in manager
        self.assertFalse(s.unregisterShortcut(shortcut1))
        self.assertFalse(s.unregisterAction(action1))

        # try unregistering objects from manager
        s.registerShortcut(shortcut1)
        s.registerShortcut(shortcut2)
        s.registerAction(action1)
        s.registerAction(action2)

        self.assertEqual(set(s.listActions()), set([action1, action2]))
        self.assertEqual(set(s.listShortcuts()), set([shortcut1, shortcut2]))

        self.assertTrue(s.unregisterAction(action1))
        self.assertTrue(s.unregisterShortcut(shortcut1))

        self.assertEqual(set(s.listActions()), set([action2]))
        self.assertEqual(set(s.listShortcuts()), set([shortcut2]))

        self.assertTrue(s.unregisterAction(action2))
        self.assertTrue(s.unregisterShortcut(shortcut2))
示例#5
0
    def testRegisterAction(self):
        """ test registering actions """
        QgsSettings().clear()

        s = QgsShortcutsManager(None)

        action1 = QAction('action1', None)
        action1.setShortcut('x')
        self.assertTrue(s.registerAction(action1, 'A'))
        action2 = QAction('action2', None)
        action2.setShortcut('y')
        self.assertTrue(s.registerAction(action2, 'B'))
        self.assertCountEqual(s.listActions(), [action1, action2])

        # try re-registering an existing action - should fail, but leave action registered
        self.assertFalse(s.registerAction(action2, 'B'))
        self.assertCountEqual(s.listActions(), [action1, action2])

        # actions should have been set to default sequences
        self.assertEqual(action1.shortcut().toString(), 'A')
        self.assertEqual(action2.shortcut().toString(), 'B')

        # test that adding an action should set its shortcut automatically
        s.setKeySequence('action1', 'C')
        s.setKeySequence('action2', 'D')

        s = QgsShortcutsManager(None)
        self.assertTrue(s.registerAction(action1, 'A'))
        self.assertTrue(s.registerAction(action2, 'B'))

        # actions should have been set to previous shortcuts
        self.assertEqual(action1.shortcut().toString(), 'C')
        self.assertEqual(action2.shortcut().toString(), 'D')

        # test registering an action containing '&' in name
        s = QgsShortcutsManager(None)
        action = QAction('&action1', None)
        self.assertTrue(s.registerAction(action))
        self.assertEqual(action1.shortcut().toString(), 'C')
示例#6
0
	def __init__(self, icon_path, text, toolbar, action_group, iface, settings, controller, plugin_dir):
		super().__init__(icon_path, text, toolbar, action_group, iface, settings, controller, plugin_dir)
		
		# First add the menu before adding it to the toolbar
		toolbar.removeAction(self.action)
		
		pg_man = PgMan(controller)
		self.feature_cat = pg_man.manage_feature_cat()
		
		project_type = self.controller.get_project_type()
		
		self.edit = GwEdit(iface, settings, controller, plugin_dir)
		
		# Get list of different node and arc types
		menu = QMenu()
		# List of nodes from node_type_cat_type - nodes which we are using
		list_feature_cat = self.controller.get_values_from_dictionary(self.feature_cat)
		for feature_cat in list_feature_cat:
			if feature_cat.feature_type.upper() == 'NODE':
				obj_action = QAction(str(feature_cat.id), action_group)
				obj_action.setShortcut(QKeySequence(str(feature_cat.shortcut_key)))
				try:
					obj_action.setShortcutVisibleInContextMenu(True)
				except:
					pass
				menu.addAction(obj_action)
				obj_action.triggered.connect(partial(self.edit.edit_add_feature, feature_cat))
		menu.addSeparator()
		
		list_feature_cat = self.controller.get_values_from_dictionary(self.feature_cat)
		for feature_cat in list_feature_cat:
			if feature_cat.feature_type.upper() == 'CONNEC':
				obj_action = QAction(str(feature_cat.id), action_group)
				obj_action.setShortcut(QKeySequence(str(feature_cat.shortcut_key)))
				try:
					obj_action.setShortcutVisibleInContextMenu(True)
				except:
					pass
				menu.addAction(obj_action)
				obj_action.triggered.connect(partial(self.edit.edit_add_feature, feature_cat))
		menu.addSeparator()
		
		list_feature_cat = self.controller.get_values_from_dictionary(self.feature_cat)
		for feature_cat in list_feature_cat:
			if feature_cat.feature_type.upper() == 'GULLY' and project_type == 'ud':
				obj_action = QAction(str(feature_cat.id), action_group)
				obj_action.setShortcut(QKeySequence(str(feature_cat.shortcut_key)))
				try:
					obj_action.setShortcutVisibleInContextMenu(True)
				except:
					pass
				menu.addAction(obj_action)
				obj_action.triggered.connect(partial(self.edit.edit_add_feature, feature_cat))
		menu.addSeparator()
		
		
		self.action.setMenu(menu)
		toolbar.addAction(self.action)
示例#7
0
    def _fill_arc_menu(self):
        """ Fill add arc menu """

        # disconnect and remove previuos signals and actions
        actions = self.menu.actions()
        for action in actions:
            action.disconnect()
            self.menu.removeAction(action)
            del action
        action_group = self.action.property('action_group')

        # Update featurecatvalues
        global_vars.feature_cat = tools_gw.manage_feature_cat()

        # Get list of different arc types
        features_cat = global_vars.feature_cat
        if features_cat is not None:
            list_feature_cat = tools_os.get_values_from_dictionary(
                features_cat)
            for feature_cat in list_feature_cat:
                if feature_cat.feature_type.upper() == 'ARC':
                    obj_action = QAction(str(feature_cat.id), action_group)
                    obj_action.setObjectName(feature_cat.id)
                    obj_action.setProperty('action_group', action_group)
                    if f"{feature_cat.shortcut_key}" not in global_vars.shortcut_keys:
                        obj_action.setShortcut(
                            QKeySequence(str(feature_cat.shortcut_key)))
                    try:
                        obj_action.setShortcutVisibleInContextMenu(True)
                    except Exception:
                        pass
                    self.menu.addAction(obj_action)
                    obj_action.triggered.connect(
                        partial(self.info_feature.add_feature, feature_cat))
                    obj_action.triggered.connect(
                        partial(self._save_last_selection, self.menu,
                                feature_cat))
示例#8
0
class LessonsCreator(object):
    def __init__(self, iface):
        self.iface = iface

        # add tests to tester plugin
        try:
            from qgistester.tests import addTestModule
            from lessonscreator.test import testerplugin
            addTestModule(testerplugin, "LessonsCreator")
        except Exception as e:
            pass

        self.capturing = False

    def unload(self):
        self.iface.removePluginMenu(u"Lessons", self.action)
        del self.action
        del self.newStepAction

        QgsApplication.instance().focusChanged.disconnect(
            self.processFocusChanged)

        try:
            from qgistester.tests import removeTestModule
            from lessonscreator.test import testerplugin
            removeTestModule(testerplugin, "LessonsCreator")
        except Exception as e:
            pass

    def initGui(self):
        lessonIcon = QIcon(os.path.dirname(__file__) + '/edit.png')
        self.action = QAction(lessonIcon, "Capture lesson steps",
                              self.iface.mainWindow())
        self.action.triggered.connect(self.toggleCapture)
        self.iface.addPluginToMenu(u"Lessons", self.action)

        QgsApplication.instance().focusChanged.connect(
            self.processFocusChanged)

        self.newStepAction = QAction("New step", self.iface.mainWindow())

        self.newStepAction.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_W))
        self.newStepAction.setShortcutContext(Qt.ApplicationShortcut)
        self.newStepAction.triggered.connect(self.startNewStep)
        self.iface.mainWindow().addAction(self.newStepAction)

    connections = []
    iScreenshot = 0
    iStep = 0
    outputHtmlFile = None
    outputPyFile = None

    def startNewStep(self):
        if self.outputHtmlFile:
            self.outputHtmlFile.close()
        self.iStep += 1
        path = os.path.join(self.folder, "step_%i.html" % self.iStep)
        self.outputHtmlFile = open(path, "w")
        self.outputPyFile.write(
            '''lesson.addStep("Step_%i", "step_%i.html", steptype=Step.MANUALSTEP)\n'''
            % (self.iStep, self.iStep))

    def toggleCapture(self):
        if self.capturing:
            self.action.setText("Capture lesson steps")
            self.capturing = False
            self.outputHtmlFile.close()
            self.outputPyFile.close()
            self.outputHtmlFile = None
            self.outputPyFile = None
        else:
            self.folder = QFileDialog.getExistingDirectory(
                self.iface.mainWindow(), "Select folder to store lesson")
            if not self.folder:
                return
            path = os.path.join(self.folder, "__init__.py")
            self.outputPyFile = open(path, "w")

            template = (
                "from lessons.lesson import Lesson, Step\n"
                "from lessons.utils import *\n"
                "lesson = Lesson('Lesson', 'Basic lessons', 'lesson.html')\n\n"
            )

            self.outputPyFile.write(template)

            self.iScreenshot = 0
            self.iStep = 0
            self.updateConnections()
            self.action.setText("Stop capturing lesson steps")
            self.capturing = True
            self.startNewStep()

    def processWidgetClick(self, obj):
        if self.capturing:
            try:
                text = "Click on '%s'" % obj.text()
            except Exception as e:
                # fix_print_with_import
                print(e)
                text = "Click on " + str(obj)
            self.outputHtmlFile.write("<p>%s</p>\n" % text)
            self.updateConnections()

    lastComboText = None

    def processComboNewSelection(self, combo):
        if self.capturing:
            text = "Select '%s' in '%s'" % (combo.currentText(),
                                            combo.objectName())
            if text == self.lastComboText:
                return
            self.lastComboText = text
            self.outputHtmlFile.write("<p>%s</p>\n" % text)
            self.createScreenshot(combo.parent(), combo.frameGeometry())
            self.updateConnections()

    def processCheckBoxChange(self, check):
        if self.capturing:
            if check.isChecked():
                text = "Check the '%s' checkbox" % (check.text())
            else:
                text = "Uncheck the '%s' checkbox" % (check.text())
            self.outputHtmlFile.write("<p>%s</p>\n" % text)
            self.createScreenshot(check.parent(), check.frameGeometry())

    def processMenuClick(self, action):
        if self.capturing and action.text() != "Stop capturing lesson steps":
            text = "Click on menu '%s'" % action.text()
            self.outputHtmlFile.write("<p>%s</p>\n" % text)

    def getParentWindow(self, obj):
        window = None
        try:
            parent = obj.parent()
            while parent is not None:
                if isinstance(parent, QDialog):
                    window = parent
                    break
                parent = parent.parent()
        except:
            window = None

        return window or QgsApplication.instance().desktop()

    def processFocusChanged(self, old, new):
        if self.capturing:
            self.updateConnections()
            if isinstance(old, QLineEdit) and old.text().strip():
                text = "Enter '%s' in textbox '%s'" % (old.text(),
                                                       old.objectName())
                self.outputHtmlFile.write("<p>%s</p>\n" % text)
                self.createScreenshot(old.parent(), old.frameGeometry())
            else:
                oldParent = self.getParentWindow(old)
                newParent = self.getParentWindow(new)
                # fix_print_with_import
                print(oldParent, newParent)
                if oldParent != newParent:
                    self.createScreenshot(newParent)
                elif isinstance(
                        new,
                    (QLineEdit, QTextEdit, QComboBox, QSpinBox, QRadioButton)):
                    text = "Select the '%s' widget" % (old.objectName()
                                                       or str(old))
                    self.outputHtmlFile.write("<p>%s</p>\n" % text)
                    self.createScreenshot(new.parent(), new.frameGeometry())

    timer = None

    def _createScreenshot(self, obj, rect):
        pixmap = QPixmap.grabWindow(obj.winId()).copy()
        if rect is not None:
            painter = QPainter()
            painter.begin(pixmap)
            painter.setPen(QPen(QBrush(Qt.red), 3, Qt.DashLine))
            painter.drawRect(rect)
            painter.end()

        pixmap.save(os.path.join(self.folder, '%i.jpg' % self.iScreenshot),
                    'jpg')

        self.outputHtmlFile.write("<img src='%i.jpg'/>\n" % self.iScreenshot)
        self.iScreenshot += 1
        self.timer = None

    def createScreenshot(self, obj, rect=None):
        if self.capturing and self.timer is None:
            self.timer = QTimer()
            self.timer.setInterval(1000)
            self.timer.setSingleShot(True)
            self.timer.timeout.connect(
                lambda: self._createScreenshot(obj, rect))
            self.timer.start()

    def updateConnections(self):
        widgets = QgsApplication.instance().allWidgets()
        for w in widgets:
            if w not in self.connections:
                if isinstance(w, (QPushButton, QToolButton)):
                    f = partial(self.processWidgetClick, w)
                    w.clicked.connect(f)
                    self.connections.append(w)
                elif isinstance(w, QComboBox):
                    f = partial(self.processComboNewSelection, w)
                    w.currentIndexChanged.connect(f)
                    self.connections.append(w)
                elif isinstance(w, QCheckBox):
                    f = partial(self.processCheckBoxChange, w)
                    w.stateChanged.connect(f)
                    self.connections.append(w)

        menuActions = []
        actions = self.iface.mainWindow().menuBar().actions()
        for action in actions:
            menuActions.extend(self.getActions(action, None))

        for action, menu in menuActions:
            if menu not in self.connections:
                menu.triggered.connect(self.processMenuClick)
                self.connections.append(menu)

    def getActions(self, action, menu):
        menuActions = []
        submenu = action.menu()
        if submenu is None:
            menuActions.append((action, menu))
            return menuActions
        else:
            actions = submenu.actions()
            for subaction in actions:
                if subaction.menu() is not None:
                    menuActions.extend(
                        self.getActions(subaction, subaction.menu()))
                elif not subaction.isSeparator():
                    menuActions.append((subaction, submenu))

        return menuActions
示例#9
0
class PhotoViewer(QScrollArea):
    """
    Widget for viewing images by incorporating basic navigation options.
    """
    def __init__(self, parent=None, photo_path=""):
        QScrollArea.__init__(self, parent)
        self.setBackgroundRole(QPalette.Dark)

        self._printer = QPrinter()

        self._lbl_photo = QLabel()
        self._lbl_photo.setBackgroundRole(QPalette.Base)
        self._lbl_photo.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self._lbl_photo.setScaledContents(True)

        self.setWidget(self._lbl_photo)

        self._photo_path = photo_path
        self._ph_image = None
        self._scale_factor = 1.0
        self._aspect_ratio = -1

        self._create_actions()

        if self._photo_path:
            self.load_document(self._photo_path)

    def _create_actions(self):
        """
        Create actions for basic image navigation.
        """
        self._zoom_in_act = QAction(
            QApplication.translate("PhotoViewer", "Zoom &In (25%)"), self)
        self._zoom_in_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl++"))
        self._zoom_in_act.setEnabled(False)
        self._zoom_in_act.triggered.connect(self.zoom_in)

        self._zoom_out_act = QAction(
            QApplication.translate("PhotoViewer", "Zoom &Out (25%)"), self)
        self._zoom_out_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+-"))
        self._zoom_out_act.setEnabled(False)
        self._zoom_out_act.triggered.connect(self.zoom_out)

        self._normal_size_act = QAction(
            QApplication.translate("PhotoViewer", "&Normal Size"), self)
        self._normal_size_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+S"))
        self._normal_size_act.setEnabled(False)
        self._normal_size_act.triggered.connect(self.normal_size)

        self._fit_to_window_act = QAction(
            QApplication.translate("PhotoViewer", "&Fit to Window"), self)
        self._fit_to_window_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+F"))
        self._fit_to_window_act.setEnabled(False)
        self._fit_to_window_act.setCheckable(True)
        self._fit_to_window_act.triggered.connect(self.fit_to_window)

        self._print_act = QAction(
            QApplication.translate("PhotoViewer", "&Print"), self)
        self._print_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+P"))
        self._print_act.setEnabled(False)
        self._print_act.triggered.connect(self.print_photo)

    def zoom_in(self):
        self.scale_photo(1.25)

    def zoom_out(self):
        self.scale_photo(0.8)

    def normal_size(self):
        self._lbl_photo.adjustSize()
        self._scale_factor = 1.0

    def fit_to_window(self):
        fit_to_win = self._fit_to_window_act.isChecked()
        self.setWidgetResizable(fit_to_win)

        if not fit_to_win:
            self.normal_size()

        self.update_actions()

    def print_photo(self):
        print_dialog = QPrintDialog(self._printer, self)

        if print_dialog.exec_() == QDialog.Accepted:
            painter = QPainter(self._printer)
            rect = painter.viewport()
            size = self._lbl_photo.pixmap().size()
            size.scale(rect.size(), Qt.KeepAspectRatio)
            painter.setViewport(rect.x(), rect.y(), size.width(),
                                size.height())
            painter.setWindow(self._lbl_photo.pixmap().rect())
            painter.drawPixmap(0, 0, self._lbl_photo.pixmap())

    def wheelEvent(self, event):
        """
        Zoom the image based on the mouse wheel rotation action.
        :param event: Event containing the wheel rotation info.
        :type event: QWheelEvent
        """
        degrees = event.delta() / 8
        num_steps = degrees / 15

        if num_steps < 0:
            abs_num_steps = abs(num_steps)
            zoom_factor = 1 + (abs_num_steps * 0.25)

        else:
            zoom_factor = 1 - (num_steps * 0.2)

        self.scale_photo(zoom_factor)

    def heightForWidth(self, width):
        if self._aspect_ratio != -1:
            return width / self._aspect_ratio

        else:
            return -1

    def resizeEvent(self, event):
        """
        Event for resizing the widget based on the pixmap's aspect ratio.
        :param event: Contains event parameters for the resize event.
        :type event: QResizeEvent
        """
        super(PhotoViewer, self).resizeEvent(event)

    def update_actions(self):
        self._zoom_out_act.setEnabled(not self._fit_to_window_act.isChecked())
        self._zoom_in_act.setEnabled(not self._fit_to_window_act.isChecked())
        self._normal_size_act.setEnabled(
            not self._fit_to_window_act.isChecked())

    def scale_photo(self, factor):
        """
        :param factor: Value by which the image will be increased/decreased in the view.
        :type factor: float
        """
        if not self._lbl_photo.pixmap().isNull():
            self._scale_factor *= factor
            self._lbl_photo.resize(self._scale_factor *
                                   self._lbl_photo.pixmap().size())

            self._adjust_scroll_bar(self.horizontalScrollBar(), factor)
            self._adjust_scroll_bar(self.verticalScrollBar(), factor)

            self._zoom_in_act.setEnabled(self._scale_factor < 3.0)
            self._zoom_out_act.setEnabled(self._scale_factor > 0.333)

    def _adjust_scroll_bar(self, scroll_bar, factor):
        scroll_bar.setValue(
            int(factor * scroll_bar.value() +
                ((factor - 1) * scroll_bar.pageStep() / 2)))

    def load_document(self, photo_path):
        if photo_path:
            self._ph_image = QImage(photo_path)

            if self._ph_image.isNull():
                return False

            self._photo_path = photo_path

            ph_pixmap = QPixmap.fromImage(self._ph_image)

            self._lbl_photo.setPixmap(ph_pixmap)
            self._scale_factor = 1.0

            self._aspect_ratio = ph_pixmap.width() / ph_pixmap.height()

            self._fit_to_window_act.setEnabled(True)
            self._print_act.setEnabled(True)
            self._fit_to_window_act.trigger()

            self.update_actions()
            return ph_pixmap

        return True

    def photo_location(self):
        """
        :returns: Absolute path of the photo in the central document repository.
        """
        return self._photo_path

    def set_actions(self, menu):
        """
        Add custom actions to the sub-window menu
        """
        menu.addSeparator()
        menu.addAction(self._zoom_in_act)
        menu.addAction(self._zoom_out_act)
        menu.addAction(self._normal_size_act)
        menu.addAction(self._fit_to_window_act)
        menu.addSeparator()
        menu.addAction(self._print_act)
示例#10
0
    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

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

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

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

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

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

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

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

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

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

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

        # Create the dialog (after translation) and keep reference
        '''self.dlg = TopoGrafiaDialog()'''

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        self.actionCounter += 1
        action.setShortcut(QKeySequence(SHORTCUT + str(self.actionCounter)))

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

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

        self.actions.append(action)

        return action
示例#11
0
class Plugin(QGISPluginBase):
    """docstring for Plugin"""
    def __init__(self, iface):
        super(Plugin, self).__init__()
        self.iface = iface

        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.i18nPath,
                                   'plugin_{}.qm'.format(locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

    def tr(self, message):
        return QApplication.translate('Plugin', message)

    def initGui(self):
        self.paste_geometry_action = QAction(self.tr('Paste Geometry'),
                                             self.iface.mainWindow())
        self.paste_geometry_action.setIcon(
            QIcon(os.path.join(self.dir, 'icon.svg')))
        self.paste_geometry_action.setShortcut(QKeySequence('Ctrl+Shift+G'))
        self.paste_geometry_action.setToolTip(self.tr('Paste Geometry'))
        self.paste_geometry_action.setStatusTip(self.description)
        self.paste_geometry_action.setEnabled(False)
        self.paste_geometry_action.triggered.connect(self.pasteGeometry)

        self.iface.editMenu().insertAction(
            self.iface.actionDeleteSelected(),
            self.paste_geometry_action,
        )
        self.iface.digitizeToolBar().insertAction(
            self.iface.actionDeleteSelected(),
            self.paste_geometry_action,
        )

        self.iface.currentLayerChanged.connect(self._changeCurrentLayerHandle)
        self._changeCurrentLayerHandle(self.iface.activeLayer())

    def unload(self):
        self.iface.editMenu().removeAction(self.paste_geometry_action)
        self.iface.digitizeToolBar().removeAction(self.paste_geometry_action)
        self.iface.currentLayerChanged.disconnect(
            self._changeCurrentLayerHandle)

    def pushMessage(self, title, message, level=QGis23MessageBarLevel.Info):
        self.iface.messageBar().pushMessage(title, message, level)

    def pushLog(self, msg, level=QGis23MessageLogLevel.Info):
        QgsMessageLog.logMessage(msg, self.name, level)

    def pasteGeometry(self):
        geoms = self._tryGetFeaturesGeomsFromClipBoard()
        if len(geoms) > 1:
            self.pushMessage(
                self.tr('Paste geometry'),
                self.tr('Fail to paste. Multiple features in the clipboard.'),
                QGis23MessageBarLevel.Critical)
            return
        if len(geoms) == 0:
            self.pushMessage(
                self.tr('Paste geometry'),
                self.tr('Nothing to paste. No features in the clipboard.'),
                QGis23MessageBarLevel.Critical)
            return

        geom = geoms[0]

        layer = self.iface.activeLayer()
        selected_features = layer.selectedFeatures()

        if len(selected_features) > 1:
            self.pushMessage(
                self.tr('Paste geometry'),
                # 'Multiple features selected. Need only one.',
                self.tr(
                    'Multiple features are selected. There should be only one.'
                ),
                QGis23MessageBarLevel.Critical)
            return

        if len(selected_features) == 0:
            self.pushMessage(
                self.tr('Paste geometry'),
                self.tr('Nowhere to paste. No target feature selected.'),
                QGis23MessageBarLevel.Critical)
            return

        feature = selected_features[0]

        if feature.geometry().type() != geom.type():
            self.pushMessage(
                self.tr('Paste geometry'),
                self.tr('Incompatible geometries. Trying to paste %s to %s') %
                (getGeomtryName(
                    geom.type()), getGeomtryName(feature.geometry().type())),
                QGis23MessageBarLevel.Critical)
            return

        result = layer.changeGeometry(feature.id(), geom)

        if not result:
            self.pushMessage(
                self.tr('Paste geometry'),
                self.tr('Something is wrong. Can\'t change geometry.'),
                QGis23MessageBarLevel.Critical)
            return

        # This is hack. It is not mandatory instruction.
        # But without new features not repaint.
        # May be I made something wrong above
        self.iface.mapCanvas().refresh()

    def _tryGetFeaturesGeomsFromClipBoard(self):
        cb = QApplication.clipboard()
        clipboard_text = cb.text()
        if sys.version_info[0] == 2:
            clipboard_text = clipboard_text.encode('utf-8')

        reader = csv.DictReader(StringIO(clipboard_text), delimiter='\t')

        geoms = []
        for row in reader:
            wkt_geom = row.get('wkt_geom')
            geom = QgsGeometry.fromWkt(wkt_geom)

            if not geom:
                self.pushLog('Can\'t create geometry from wkt: %s' % wkt_geom)
                continue

            geoms.append(geom)
        return geoms

    def _changeCurrentLayerHandle(self, layer):
        if layer and isinstance(layer, QgsVectorLayer):
            layer.selectionChanged.connect(self._checkPasteAvalability)
            layer.editingStarted.connect(self._checkPasteAvalability)
            layer.editingStopped.connect(self._checkPasteAvalability)
            self._checkPasteAvalability()

    def _checkPasteAvalability(self):
        layer = self.iface.activeLayer()
        is_available = False
        if layer and isinstance(layer, QgsVectorLayer) and layer.isEditable():

            if len(layer.selectedFeatures()) == 1:
                is_available = True
            else:
                msg = self.tr("Select a target feature!")
                is_available = False
        else:
            msg = self.tr("Start editing a vector layer!")
            is_available = False

        if is_available:
            if len(self._tryGetFeaturesGeomsFromClipBoard()) == 0:
                msg = self.tr(
                    "Copy feature with the geometry you need to paste first!")
                is_available = False

        self.paste_geometry_action.setEnabled(is_available)
        if is_available:
            self.paste_geometry_action.setToolTip(self.tr('Paste Geometry'))
        else:
            self.paste_geometry_action.setToolTip(
                "%s. %s" % (self.tr('Paste Geometry'), msg))
示例#12
0
    def initGui(self):

        self.initProcessing()

        plugin_dir = str(Path(__file__).resolve().parent)
        main_icon = QIcon(os.path.join(plugin_dir, "icon.png"))

        # Open the online help
        if Qgis.QGIS_VERSION_INT >= 31000:
            self.help_action_about_menu = QAction(main_icon, 'Cadastre', self.iface.mainWindow())
            self.iface.pluginHelpMenu().addAction(self.help_action_about_menu)
            self.help_action_about_menu.triggered.connect(self.open_help)

        actions = {
            "import_action": (
                "database.png",
                "Importer des données",
                "",
                self.open_import_dialog,
                True
            ),
            "search_action": (
                "search.png",
                "Outils de recherche",
                "",
                self.toggle_search_dialog,
                True
            ),
            "load_action": (
                "output.png",
                "Charger des données",
                "",
                self.open_load_dialog,
                True
            ),
            "export_action": (
                "mActionSaveAsPDF.png",
                "Exporter la vue",
                "",
                self.export_view,
                True
            ),
            "option_action": (
                "config.png",
                "Configurer le plugin",
                "",
                self.open_option_dialog,
                True
            ),
            "about_action": (
                "about.png",
                "À propos",
                "",
                self.open_about_dialog,
                True
            ),
            "help_action": (
                "about.png",
                "Aide",
                "",
                self.open_help,
                True
            ),
            "version_action": (
                "about.png",
                "Notes de version",
                "",
                self.open_message_dialog,
                True
            )
        }

        for key in actions:
            icon_path = os.path.join(plugin_dir, 'icons', actions[key][0])
            icon = QIcon(icon_path)
            action = QAction(QIcon(icon), actions[key][1], self.iface.mainWindow())
            if actions[key][2] != "":
                action.setShortcut(QKeySequence(actions[key][2]))
            setattr(self, key, action)
            action.setEnabled(actions[key][4])
            action.setObjectName(key)
            action.triggered.connect(actions[key][3])

        if not self.cadastre_search_dialog:
            dialog = CadastreSearchDialog(self.iface)
            self.cadastre_search_dialog = dialog

        self.menu = QMenu("&Cadastre")
        self.menu.setObjectName("Cadastre")
        self.menu.setIcon(main_icon)

        # Add Cadastre to Extension menu
        self.menu.addAction(self.import_action)
        self.menu.addAction(self.load_action)
        self.menu.addSeparator()
        self.menu.addAction(self.search_action)
        self.menu.addAction(self.export_action)
        self.menu.addSeparator()
        self.menu.addAction(self.option_action)
        self.menu.addAction(self.about_action)
        self.menu.addAction(self.version_action)
        self.menu.addAction(self.help_action)

        menuBar = self.iface.mainWindow().menuBar()
        menu = menuBar
        for child in menuBar.children():
            if child.objectName() == "mPluginMenu":
                menu = child
                break
        menu.addMenu(self.menu)

        # Add cadastre toolbar
        self.toolbar = self.iface.addToolBar('&Cadastre')
        self.toolbar.setObjectName("cadastreToolbar")

        # Create action for "Parcelle information"
        self.identifyParcelleAction = QAction(
            QIcon(os.path.join(
                plugin_dir,
                "icons",
                "toolbar",
                "get-parcelle-info.png"
            )),
            "Infos parcelle",
            self.iface.mainWindow()
        )
        self.identifyParcelleAction.setCheckable(True)
        self.identifyParcelleAction.triggered.connect(self.setIndentifyParcelleTool)

        self.toolbar.addAction(self.import_action)
        self.toolbar.addAction(self.load_action)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.search_action)
        self.toolbar.addAction(self.identifyParcelleAction)
        self.toolbar.addAction(self.export_action)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.option_action)
        self.toolbar.addAction(self.about_action)

        self.setActionsExclusive()

        # Disable some dialogs on CI : about and changelog
        on_ci = os.getenv("QGIS_TESTING") == 'True'

        # Display About window on first use
        s = QSettings()
        firstUse = s.value("cadastre/isFirstUse", 1, type=int)
        if firstUse == 1 and not on_ci:
            s.setValue("cadastre/isFirstUse", 0)
            self.open_about_dialog()

        # Display some messages depending on version number
        mConfig = configparser.ConfigParser()
        metadataFile = plugin_dir + "/metadata.txt"
        mConfig.read(metadataFile, encoding='utf-8')
        self.mConfig = mConfig
        if not on_ci:
            myVersion = mConfig.get('general', 'version').replace('.', '_')
            myVersionMsg = s.value("cadastre/version_%s" % myVersion, 1, type=int)
            if myVersionMsg == 1:
                s.setValue("cadastre/version_%s" % myVersion, 0)
                self.open_message_dialog()

        # Project load or create : refresh search and identify tool
        self.iface.projectRead.connect(self.onProjectRead)
        self.iface.newProjectCreated.connect(self.onNewProjectCreated)

        # Delete layers from table when deleted from registry
        lr = QgsProject.instance()
        lr.layersRemoved.connect(self.checkIdentifyParcelleTool)

        self.updateSearchButton()

        self.cadastre_search_dialog.visibilityChanged.connect(self.updateSearchButton)