1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/
#
# Copyright (c) 2008 - 2014 by Wilbert Berendsen
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# See http://www.gnu.org/licenses/ for more information.
"""
Interface for extensions to save and load settings from extension files
"""
import os
import sys
from PyQt5.QtCore import Qt, QObject, QSettings
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QMenu
import app
class ExtensionSettings(QObject):
"""
Manage an extension's settings, serves as an abstraction to QSettings
to make it easier to handle in an extension and to make it harder
to create damage.
Allowed settings and their default values (and implicit types) are defined
in the Extension class with the _settings_config class variable.
Extension code should never work with QSettings themselves but interact
with the extension.settings() object. Settings are loaded once upon startup
and then maintained in the object. Settings are retrieved thorugh
settings().get() and changed with settings().set(). When setting a value
both the settings object is updated and the setting written to disk
immediately.
Settings are managed in a 'settings.conf' file in the extension directory.
"""
def __init__(self, extension):
super(ExtensionSettings, self).__init__(extension)
self._extension = extension
self._defaults = extension._settings_config
self._data = dict(self._defaults)
self._load_settings()
def extension(self):
return self._extension
def get(self, key):
"""Retrieve a setting.
Raises a KeyError if non-existent key is requested."""
if not key in self._defaults.keys():
raise KeyError(
_("Trying to retrieve unknown setting '{setting}' "
"in extension '{extension}'").format(
setting=key,
extension=self.extension().name()))
return self._data[key]
def _load_settings(self):
"""Load settings from disk, is done once upon creation."""
s = QSettings(self.settings_file(), QSettings.IniFormat)
for key in self._defaults:
default = self._defaults[key]
self._data[key] = s.value(key, default, type(default))
def set(self, key, value):
"""Set a setting and save it to disk.
Check type before and raise an exception if necessary."""
extension_name = (self.extension().display_name()
or self.extension().name())
if not key in self._defaults.keys():
raise KeyError(
_("Trying to store unknown setting '{setting}' "
"in extension '{extension}'").format(
setting=key,
extension=extension_name))
try:
old_value = self._data[key]
value = type(self._defaults[key])(value)
if value == old_value:
return
self._data[key] = value
QSettings(self.settings_file(), QSettings.IniFormat).setValue(key, value)
self.extension().settings_changed(key, old_value, value)
except ValueError:
# type conversion failed
raise ValueError(
_("Trying to store setting '{setting}' in extension "
"'{extension}' with type '{type}' instead of '{type_is}'").format(
setting=key,
extension=extension_name,
type = type(self._defaults[key]),
type_is = type(value)))
def settings_file(self):
"""Return path to 'settings.conf' in the extension directory."""
extension = self.extension()
return os.path.join(
extension.parent().root_directory(),
extension.name(),
'settings.conf')
|