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")
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')
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))
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))
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')
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)
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))
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
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)
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
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))
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)