file_management.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. # -*- coding: utf-8 -*-
  2. """
  3. /***************************************************************************
  4. FileSystem
  5. A QGIS plugin
  6. Plugin allows users to rename layers on disk within QGIS, and copy layer paths (both absolute and relative) to the clipboard.
  7. Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
  8. -------------------
  9. begin : 2022-05-31
  10. git sha : $Format:%H$
  11. copyright : (C) 2022 by TUFLOW
  12. email : support@tuflow.com
  13. ***************************************************************************/
  14. /***************************************************************************
  15. * *
  16. * This program is free software; you can redistribute it and/or modify *
  17. * it under the terms of the GNU General Public License as published by *
  18. * the Free Software Foundation; either version 2 of the License, or *
  19. * (at your option) any later version. *
  20. * *
  21. ***************************************************************************/
  22. """
  23. from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
  24. from qgis.PyQt.QtGui import QIcon
  25. from qgis.PyQt.QtWidgets import QAction, QMessageBox, QMenu
  26. from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsProject, QgsMapLayer
  27. import os.path
  28. import sys
  29. from file_management.utils.file_management_menu_provider import (FileManagementMenuProvider,
  30. FileManagementMenuObjectSettings)
  31. from file_management.utils.rename import rename
  32. from file_management.utils.copy_path import copy_path
  33. from .settings import FileManagementSettings
  34. from .settings_dialog import FileManagementSettingsDialog
  35. # remote debugging
  36. sys.path.append(r'C:\Program Files\JetBrains\PyCharm 2020.3.1\debug-eggs')
  37. sys.path.append(r'C:\Program Files\JetBrains\PyCharm 2020.3.1\plugins\python\helpers\pydev')
  38. class FileManagement:
  39. """QGIS Plugin Implementation."""
  40. def __init__(self, iface):
  41. """Constructor.
  42. :param iface: An interface instance that will be passed to this class
  43. which provides the hook by which you can manipulate the QGIS
  44. application at run time.
  45. :type iface: QgsInterface
  46. """
  47. # Save reference to the QGIS interface
  48. self.iface = iface
  49. # initialize plugin directory
  50. self.plugin_dir = os.path.dirname(__file__)
  51. # initialize locale
  52. locale = QSettings().value('locale/userLocale')[0:2]
  53. locale_path = os.path.join(
  54. self.plugin_dir,
  55. 'i18n',
  56. 'FileManagement_{}.qm'.format(locale))
  57. if os.path.exists(locale_path):
  58. self.translator = QTranslator()
  59. self.translator.load(locale_path)
  60. QCoreApplication.installTranslator(self.translator)
  61. # Declare instance attributes
  62. self.actions = []
  63. self.menu = self.tr(u'&File Management')
  64. # Check if plugin was started the first time in current QGIS session
  65. # Must be set in initGui() to survive plugin reloads
  66. self.first_start = None
  67. # noinspection PyMethodMayBeStatic
  68. def tr(self, message):
  69. """Get the translation for a string using Qt translation API.
  70. We implement this ourselves since we do not inherit QObject.
  71. :param message: String for translation.
  72. :type message: str, QString
  73. :returns: Translated version of message.
  74. :rtype: QString
  75. """
  76. # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
  77. return QCoreApplication.translate('FileManagement', message)
  78. def add_action(
  79. self,
  80. icon_path,
  81. text,
  82. callback,
  83. enabled_flag=True,
  84. add_to_menu=True,
  85. add_to_toolbar=False,
  86. status_tip=None,
  87. whats_this=None,
  88. parent=None):
  89. """Add a toolbar icon to the toolbar.
  90. :param icon_path: Path to the icon for this action. Can be a resource
  91. path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
  92. :type icon_path: str
  93. :param text: Text that should be shown in menu items for this action.
  94. :type text: str
  95. :param callback: Function to be called when the action is triggered.
  96. :type callback: function
  97. :param enabled_flag: A flag indicating if the action should be enabled
  98. by default. Defaults to True.
  99. :type enabled_flag: bool
  100. :param add_to_menu: Flag indicating whether the action should also
  101. be added to the menu. Defaults to True.
  102. :type add_to_menu: bool
  103. :param add_to_toolbar: Flag indicating whether the action should also
  104. be added to the toolbar. Defaults to True.
  105. :type add_to_toolbar: bool
  106. :param status_tip: Optional text to show in a popup when mouse pointer
  107. hovers over the action.
  108. :type status_tip: str
  109. :param parent: Parent widget for the new action. Defaults None.
  110. :type parent: QWidget
  111. :param whats_this: Optional text to show in the status bar when the
  112. mouse pointer hovers over the action.
  113. :returns: The action that was created. Note that the action is also
  114. added to self.actions list.
  115. :rtype: QAction
  116. """
  117. icon = QIcon(icon_path)
  118. action = QAction(icon, text, parent)
  119. action.triggered.connect(callback)
  120. action.setEnabled(enabled_flag)
  121. if status_tip is not None:
  122. action.setStatusTip(status_tip)
  123. if whats_this is not None:
  124. action.setWhatsThis(whats_this)
  125. if add_to_toolbar:
  126. # Adds plugin icon to Plugins toolbar
  127. self.iface.addToolBarIcon(action)
  128. if add_to_menu:
  129. self.iface.addPluginToMenu(
  130. self.menu,
  131. action)
  132. self.actions.append(action)
  133. return action
  134. def initGui(self):
  135. """Create the menu entries and toolbar icons inside the QGIS GUI."""
  136. icon_path = ':/plugins/file_management/mActionFileOpen.svg'
  137. self.add_action(
  138. icon_path,
  139. text=self.tr(u'Settings'),
  140. callback=self.run,
  141. parent=self.iface.mainWindow())
  142. self.settings = FileManagementSettings()
  143. self.rename_layer_action = QAction('Rename Layer')
  144. self.rename_layer_action.triggered.connect(lambda: rename(self.iface.layerTreeView(), self.iface, 'layer', self.settings))
  145. self.rename_database_action = QAction('Rename Database')
  146. self.rename_database_action.triggered.connect(lambda: rename(self.iface.layerTreeView(), self.iface, 'database', self.settings))
  147. self.copy_file_path_action = QAction('Copy File Path')
  148. self.copy_file_path_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(), 'full path', settings=self.settings))
  149. self.copy_database_path_action = QAction('Copy Database Path')
  150. self.copy_database_path_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(), 'database path', settings=self.settings))
  151. self.copy_file_name_action = QAction('Copy File Name')
  152. self.copy_file_name_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(), 'file name', settings=self.settings))
  153. self.copy_rel_file_path_wor_action = QAction('Copy Relative Path From Workspace')
  154. self.copy_rel_file_path_wor_action.triggered.connect(lambda: copy_path(self.iface.layerTreeView(),
  155. 'relative path workspace', settings=self.settings))
  156. self.copy_rel_file_path_action = QAction('Copy Relative Path From...')
  157. self.copy_rel_file_path_action.triggered.connect(lambda: self.copy_path(self.iface.layerTreeView(),
  158. 'relative path', settings=self.settings))
  159. self.menu_provider = FileManagementMenuProvider(self.iface, self.settings)
  160. self.menu_provider.addAction(self.rename_layer_action, FileManagementMenuObjectSettings(QgsVectorLayer, True, ['database', 'file']))
  161. self.menu_provider.addAction(self.rename_database_action, FileManagementMenuObjectSettings(QgsVectorLayer, True, ['database']))
  162. self.menu_provider.addAction('separator', FileManagementMenuObjectSettings(QgsVectorLayer, True, ['database', 'file']))
  163. self.menu_provider.addAction(self.copy_file_path_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['file']))
  164. self.menu_provider.addAction(self.copy_database_path_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database']))
  165. self.menu_provider.addAction(self.copy_file_name_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database', 'file']))
  166. self.menu_provider.addAction(self.copy_rel_file_path_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database', 'file']))
  167. self.menu_provider.addAction(self.copy_rel_file_path_wor_action, FileManagementMenuObjectSettings([QgsVectorLayer, QgsRasterLayer], False, ['database', 'file']))
  168. self.menu_provider.register_menus()
  169. self.menu_provider.create_menus()
  170. for lyrid, lyr in QgsProject.instance().mapLayers().items():
  171. self.menu_provider.register_layer(lyr)
  172. QgsProject.instance().layersAdded.connect(self.menu_provider.register_layers)
  173. def unload(self):
  174. """Removes the plugin menu item and icon from QGIS GUI."""
  175. self.menu_provider.unregister_menus()
  176. for action in self.actions:
  177. self.iface.removePluginMenu(
  178. self.tr(u'&File Management'),
  179. action)
  180. self.iface.removeToolBarIcon(action)
  181. def run(self):
  182. """Run method that performs all the real work"""
  183. dlg = FileManagementSettingsDialog(self.iface.mainWindow(), self.settings)
  184. dlg.exec_()
  185. def rename_layer(self, layer, target_name):
  186. """Function for external calls to plugin."""
  187. from file_management.utils.rename import Renamer
  188. from file_management.utils.uri import Uri
  189. src_uri = Uri(layer=layer)
  190. renamer = Renamer(self.iface.layerTreeView(), self.iface, src_uri, 'layer')
  191. if not renamer.is_valid():
  192. return result
  193. target_uri = Uri()
  194. target_uri.set_database(src_uri.database())
  195. target_uri.set_layer_name(target_name)
  196. target_uri.build(src_uri) # use src_uri as template so things like filters are retained
  197. if renamer.exists(target_uri):
  198. renamer.delete(target_uri)
  199. renamer.rename(target_uri)
  200. def copy_path(self, view, reference_type, text_=None, settings=None):
  201. copy_path(view, reference_type, text_, settings)
  202. if reference_type == 'relative path':
  203. self.menu_provider.create_recent_path_actions()
  204. self.menu_provider.create_menus()