Skip to content

Commit

Permalink
Shortcuts to copy services
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Nov 19, 2024
1 parent 32d650d commit ef063a5
Show file tree
Hide file tree
Showing 6 changed files with 361 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pg_service_parser/libs/
!pg_service_parser/libs/__init__.py
.idea
__pycache__
.DS_Store
120 changes: 120 additions & 0 deletions pg_service_parser/core/copy_shortcuts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from qgis.PyQt.QtCore import QAbstractTableModel, QModelIndex, QObject, Qt

from pg_service_parser.core.plugin_settings import PluginSettings


class Shortcut:
def __init__(self, service_from: str, service_to: str, name: str = None):
if name:
self.name = name
else:
self.name = f"{service_from} -> {service_to}"
self.service_from = service_from
self.service_to = service_to

def save(self):
PluginSettings().shortcut_from.setValue(self.service_from, self.name)
PluginSettings().shortcut_to.setValue(self.service_to, self.name)

def rename(self, name: str):
PluginSettings().shortcuts_node.deleteItem(self.name)
self.name = name
self.save()

def delete(self):
PluginSettings().shortcuts_node.deleteItem(self.name)


class ShortcutsModel(QAbstractTableModel):
def __init__(self, parent: QObject = None):
super().__init__(parent)
self.shortcuts = []

for shortcut in PluginSettings().shortcuts_node.items():
sh_from = PluginSettings().shortcut_from.value(shortcut)
sh_to = PluginSettings().shortcut_to.value(shortcut)
self.shortcuts.append(Shortcut(sh_from, sh_to, shortcut))

def add_shortcut(self, service_from: str, service_to: str):
existing_names = [sh.name for sh in self.shortcuts]
base_name = f"{service_from} -> {service_to}"
name = base_name
i = 2
while name in existing_names:
name = f"{base_name} ({i})"
i += 1

shortcut = Shortcut(service_from, service_to, name)
shortcut.save()
row = self.rowCount()
self.beginInsertRows(QModelIndex(), row, row)
self.shortcuts.append(shortcut)
self.endInsertRows()
self.dataChanged.emit(self.index(row, 0), self.index(row, 0))

def remove_shortcut(self, index: QModelIndex):
if not index.isValid():
return

self.beginRemoveRows(QModelIndex(), index.row(), index.row())
self.shortcuts[index.row()].delete()
del self.shortcuts[index.row()]
self.endRemoveRows()
self.dataChanged.emit(index, index)

def headerData(self, section, orientation, role=Qt.DisplayRole):
if orientation == Qt.Vertical:
return None

if role == Qt.DisplayRole:
if section == 0:
return self.tr("Name")
if section == 1:
return self.tr("From")
if section == 2:
return self.tr("To")

return super().headerData(section, orientation, role)

def rowCount(self, parent=QModelIndex()):
return len(self.shortcuts)

def columnCount(self, parent=QModelIndex()):
return 3

def flags(self, index):
if not index.isValid():
return None

if index.column() == 0:
return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
else:
return Qt.ItemIsSelectable | Qt.ItemIsEnabled

def data(self, index, role=Qt.DisplayRole):
if not index.isValid:
return None

if role == Qt.DisplayRole:
if index.column() == 0:
return self.shortcuts[index.row()].name
if index.column() == 1:
return self.shortcuts[index.row()].service_from
if index.column() == 2:
return self.shortcuts[index.row()].service_to

return None

def setData(self, index, value, role=Qt.EditRole):
if not index.isValid():
return False

if role == Qt.EditRole and len(value) > 0:
for sh in self.shortcuts:
if sh.name == value:
return False
self.shortcuts[index.row()].rename(value)
self.dataChanged.emit(index, index)
return True

return False
20 changes: 20 additions & 0 deletions pg_service_parser/core/plugin_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from qgis.core import QgsSettingsEntryString, QgsSettingsTree

PLUGIN_NAME = "pg_service_parser"


class PluginSettings:
instance = None

def __new__(cls):
if cls.instance is None:
cls.instance = super().__new__(cls)

settings_node = QgsSettingsTree.createPluginTreeNode(pluginName=PLUGIN_NAME)
shortcuts_node = settings_node.createNamedListNode("shortcuts")

cls.shortcut_from = QgsSettingsEntryString("shortcut_from", shortcuts_node)
cls.shortcut_to = QgsSettingsEntryString("shortcut_to", shortcuts_node)
cls.shortcuts_node = shortcuts_node

return cls.instance
51 changes: 49 additions & 2 deletions pg_service_parser/gui/dlg_pg_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from pg_service_parser.conf.service_settings import SERVICE_SETTINGS, SETTINGS_TEMPLATE
from pg_service_parser.core.connection_model import ServiceConnectionModel
from pg_service_parser.core.copy_shortcuts import ShortcutsModel
from pg_service_parser.core.pg_service_parser_wrapper import (
add_new_service,
conf_path,
Expand Down Expand Up @@ -34,14 +35,15 @@


class PgServiceDialog(QDialog, DIALOG_UI):

def __init__(self, parent):
def __init__(self, shortcuts_model: ShortcutsModel, parent):
QDialog.__init__(self, parent)
self.setupUi(self)

# Flag to handle initialization of new files
self.__new_empty_file = False

self.__shortcuts_model = shortcuts_model

self.__conf_file_path = conf_path()
self.__initialize_dialog()

Expand All @@ -68,6 +70,8 @@ def __initialize_dialog(self):
self.btnAddConnection.setIcon(QgsApplication.getThemeIcon("/symbologyAdd.svg"))
self.btnEditConnection.setIcon(QgsApplication.getThemeIcon("/symbologyEdit.svg"))
self.btnRemoveConnection.setIcon(QgsApplication.getThemeIcon("/symbologyRemove.svg"))
self.shortcutAddButton.setIcon(QgsApplication.getThemeIcon("/symbologyAdd.svg"))
self.shortcutRemoveButton.setIcon(QgsApplication.getThemeIcon("/symbologyRemove.svg"))
self.txtConfFile.setText(str(self.__conf_file_path))
self.lblWarning.setVisible(False)
self.lblConfFile.setText("Config file path found at ")
Expand All @@ -77,9 +81,12 @@ def __initialize_dialog(self):
self.btnCreateServiceFile.setVisible(False)
self.tblServiceConnections.horizontalHeader().setVisible(True)
self.btnRemoveSetting.setEnabled(False)
self.shortcutRemoveButton.setEnabled(False)

self.radOverwrite.toggled.connect(self.__update_target_controls)
self.btnCopyService.clicked.connect(self.__copy_service)
self.shortcutAddButton.clicked.connect(self.__create_copy_shortcut)
self.shortcutRemoveButton.clicked.connect(self.__remove_copy_shortcut)
self.cboSourceService.currentIndexChanged.connect(self.__source_service_changed)
self.tabWidget.currentChanged.connect(self.__current_tab_changed)
self.cboEditService.currentIndexChanged.connect(self.__edit_service_changed)
Expand Down Expand Up @@ -118,6 +125,7 @@ def __create_file_clicked(self):
def __update_target_controls(self, checked):
self.cboTargetService.setEnabled(self.radOverwrite.isChecked())
self.txtNewService.setEnabled(not self.radOverwrite.isChecked())
self.shortcutAddButton.setEnabled(self.radOverwrite.isChecked())

def __update_add_settings_button(self):
# Make sure to call this method whenever the settings are added/removed
Expand Down Expand Up @@ -148,6 +156,12 @@ def __initialize_copy_services(self):
self.cboSourceService.addItems(service_names(self.__conf_file_path))
self.cboSourceService.setCurrentText(current_text)

self.shortcutsTableView.setModel(self.__shortcuts_model)
self.shortcutsTableView.resizeColumnsToContents()
self.shortcutsTableView.selectionModel().selectionChanged.connect(
self.__shortcuts_selection_changed
)

def __initialize_edit_services(self):
self.__edit_model = None
current_text = self.cboEditService.currentText() # Remember latest currentText
Expand Down Expand Up @@ -199,6 +213,35 @@ def __copy_service(self):
if self.radCreate.isChecked():
self.__initialize_copy_services() # Reflect the newly added service

@pyqtSlot()
def __create_copy_shortcut(self):
target_service = self.cboTargetService.currentText()

if not self.cboTargetService.currentText():
self.bar.pushInfo("PG service", "Select a valid target service and try again.")
return
self.__shortcuts_model.add_shortcut(self.cboSourceService.currentText(), target_service)
if self.__shortcuts_model.rowCount() == 1:
self.shortcutsTableView.resizeColumnsToContents()

@pyqtSlot()
def __remove_copy_shortcut(self):
selectedIndexes = self.shortcutsTableView.selectedIndexes()
if len(selectedIndexes) == 0:
return

shortcut = self.__shortcuts_model.data(selectedIndexes[0])

res = QMessageBox.question(
self,
"Remove shortcut",
f"Are you sure you want to remove the shortcut '{shortcut}'?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
QMessageBox.StandardButton.No,
)
if res == QMessageBox.StandardButton.Yes:
self.__shortcuts_model.remove_shortcut(selectedIndexes[0])

@pyqtSlot(int)
def __current_tab_changed(self, index):
if index == COPY_TAB_INDEX:
Expand Down Expand Up @@ -374,3 +417,7 @@ def __conn_table_selection_changed(self, selected, deselected):
def __update_connection_controls(self, enable):
self.btnEditConnection.setEnabled(enable)
self.btnRemoveConnection.setEnabled(enable)

@pyqtSlot(QItemSelection, QItemSelection)
def __shortcuts_selection_changed(self, selected, deselected):
self.shortcutRemoveButton.setEnabled(len(selected) > 0)
95 changes: 89 additions & 6 deletions pg_service_parser/pg_service_parser_plugin.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,113 @@
import os
from pathlib import Path

from qgis.core import NULL, QgsSettingsTree
from qgis.PyQt.QtCore import QCoreApplication, QLocale, QSettings, QTranslator
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.PyQt.QtWidgets import QAction, QMenu, QToolButton

from pg_service_parser.core.copy_shortcuts import ShortcutsModel
from pg_service_parser.core.pg_service_parser_wrapper import (
conf_path,
copy_service_settings,
service_names,
)
from pg_service_parser.core.plugin_settings import PLUGIN_NAME
from pg_service_parser.gui.dlg_pg_service import PgServiceDialog


class PgServiceParserPlugin:
def __init__(self, iface):
self.iface = iface

# initialize translation
qgis_locale = QLocale(
str(QSettings().value("locale/userLocale")).replace(str(NULL), "en_CH")
)
locale_path = os.path.join(os.path.dirname(__file__), "i18n")
self.translator = QTranslator()
self.translator.load(qgis_locale, "qgis-pg-service-parser-plugin", "_", locale_path)
QCoreApplication.installTranslator(self.translator)

self.action = None
self.shortcuts_model = None

def tr(self, text: str) -> str:
return QCoreApplication.translate("Plugin", text)

def initGui(self):
self.action = QAction(
icon = QIcon(str(Path(__file__).parent / "images" / "logo.png"))

self.shortcuts_model = ShortcutsModel(self.iface.mainWindow())
self.shortcuts_model.dataChanged.connect(self.build_menus)

self.button = QToolButton(self.iface.mainWindow())
self.button.setIcon(icon)

self.menu = self.iface.pluginMenu().addMenu(icon, "PG service parser")

self.default_action = QAction(
QIcon(str(Path(__file__).parent / "images" / "logo.png")),
"PG service parser",
self.iface.mainWindow(),
)
self.action.triggered.connect(self.run)
self.iface.addToolBarIcon(self.action)
self.iface.addPluginToDatabaseMenu("PG service parser", self.action)
self.default_action.triggered.connect(self.run)
self.button.setDefaultAction(self.default_action)

self.action = self.iface.addToolBarWidget(self.button)

self.build_menus()

def build_menus(self):
self.menu.clear()

button_menu = QMenu()
button_menu.addAction(self.default_action)

self.menu.addAction(self.default_action)

if len(self.shortcuts_model.shortcuts):
_conf_path = conf_path()
_services = service_names(_conf_path)
self.button.setPopupMode(QToolButton.MenuButtonPopup)
button_menu.addSeparator()
for shortcut in self.shortcuts_model.shortcuts:
action = QAction(shortcut.name, self.iface.mainWindow())
action.setToolTip(
self.tr(f"Copy service '{shortcut.service_from}' to '{shortcut.service_to}'.")
)
action.setEnabled(
_conf_path.exists()
and shortcut.service_from in _services
and shortcut.service_to in _services
)
action.triggered.connect(
lambda _triggered, _shortcut=shortcut: self.copy_service(
_shortcut.service_from, _shortcut.service_to
)
)
button_menu.addAction(action)
self.menu.addAction(action)
else:
self.button.setPopupMode(QToolButton.DelayedPopup)

self.button.setMenu(button_menu)

def unload(self):
self.iface.removeToolBarIcon(self.action)
self.iface.removePluginDatabaseMenu("PG service parser", self.action)
self.iface.pluginMenu().removeAction(self.menu.menuAction())
QgsSettingsTree.unregisterPluginTreeNode(PLUGIN_NAME)

def run(self):
dlg = PgServiceDialog(self.iface.mainWindow())
dlg = PgServiceDialog(self.shortcuts_model, self.iface.mainWindow())
dlg.exec()

def copy_service(self, service_from: str, service_to: str):
print(service_from, service_to)
_conf_path = conf_path()
if _conf_path.exists():
copy_service_settings(service_from, service_to, _conf_path)
self.iface.messageBar().pushMessage(
"PG service", f"PG service copied to '{service_to}'!"
)
Loading

0 comments on commit ef063a5

Please sign in to comment.