From 1889bb0eae8de6c0c27855fa010c6f3a969dd250 Mon Sep 17 00:00:00 2001 From: tsalemink Date: Wed, 27 Nov 2024 18:39:17 +1300 Subject: [PATCH] Add user options for recents menu --- src/mapclient/core/mainapplication.py | 6 +- src/mapclient/core/managers/optionsmanager.py | 14 +++- src/mapclient/settings/definitions.py | 2 + .../view/managers/options/optionsdialog.py | 10 ++- .../view/managers/options/qt/optionsdialog.ui | 66 +++++++++++++++++++ .../managers/options/ui/ui_optionsdialog.py | 60 ++++++++++++++--- src/mapclient/view/workflow/workflowwidget.py | 19 +++++- 7 files changed, 161 insertions(+), 16 deletions(-) diff --git a/src/mapclient/core/mainapplication.py b/src/mapclient/core/mainapplication.py index b969fc45..7608ff59 100644 --- a/src/mapclient/core/mainapplication.py +++ b/src/mapclient/core/mainapplication.py @@ -27,7 +27,7 @@ from mapclient.core.managers.pluginmanager import PluginManager from mapclient.core.managers.optionsmanager import OptionsManager from mapclient.core.checks import runChecks -from mapclient.settings.definitions import CHECK_TOOLS_ON_STARTUP +from mapclient.settings.definitions import CHECK_TOOLS_ON_STARTUP, RECENTS_LENGTH logger = logging.getLogger(__name__) @@ -125,8 +125,10 @@ def readSettings(self): self._package_manager.read_settings(settings) def add_recent_workflow(self, recent): + recents_length = self._optionsManager.getOption(RECENTS_LENGTH) + self.remove_recent_workflow(recent) - if len(self._recent_workflows) >= 10: + while len(self._recent_workflows) >= recents_length: self._recent_workflows.pop(0) self._recent_workflows.append(recent) diff --git a/src/mapclient/core/managers/optionsmanager.py b/src/mapclient/core/managers/optionsmanager.py index 19d5017a..50b87b83 100644 --- a/src/mapclient/core/managers/optionsmanager.py +++ b/src/mapclient/core/managers/optionsmanager.py @@ -8,18 +8,23 @@ from mapclient.settings.definitions import SHOW_STEP_NAMES, CLOSE_AFTER, METRICS_PERMISSION, INTERNAL_EXE, UNSET_FLAG, \ DONT_CREATE_VIRTUAL_ENV, OPTIONS_SETTINGS_TAG, INTERNAL_WORKFLOWS_AVAILABLE, INTERNAL_WORKFLOW_DIR, VIRTUAL_ENV_PATH, \ GIT_EXE, PYSIDE_UIC_EXE, PYSIDE_RCC_EXE, PREVIOUS_PW_WRITE_STEP_LOCATION, PREVIOUS_PW_ICON_LOCATION, CHECK_TOOLS_ON_STARTUP, \ - USE_EXTERNAL_GIT, USE_EXTERNAL_RCC, USE_EXTERNAL_UIC, PREVIOUS_WORKFLOW, AUTOLOAD_PREVIOUS_WORKFLOW, METRICS_PERMISSION_ATTAINED + USE_EXTERNAL_GIT, USE_EXTERNAL_RCC, USE_EXTERNAL_UIC, RECENTS_ABSOLUTE_PATHS, RECENTS_LENGTH, PREVIOUS_WORKFLOW, \ + AUTOLOAD_PREVIOUS_WORKFLOW, METRICS_PERMISSION_ATTAINED def _is_boolean(option): - return option in [SHOW_STEP_NAMES, CHECK_TOOLS_ON_STARTUP, DONT_CREATE_VIRTUAL_ENV, METRICS_PERMISSION, - USE_EXTERNAL_GIT, USE_EXTERNAL_RCC, USE_EXTERNAL_UIC, INTERNAL_WORKFLOWS_AVAILABLE, AUTOLOAD_PREVIOUS_WORKFLOW] + return option in [SHOW_STEP_NAMES, CHECK_TOOLS_ON_STARTUP, DONT_CREATE_VIRTUAL_ENV, METRICS_PERMISSION, USE_EXTERNAL_GIT, + USE_EXTERNAL_RCC, USE_EXTERNAL_UIC, RECENTS_ABSOLUTE_PATHS, INTERNAL_WORKFLOWS_AVAILABLE, AUTOLOAD_PREVIOUS_WORKFLOW] def _is_float(option): return option in [CLOSE_AFTER] +def _is_int(option): + return option in [RECENTS_LENGTH] + + class OptionsManager(object): def __init__(self): @@ -28,6 +33,7 @@ def __init__(self): SHOW_STEP_NAMES: True, CLOSE_AFTER: 2.0, METRICS_PERMISSION: False, DONT_CREATE_VIRTUAL_ENV: False, CHECK_TOOLS_ON_STARTUP: True, USE_EXTERNAL_GIT: False, USE_EXTERNAL_RCC: False, USE_EXTERNAL_UIC: False, + RECENTS_ABSOLUTE_PATHS: False, RECENTS_LENGTH: 10, VIRTUAL_ENV_PATH: get_virtualenv_directory(), GIT_EXE: which('git'), PYSIDE_RCC_EXE: INTERNAL_EXE, PYSIDE_UIC_EXE: INTERNAL_EXE, PREVIOUS_PW_WRITE_STEP_LOCATION: '', PREVIOUS_PW_ICON_LOCATION: '', @@ -65,6 +71,8 @@ def readSettings(self, settings): self._options[option] = settings.value(option) == 'true' elif _is_float(option): self._options[option] = float(settings.value(option)) + elif _is_int(option): + self._options[option] = int(settings.value(option)) else: self._options[option] = settings.value(option) settings.endGroup() diff --git a/src/mapclient/settings/definitions.py b/src/mapclient/settings/definitions.py index 5ebc5839..347e2cda 100644 --- a/src/mapclient/settings/definitions.py +++ b/src/mapclient/settings/definitions.py @@ -42,6 +42,8 @@ USE_EXTERNAL_GIT = 'checkBoxUseExternalGit' USE_EXTERNAL_RCC = 'checkBoxUseExternalPySideRCC' USE_EXTERNAL_UIC = 'checkBoxUseExternalPySideUIC' +RECENTS_ABSOLUTE_PATHS = 'checkBoxAbsolutePaths' +RECENTS_LENGTH = 'spinBoxRecentsLength' WIZARD_TOOL_STRING = 'Wizard Tool' VIRTUAL_ENVIRONMENT_STRING = 'Virtual Environment' diff --git a/src/mapclient/view/managers/options/optionsdialog.py b/src/mapclient/view/managers/options/optionsdialog.py index 64b07d25..d140fefc 100644 --- a/src/mapclient/view/managers/options/optionsdialog.py +++ b/src/mapclient/view/managers/options/optionsdialog.py @@ -154,6 +154,8 @@ def load(self, options): internal_directory_option = self._ui.lineEditInternalWorkflowDirectory.objectName() message_box_timer = self._ui.doubleSpinBoxMessageBoxTimer.objectName() metrics_permission = self._ui.checkBoxMetricsPermission.objectName() + absolute_paths = self._ui.checkBoxAbsolutePaths.objectName() + recents_length = self._ui.spinBoxRecentsLength.objectName() if step_name_option in options: self._ui.checkBoxShowStepNames.setChecked(options[step_name_option]) if check_tools_option in options: @@ -176,6 +178,10 @@ def load(self, options): self._ui.doubleSpinBoxMessageBoxTimer.setValue(options[message_box_timer]) if metrics_permission in options: self._ui.checkBoxMetricsPermission.setChecked(options[metrics_permission]) + if absolute_paths in options: + self._ui.checkBoxAbsolutePaths.setChecked(options[absolute_paths]) + if recents_length in options: + self._ui.spinBoxRecentsLength.setValue(options[recents_length]) self._update_ui() self._test_tools() @@ -191,7 +197,9 @@ def save(self): self._ui.lineEditGitExecutable.objectName(): self._ui.lineEditGitExecutable.text(), self._ui.lineEditInternalWorkflowDirectory.objectName(): self._ui.lineEditInternalWorkflowDirectory.text(), self._ui.doubleSpinBoxMessageBoxTimer.objectName(): self._ui.doubleSpinBoxMessageBoxTimer.value(), - self._ui.checkBoxMetricsPermission.objectName(): self._ui.checkBoxMetricsPermission.isChecked()} + self._ui.checkBoxMetricsPermission.objectName(): self._ui.checkBoxMetricsPermission.isChecked(), + self._ui.checkBoxAbsolutePaths.objectName(): self._ui.checkBoxAbsolutePaths.isChecked(), + self._ui.spinBoxRecentsLength.objectName(): self._ui.spinBoxRecentsLength.value()} return options diff --git a/src/mapclient/view/managers/options/qt/optionsdialog.ui b/src/mapclient/view/managers/options/qt/optionsdialog.ui index 3d99cfff..92878ee2 100644 --- a/src/mapclient/view/managers/options/qt/optionsdialog.ui +++ b/src/mapclient/view/managers/options/qt/optionsdialog.ui @@ -139,6 +139,72 @@ + + + + Recent workflows + + + + + + If deselected, minimum difference paths will be displayed. + + + Display absolute paths for recent workflows + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 120 + 16777215 + + + + 1 + + + 10 + + + + + + + Recent workflows list length + + + + + + + + + diff --git a/src/mapclient/view/managers/options/ui/ui_optionsdialog.py b/src/mapclient/view/managers/options/ui/ui_optionsdialog.py index 450a09ce..2a78fab6 100644 --- a/src/mapclient/view/managers/options/ui/ui_optionsdialog.py +++ b/src/mapclient/view/managers/options/ui/ui_optionsdialog.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'optionsdialog.ui' ## -## Created by: Qt User Interface Compiler version 6.7.0 +## Created by: Qt User Interface Compiler version 6.5.1 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -16,10 +16,11 @@ QImage, QKeySequence, QLinearGradient, QPainter, QPalette, QPixmap, QRadialGradient, QTransform) from PySide6.QtWidgets import (QAbstractButton, QApplication, QCheckBox, QDialog, - QDialogButtonBox, QDoubleSpinBox, QFormLayout, QGridLayout, - QGroupBox, QHBoxLayout, QLabel, QLineEdit, - QPlainTextEdit, QPushButton, QSizePolicy, QSpacerItem, - QTabWidget, QVBoxLayout, QWidget) + QDialogButtonBox, QDoubleSpinBox, QFormLayout, QFrame, + QGridLayout, QGroupBox, QHBoxLayout, QLabel, + QLineEdit, QPlainTextEdit, QPushButton, QSizePolicy, + QSpacerItem, QSpinBox, QTabWidget, QVBoxLayout, + QWidget) class Ui_OptionsDialog(object): def setupUi(self, OptionsDialog): @@ -110,7 +111,42 @@ def setupUi(self, OptionsDialog): self.verticalLayout_4.addWidget(self.groupBox_3) - self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) + self.groupBox_4 = QGroupBox(self.tabGeneral) + self.groupBox_4.setObjectName(u"groupBox_4") + self.verticalLayout_8 = QVBoxLayout(self.groupBox_4) + self.verticalLayout_8.setObjectName(u"verticalLayout_8") + self.checkBoxAbsolutePaths = QCheckBox(self.groupBox_4) + self.checkBoxAbsolutePaths.setObjectName(u"checkBoxAbsolutePaths") + + self.verticalLayout_8.addWidget(self.checkBoxAbsolutePaths) + + self.frame = QFrame(self.groupBox_4) + self.frame.setObjectName(u"frame") + self.frame.setFrameShape(QFrame.StyledPanel) + self.frame.setFrameShadow(QFrame.Raised) + self.horizontalLayout_5 = QHBoxLayout(self.frame) + self.horizontalLayout_5.setObjectName(u"horizontalLayout_5") + self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0) + self.spinBoxRecentsLength = QSpinBox(self.frame) + self.spinBoxRecentsLength.setObjectName(u"spinBoxRecentsLength") + self.spinBoxRecentsLength.setMaximumSize(QSize(120, 16777215)) + self.spinBoxRecentsLength.setMinimum(1) + self.spinBoxRecentsLength.setValue(10) + + self.horizontalLayout_5.addWidget(self.spinBoxRecentsLength) + + self.label_2 = QLabel(self.frame) + self.label_2.setObjectName(u"label_2") + + self.horizontalLayout_5.addWidget(self.label_2) + + + self.verticalLayout_8.addWidget(self.frame) + + + self.verticalLayout_4.addWidget(self.groupBox_4) + + self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_4.addItem(self.verticalSpacer) @@ -199,7 +235,7 @@ def setupUi(self, OptionsDialog): self.lineEditGitExecutable = QLineEdit(self.groupBoxPMR) self.lineEditGitExecutable.setObjectName(u"lineEditGitExecutable") - sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed) + sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lineEditGitExecutable.sizePolicy().hasHeightForWidth()) @@ -229,7 +265,7 @@ def setupUi(self, OptionsDialog): self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName(u"horizontalLayout") - self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(self.horizontalSpacer) @@ -244,7 +280,7 @@ def setupUi(self, OptionsDialog): self.verticalLayout_2.addWidget(self.groupBoxOutput) - self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) + self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(self.verticalSpacer_2) @@ -280,6 +316,12 @@ def retranslateUi(self, OptionsDialog): self.label.setText(QCoreApplication.translate("OptionsDialog", u"Auto close after (seconds)", None)) self.groupBox_3.setTitle(QCoreApplication.translate("OptionsDialog", u"Permissions", None)) self.checkBoxMetricsPermission.setText(QCoreApplication.translate("OptionsDialog", u"Allow the MAP-Client to log metrics/usage statistics", None)) + self.groupBox_4.setTitle(QCoreApplication.translate("OptionsDialog", u"Recent workflows", None)) +#if QT_CONFIG(tooltip) + self.checkBoxAbsolutePaths.setToolTip(QCoreApplication.translate("OptionsDialog", u"If deselected, minimum difference paths will be displayed.", None)) +#endif // QT_CONFIG(tooltip) + self.checkBoxAbsolutePaths.setText(QCoreApplication.translate("OptionsDialog", u"Display absolute paths for recent workflows", None)) + self.label_2.setText(QCoreApplication.translate("OptionsDialog", u"Recent workflows list length", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabGeneral), QCoreApplication.translate("OptionsDialog", u"&General", None)) self.groupBoxStepWizard.setTitle(QCoreApplication.translate("OptionsDialog", u"Step Wizard", None)) self.checkBoxUseExternalPySideRCC.setText(QCoreApplication.translate("OptionsDialog", u"Use external PySide resource compiler (rcc)", None)) diff --git a/src/mapclient/view/workflow/workflowwidget.py b/src/mapclient/view/workflow/workflowwidget.py index 227450bc..c1e630e4 100644 --- a/src/mapclient/view/workflow/workflowwidget.py +++ b/src/mapclient/view/workflow/workflowwidget.py @@ -44,7 +44,8 @@ from mapclient.tools.pmr.settings.general import PMR from mapclient.settings.general import get_virtualenv_directory, is_workflow from mapclient.core.workflow.workflowerror import WorkflowError -from mapclient.settings.definitions import SHOW_STEP_NAMES, CLOSE_AFTER, USE_EXTERNAL_GIT, PREVIOUS_WORKFLOW +from mapclient.settings.definitions import SHOW_STEP_NAMES, CLOSE_AFTER, USE_EXTERNAL_GIT, PREVIOUS_WORKFLOW,\ + RECENTS_ABSOLUTE_PATHS, RECENTS_LENGTH from mapclient.core.workflow.workflowitems import MetaStep from mapclient.view.workflow.importconfigdialog import ImportConfigDialog @@ -139,6 +140,8 @@ def applyOptions(self): om = self._main_window.model().optionsManager() show_step_names = om.getOption(SHOW_STEP_NAMES) self._graphicsScene.showStepNames(show_step_names) + self._check_recents_length() + self._update_recent_menu() def undoStackIndexChanged(self, index): self._main_window.model().workflowManager().undoStackIndexChanged(index) @@ -744,8 +747,12 @@ def _create_menu_items(self): menu_workflow.addAction(self.action_Abort) def _update_recent_menu(self): + absolute_paths = self._main_window.model().optionsManager().getOption(RECENTS_ABSOLUTE_PATHS) + self.menu_recent.clear() for path, name in self._recent_workflow_paths().items(): + if absolute_paths: + name = path recent_action = QtGui.QAction(self.menu_recent) recent_action.setText(name) self.menu_recent.insertAction(QtGui.QAction(), recent_action) @@ -771,6 +778,16 @@ def _recent_workflow_paths(self): return directory_map + def _check_recents_length(self): + options_manager = self._main_window.model().optionsManager() + recents_length = options_manager.getOption(RECENTS_LENGTH) + + recent_paths = self.model().get_recent_workflows() + removals = len(recent_paths) - recents_length + if removals > 0: + for recent_path in recent_paths[:removals]: + self.model().remove_recent_workflow(recent_path) + def _open_recent_workflow(self, path): if is_workflow(path): self.open_workflow(path)