# -*- coding: utf-8 -*- """ /*************************************************************************** FileSystem A QGIS plugin Plugin allows users to rename layers on disk within QGIS, and copy layer paths (both absolute and relative) to the clipboard. Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/ ------------------- begin : 2022-05-31 git sha : $Format:%H$ copyright : (C) 2022 by TUFLOW email : support@tuflow.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ """ from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication from qgis.PyQt.QtGui import QIcon from qgis.PyQt.QtWidgets import QAction, QMessageBox, QMenu from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsProject, QgsMapLayer import os.path import sys from file_management.utils.file_management_menu_provider import (FileManagementMenuProvider, FileManagementMenuObjectSettings) from file_management.utils.rename import rename from file_management.utils.copy_path import copy_path from .settings import FileManagementSettings from .settings_dialog import FileManagementSettingsDialog # remote debugging sys.path.append(r'C:\Program Files\JetBrains\PyCharm 2020.3.1\debug-eggs') sys.path.append(r'C:\Program Files\JetBrains\PyCharm 2020.3.1\plugins\python\helpers\pydev') class FileManagement: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'FileManagement_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&File Management') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('FileManagement', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=False, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/file_management/mActionFileOpen.svg' self.add_action( icon_path, text=self.tr(u'Settings'), callback=self.run, parent=self.iface.mainWindow()) self.settings = FileManagementSettings() self.rename_layer_action = QAction('Rename Layer') self.rename_layer_action.triggered.connect(lambda: rename(self.iface.layerTreeView(), self.iface, 'layer', self.settings)) self.rename_database_action = QAction('Rename Database') self.rename_database_action.triggered.connect(lambda: rename(self.iface.layerTreeView(), self.iface, 'database', self.settings)) self.copy_file_path_action = QAction('Copy File Path') self.copy_file_path_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(), 'full path', settings=self.settings)) self.copy_database_path_action = QAction('Copy Database Path') self.copy_database_path_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(), 'database path', settings=self.settings)) self.copy_file_name_action = QAction('Copy File Name') self.copy_file_name_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(), 'file name', settings=self.settings)) self.copy_rel_file_path_wor_action = QAction('Copy Relative Path From Workspace') self.copy_rel_file_path_wor_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(), 'relative path workspace', settings=self.settings)) self.copy_rel_file_path_action = QAction('Copy Relative Path From...') self.copy_rel_file_path_action.triggered.connect(lambda: self.copy_path(self.iface.layerTreeView(), 'relative path', settings=self.settings)) self.menu_provider = FileManagementMenuProvider(self.iface, self.settings) self.menu_provider.addAction(self.rename_layer_action, FileManagementMenuObjectSettings(QgsVectorLayer, True, ['database', 'file'])) self.menu_provider.addAction(self.rename_database_action, FileManagementMenuObjectSettings(QgsVectorLayer, True, ['database'])) self.menu_provider.addAction('separator', FileManagementMenuObjectSettings(QgsVectorLayer, True, ['database', 'file'])) self.menu_provider.addAction(self.copy_file_path_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['file'])) self.menu_provider.addAction(self.copy_database_path_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database'])) self.menu_provider.addAction(self.copy_file_name_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database', 'file'])) self.menu_provider.addAction(self.copy_rel_file_path_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database', 'file'])) self.menu_provider.addAction(self.copy_rel_file_path_wor_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database', 'file'])) self.menu_provider.register_menus() self.menu_provider.create_menus() for lyrid, lyr in QgsProject.instance().mapLayers().items(): self.menu_provider.register_layer(lyr) QgsProject.instance().layersAdded.connect(self.menu_provider.register_layers) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" self.menu_provider.unregister_menus() for action in self.actions: self.iface.removePluginMenu( self.tr(u'&File Management'), action) self.iface.removeToolBarIcon(action) def run(self): """Run method that performs all the real work""" dlg = FileManagementSettingsDialog(self.iface.mainWindow(), self.settings) dlg.exec_() def rename_layer(self, layer, target_name): """Function for external calls to plugin.""" from file_management.utils.rename import Renamer from file_management.utils.uri import Uri src_uri = Uri(layer=layer) renamer = Renamer(self.iface.layerTreeView(), self.iface, src_uri, 'layer') if not renamer.is_valid(): return result target_uri = Uri() target_uri.set_database(src_uri.database()) target_uri.set_layer_name(target_name) target_uri.build(src_uri) # use src_uri as template so things like filters are retained if renamer.exists(target_uri): renamer.delete(target_uri) renamer.rename(target_uri) def copy_path(self, view, reference_type, text_=None, settings=None): copy_path(view, reference_type, text_, settings) if reference_type == 'relative path': self.menu_provider.create_recent_path_actions() self.menu_provider.create_menus()