from PyQt5.QtWidgets import QMenu, QAction from PyQt5.QtCore import QEvent, QObject, QSettings from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsMapLayer from .copy_path import copy_path from .uri import Uri from .file_manager import FileManager class FileManagementMenuObjectSettings: def __init__(self, layer_type, supported, context): if isinstance(layer_type, str): self.layer_type = [layer_type] else: self.layer_type = layer_type self.must_be_supported_type = supported self.context = context class FileManagementMenuProvider(QObject): def __init__(self, iface, settings): QObject.__init__(self) self._iface = iface self._view = iface.layerTreeView() self._actions = {} self._file_management_menu_base = QMenu('&File Management') # vector layer self._file_management_menu_db = QMenu('&File Management') # vector layer and database type self._file_management_menu_lyr = QMenu('&File Management') # vector layer and not database type self._settings = settings self._recent_path_actions = [] self.create_recent_path_actions() self._clear_recent_paths_action = QAction('Clear History') self._clear_recent_paths_action.triggered.connect(self.clear_history) def clear_history(self): QSettings().remove('file_management/recent_rel_paths') self.create_recent_path_actions() self.create_menus() def addAction(self, action, settings): self._actions[action] = settings def create_recent_path_actions(self): self._recent_path_actions.clear() recent_paths = [str(x) for x in QSettings().value('file_management/recent_rel_paths', []) if x] for recent_path in recent_paths: func = eval(f'lambda: copy_path(self._view, \'relative path\', \'{recent_path}\', settings)', {'self': self, 'copy_path': copy_path, 'settings': self._settings}) action_ = QAction(f'Copy Relative Path From: {recent_path}') action_.triggered.connect(func) self._recent_path_actions.append(action_) def register_layers(self, layers): for layer in layers: self.register_layer(layer) def register_layer(self, layer): uri = Uri(layer) fm = FileManager(uri) if fm.is_valid() and uri.is_database(): self._iface.addCustomActionForLayer(self._file_management_menu_db.menuAction(), layer) elif fm.is_valid(): self._iface.addCustomActionForLayer(self._file_management_menu_lyr.menuAction(), layer) else: self._iface.addCustomActionForLayer(self._file_management_menu_base.menuAction(), layer) def register_menus(self): self._iface.addCustomActionForLayerType(self._file_management_menu_base.menuAction(), '', QgsMapLayer.VectorLayer, False) self._iface.addCustomActionForLayerType(self._file_management_menu_db.menuAction(), '', QgsMapLayer.VectorLayer, False) self._iface.addCustomActionForLayerType(self._file_management_menu_lyr.menuAction(), '', QgsMapLayer.VectorLayer, False) def unregister_menus(self): self._iface.removeCustomActionForLayerType(self._file_management_menu_base.menuAction()) self._iface.removeCustomActionForLayerType(self._file_management_menu_db.menuAction()) self._iface.removeCustomActionForLayerType(self._file_management_menu_lyr.menuAction()) def create_menus(self): self._file_management_menu_base.clear() self._file_management_menu_db.clear() self._file_management_menu_lyr.clear() for action, settings in self._actions.items(): if isinstance(action, QAction): if 'database' in settings.context: self._file_management_menu_db.addAction(action) if 'file' in settings.context: self._file_management_menu_lyr.addAction(action) if not settings.must_be_supported_type: self._file_management_menu_base.addAction(action) elif isinstance(action, str) and action == 'separator': if 'database' in settings.context: self._file_management_menu_db.addSeparator() if 'file' in settings.context: self._file_management_menu_lyr.addSeparator() if not settings.must_be_supported_type: self._file_management_menu_base.addSeparator() if self._recent_path_actions: self._file_management_menu_db.addSeparator() self._file_management_menu_lyr.addSeparator() self._file_management_menu_base.addSeparator() for action in self._recent_path_actions: self._file_management_menu_db.addAction(action) self._file_management_menu_lyr.addAction(action) self._file_management_menu_base.addAction(action) self._file_management_menu_db.addAction(self._clear_recent_paths_action) self._file_management_menu_lyr.addAction(self._clear_recent_paths_action) self._file_management_menu_base.addAction(self._clear_recent_paths_action) # def createContextMenu(self) -> QMenu: # menu = self._original_menu() # # if not self._view.currentLayer(): # return menu # # uri = Uri(self._view.currentLayer()) # fm = FileManager(uri) # # action_before = None # for action in menu.actions(): # if 'Set Layer Scale' in action.text(): # action_before = action # break # # self._file_management_menu.clear() # for action, settings in self._actions.items(): # if isinstance(action, QAction): # if settings.must_be_supported and fm.is_valid(): # if settings.must_be_database and uri.is_database(): # self._file_management_menu.addAction(action) # elif not settings.must_be_database: # self._file_management_menu.addAction(action) # elif not settings.must_be_supported: # if settings.must_be_database and uri.is_database(): # self._file_management_menu.addAction(action) # elif not settings.must_be_database: # self._file_management_menu.addAction(action) # elif isinstance(action, str) and action == 'separator': # self._file_management_menu.addSeparator() # elif isinstance(action, str): # if QSettings().contains(action): # recent_paths = [str(x) for x in QSettings().value(action) if x] # if not isinstance(recent_paths, list): # continue # for i, recent_path in enumerate(recent_paths): # if i == 0: # self._file_management_menu.addSeparator() # func = eval(f'lambda: copy_path(self._view, \'relative path\', \'{recent_path}\', settings)', # {'self': self, 'copy_path': copy_path, 'settings': self._settings}) # action_ = QAction(f'Copy Relative Path From: {recent_path}', self._file_management_menu) # action_.triggered.connect(func) # self._file_management_menu.addAction(action_) # # if i + 1 == len(recent_paths): # action_ = QAction('Clear History', self._file_management_menu) # action_.triggered.connect(lambda: QSettings().remove('file_management/recent_rel_paths')) # self._file_management_menu.addAction(action_) # # if not self._file_management_menu.isEmpty(): # if action_before is not None: # menu.insertMenu(action_before, self._file_management_menu) # menu.insertSeparator(action_before) # else: # menu.addSeparator() # menu.addMenu(self._file_management_menu) # # return menu