diff --git a/lisp/ui/settings/app_configuration.py b/lisp/ui/settings/app_configuration.py index 551cfa944..764a48c02 100644 --- a/lisp/ui/settings/app_configuration.py +++ b/lisp/ui/settings/app_configuration.py @@ -1,6 +1,6 @@ # This file is part of Linux Show Player # -# Copyright 2016 Francesco Ceruti +# Copyright 2020 Francesco Ceruti # # Linux Show Player is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,127 +15,34 @@ # You should have received a copy of the GNU General Public License # along with Linux Show Player. If not, see . -import logging from collections import namedtuple -from PyQt5 import QtCore -from PyQt5.QtCore import QModelIndex -from PyQt5.QtWidgets import QVBoxLayout, QDialogButtonBox, QDialog - from lisp.core.dicttree import DictNode +from lisp.ui.settings.configuration_dialog import ConfigurationDialog from lisp.ui.ui_utils import translate -from lisp.ui.widgets.pagestreewidget import PagesTreeModel, PagesTreeWidget - -logger = logging.getLogger(__name__) PageEntry = namedtuple("PageEntry", ("page", "config")) -class AppConfigurationDialog(QDialog): +class AppConfigurationDialog(ConfigurationDialog): PagesRegistry = DictNode() def __init__(self, **kwargs): super().__init__(**kwargs) self.setWindowTitle(translate("AppConfiguration", "LiSP preferences")) - self.setWindowModality(QtCore.Qt.WindowModal) - self.setMinimumSize(800, 510) - self.resize(800, 510) - self.setLayout(QVBoxLayout()) - - self.configurations = {} - - self.model = PagesTreeModel(tr_context="SettingsPageName") - for page_node in AppConfigurationDialog.PagesRegistry.children: - self._populateModel(QModelIndex(), page_node) - - self.mainPage = PagesTreeWidget(self.model) - self.mainPage.selectFirst() - self.layout().addWidget(self.mainPage) - - self.dialogButtons = QDialogButtonBox(self) - self.dialogButtons.setStandardButtons( - QDialogButtonBox.Cancel - | QDialogButtonBox.Apply - | QDialogButtonBox.Ok - ) - self.layout().addWidget(self.dialogButtons) - - self.dialogButtons.button(QDialogButtonBox.Cancel).clicked.connect( - self.reject - ) - self.dialogButtons.button(QDialogButtonBox.Apply).clicked.connect( - self.applySettings - ) - self.dialogButtons.button(QDialogButtonBox.Ok).clicked.connect( - self.__onOk - ) - - def applySettings(self): - for conf, pages in self.configurations.items(): - for page in pages: - conf.update(page.getSettings()) - - conf.write() - - def _populateModel(self, model_parent, page_parent): - if page_parent.value is not None: - page_class = page_parent.value.page - config = page_parent.value.config - else: - page_class = None - config = None - - try: - if page_class is None: - # The current node have no page, use the parent model-index - # as parent for it's children - model_index = model_parent - else: - page_instance = page_class() - page_instance.loadSettings(config) - model_index = self.model.addPage( - page_instance, parent=model_parent - ) - - # Keep track of configurations and corresponding pages - self.configurations.setdefault(config, []).append(page_instance) - except Exception: - if not isinstance(page_class, type): - page_name = "InvalidPage" - else: - page_name = getattr(page_class, "Name", page_class.__name__) - - logger.warning( - translate( - "AppConfigurationWarning", - 'Cannot load configuration page: "{}" ({})', - ).format(page_name, page_parent.path()), - exc_info=True, - ) - else: - for page_node in page_parent.children: - self._populateModel(model_index, page_node) - - def __onOk(self): - self.applySettings() - self.accept() @staticmethod - def registerSettingsPage(path, page, config): + def _getConfigFromPageEntry(page_parent): + return page_parent.value.config + + @classmethod + def registerSettingsPage(cls, path, page, config): """ :param path: indicate the page "position": 'category.sub.key' :type path: str :type page: type :type config: lisp.core.configuration.Configuration """ - AppConfigurationDialog.PagesRegistry.set( + cls.PagesRegistry.set( path, PageEntry(page=page, config=config) ) - - @staticmethod - def unregisterSettingsPage(path): - """ - :param path: indicate the page "position": 'category.sub.key' - :type path: str - """ - AppConfigurationDialog.PagesRegistry.pop(path) diff --git a/lisp/ui/settings/configuration_dialog.py b/lisp/ui/settings/configuration_dialog.py new file mode 100644 index 000000000..3256a8685 --- /dev/null +++ b/lisp/ui/settings/configuration_dialog.py @@ -0,0 +1,141 @@ +# This file is part of Linux Show Player +# +# Copyright 2020 Francesco Ceruti +# +# Linux Show Player 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 3 of the License, or +# (at your option) any later version. +# +# Linux Show Player is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Linux Show Player. If not, see . + +import logging + +from PyQt5 import QtCore +from PyQt5.QtCore import QModelIndex +from PyQt5.QtWidgets import QVBoxLayout, QDialogButtonBox, QDialog + +from lisp.ui.ui_utils import translate +from lisp.ui.widgets.pagestreewidget import PagesTreeModel, PagesTreeWidget + +logger = logging.getLogger(__name__) + + +class ConfigurationDialog(QDialog): + ''' + Note for implementing subclasses of this: + 1) Define a named tuple named "PageEntry" (not a class member) + 2) Define a class member named "PagesRegistry" of type "DictNode" + 3) Define a static method named "_getConfigFromPageEntry" + which returns the config from step (1) + ''' + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.setWindowModality(QtCore.Qt.WindowModal) + self.setMinimumSize(800, 510) + self.resize(800, 510) + self.setLayout(QVBoxLayout()) + + self.configurations = {} + + self.model = PagesTreeModel(tr_context="SettingsPageName") + for page_node in self.__class__.PagesRegistry.children: + self._populateModel(QModelIndex(), page_node) + + self.mainPage = PagesTreeWidget(self.model) + self.mainPage.selectFirst() + self.layout().addWidget(self.mainPage) + + self.dialogButtons = QDialogButtonBox(self) + self.dialogButtons.setStandardButtons( + QDialogButtonBox.Cancel + | QDialogButtonBox.Apply + | QDialogButtonBox.Ok + ) + self.layout().addWidget(self.dialogButtons) + + self.dialogButtons.button(QDialogButtonBox.Cancel).clicked.connect( + self.reject + ) + self.dialogButtons.button(QDialogButtonBox.Apply).clicked.connect( + self.applySettings + ) + self.dialogButtons.button(QDialogButtonBox.Ok).clicked.connect( + self.__onOk + ) + + def applySettings(self): + for conf, pages in self.configurations.items(): + for page in pages: + conf.update(page.getSettings()) + + conf.write() + + def _populateModel(self, model_parent, page_parent): + if page_parent.value is not None: + page_class = page_parent.value.page + config = self._getConfigFromPageEntry(page_parent) + else: + page_class = None + config = None + + try: + if page_class is None: + # The current node have no page, use the parent model-index + # as parent for it's children + model_index = model_parent + else: + page_instance = page_class() + page_instance.loadSettings(config) + model_index = self.model.addPage( + page_instance, parent=model_parent + ) + + # Keep track of configurations and corresponding pages + self.configurations.setdefault(config, []).append(page_instance) + except Exception: + if not isinstance(page_class, type): + page_name = "InvalidPage" + else: + page_name = getattr(page_class, "Name", page_class.__name__) + + logger.warning( + translate( + "ConfigurationWarning", + 'Cannot load configuration page: "{}" ({})', + ).format(page_name, page_parent.path()), + exc_info=True, + ) + else: + for page_node in page_parent.children: + self._populateModel(model_index, page_node) + + def __onOk(self): + self.applySettings() + self.accept() + + @staticmethod + def _getConfigFromPageEntry(page_parent): + '''This needs overridding by any subclass.''' + logger.critical( + translate( + "ConfigurationCritical", + "Need to implement the Static Method `_getConfigFromPageEntry`" + ) + ) + return None + + @classmethod + def unregisterSettingsPage(cls, path): + """ + :param path: indicate the page "position": 'category.sub.key' + :type path: str + """ + cls.PagesRegistry.pop(path) diff --git a/lisp/ui/settings/session_configuration.py b/lisp/ui/settings/session_configuration.py index 0de2d3182..c647649b0 100644 --- a/lisp/ui/settings/session_configuration.py +++ b/lisp/ui/settings/session_configuration.py @@ -1,8 +1,6 @@ -# -*- coding: utf-8 -*- -# # This file is part of Linux Show Player # -# Copyright 2012-2016 Francesco Ceruti +# Copyright 2020 Francesco Ceruti # # Linux Show Player is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,127 +15,34 @@ # You should have received a copy of the GNU General Public License # along with Linux Show Player. If not, see . -import logging from collections import namedtuple -from PyQt5 import QtCore -from PyQt5.QtCore import QModelIndex -from PyQt5.QtWidgets import QVBoxLayout, QDialogButtonBox, QDialog - from lisp.core.dicttree import DictNode -from lisp.core.util import typename -from lisp.ui.settings.pages import SettingsPage, TreeMultiSettingsWidget -#from lisp.ui.settings.pages_tree_model import PagesTreeModel -from lisp.ui.widgets.pagestreewidget import PagesTreeModel +from lisp.ui.settings.configuration_dialog import ConfigurationDialog from lisp.ui.ui_utils import translate -logger = logging.getLogger(__name__) - -PageEntry = namedtuple('PageEntry', ('page', 'plugin')) +PageEntry = namedtuple("PageEntry", ("page", "plugin")) -class SessionConfigurationDialog(QDialog): +class SessionConfigurationDialog(ConfigurationDialog): PagesRegistry = DictNode() def __init__(self, **kwargs): super().__init__(**kwargs) self.setWindowTitle(translate('SessionConfiguration', 'Session preferences')) - self.setWindowModality(QtCore.Qt.WindowModal) - self.setMaximumSize(800, 510) - self.setMinimumSize(800, 510) - self.resize(800, 510) - self.setLayout(QVBoxLayout()) - - self._confsMap = {} - self.model = PagesTreeModel() - for r_node in SessionConfigurationDialog.PagesRegistry.children: - self._populateModel(QModelIndex(), r_node) - - self.mainPage = TreeMultiSettingsWidget(self.model) - if len(self.PagesRegistry.children): - self.mainPage.selectFirst() - self.layout().addWidget(self.mainPage) - - self.dialogButtons = QDialogButtonBox(self) - self.dialogButtons.setStandardButtons( - QDialogButtonBox.Cancel | - QDialogButtonBox.Apply | - QDialogButtonBox.Ok - ) - self.layout().addWidget(self.dialogButtons) - - self.dialogButtons.button(QDialogButtonBox.Cancel).clicked.connect( - self.reject) - self.dialogButtons.button(QDialogButtonBox.Apply).clicked.connect( - self.applySettings) - self.dialogButtons.button(QDialogButtonBox.Ok).clicked.connect( - self.__onOk) - - def applySettings(self): - for conf, pages in self._confsMap.items(): - for page in pages: - conf.update(page.getSettings()) - conf.write() - - def _populateModel(self, m_parent, r_parent): - if r_parent.value is not None: - page_class = r_parent.value.page - config = r_parent.value.plugin.SessionConfig - else: - page_class = None - config = None - - try: - if page_class is None: - # The current node have no page, use the parent model-index - # as parent for it's children - mod_index = m_parent - else: - page_instance = page_class() - page_instance.loadSettings(config) - mod_index = self.model.addPage(page_instance, parent=m_parent) - - # Keep track of configurations and corresponding pages - self._confsMap.setdefault(config, []).append(page_instance) - - except Exception: - if not isinstance(page_class, type): - page_name = 'InvalidPage' - else: - page_name = getattr(page_class, 'Name', page_class.__name__) - - logger.warning( - 'Cannot load configuration page: "{}" ({})'.format( - page_name, r_parent.path()), exc_info=True) - else: - for r_node in r_parent.children: - self._populateModel(mod_index, r_node) - - def __onOk(self): - self.applySettings() - self.accept() @staticmethod - def registerSettingsPage(path, page, plugin): - """ - :param path: indicate the page "position": 'category.sub.key' - :type path: str - :type page: Type[lisp.ui.settings.settings_page.SettingsPage] - :type plugin_config: lisp.core.configuration.Configuration - """ - if issubclass(page, SettingsPage): - SessionConfigurationDialog.PagesRegistry.set( - path, PageEntry(page=page, plugin=plugin)) - else: - raise TypeError( - 'SessionConfiguration pages must be SettingsPage(s), not {}' - .format(typename(page)) - ) + def _getConfigFromPageEntry(page_parent): + return page_parent.value.plugin.SessionConfig - @staticmethod - def unregisterSettingsPage(path): + @classmethod + def registerSettingsPage(cls, path, page, plugin): """ :param path: indicate the page "position": 'category.sub.key' :type path: str + :type page: type + :type plugin: lisp.core.plugin.Plugin """ - SessionConfigurationDialog.PagesRegistry.pop(path) + cls.PagesRegistry.set( + path, PageEntry(page=page, plugin=plugin) + )