File indexing completed on 2024-04-28 07:51:06
0001 # -*- coding: utf-8 -*- 0002 0003 """ 0004 Copyright (C) 2008-2016 Wolfgang Rohdewald <wolfgang@rohdewald.de> 0005 0006 partially based on C++ code from: 0007 - Copyright (C) 2006 Mauricio Piacentini <mauricio@tabuleiro.com> 0008 0009 SPDX-License-Identifier: GPL-2.0 0010 0011 """ 0012 0013 from collections import defaultdict 0014 0015 from kde import KConfigSkeleton 0016 from log import logException, logDebug 0017 from common import Internal, Debug 0018 0019 0020 class Parameter: 0021 0022 """helper class for defining configuration parameters""" 0023 0024 def __init__(self, group, name, default=None): 0025 """configuration group, parameter name, default value""" 0026 self.group = group 0027 self.name = name 0028 self.default = default 0029 self.item = None 0030 0031 def itemValue(self): 0032 """return the value of this item""" 0033 return self.item.value() 0034 0035 0036 class StringParameter(Parameter): 0037 0038 """helper class for defining string parameters""" 0039 0040 def __init__(self, group, name, default=None): 0041 if default is None: 0042 default = '' 0043 Parameter.__init__(self, group, name, default) 0044 self.value = '' 0045 0046 def add(self, skeleton): 0047 """add tis parameter to the skeleton""" 0048 self.item = skeleton.addItem(self.name, self.value, self.default or '') 0049 0050 def itemValue(self): 0051 """return the value of this item""" 0052 return str(self.item.value()) 0053 0054 0055 class BoolParameter(Parameter): 0056 0057 """helper class for defining boolean parameters""" 0058 0059 def __init__(self, group, name, default=None): 0060 if default is None: 0061 default = False 0062 Parameter.__init__(self, group, name, default) 0063 self.value = default 0064 0065 def add(self, skeleton): 0066 """add tis parameter to the skeleton""" 0067 self.item = skeleton.addItem(self.name, self.value, self.default) 0068 0069 0070 class IntParameter(Parameter): 0071 0072 """helper class for defining integer parameters""" 0073 0074 def __init__(self, group, name, default=None, 0075 minValue=None, maxValue=None): 0076 """minValue and maxValue are also used by the edit widget""" 0077 if default is None: 0078 default = 0 0079 Parameter.__init__(self, group, name, default) 0080 self.value = default 0081 self.minValue = minValue 0082 self.maxValue = maxValue 0083 0084 def add(self, skeleton): 0085 """add this parameter to the skeleton""" 0086 self.item = skeleton.addItem(self.name, self.value, self.default) 0087 if self.minValue is not None: 0088 self.item.setMinValue(self.minValue) 0089 if self.maxValue is not None: 0090 self.item.setMaxValue(self.maxValue) 0091 0092 0093 class SetupPreferences(KConfigSkeleton): 0094 0095 """Holds all Kajongg options. Only instantiate this once""" 0096 _Parameters = {} 0097 0098 def __init__(self): # pylint: disable=super-init-not-called 0099 if Internal.Preferences: 0100 logException('Preferences is not None') 0101 self.__watching = defaultdict(list) 0102 Internal.Preferences = self 0103 KConfigSkeleton.__init__(self) 0104 self.configChanged.connect(self.callTriggers) 0105 self.__oldValues = defaultdict(str) 0106 self.addString('General', 'tilesetName', 'default') 0107 self.addString('General', 'windTilesetName', 'traditional') 0108 self.addString('General', 'backgroundName', 'wood_light') 0109 self.addBool('Display', 'showShadows', True) 0110 self.addBool('Display', 'rearrangeMelds', False) 0111 self.addBool('Display', 'showOnlyPossibleActions', True) 0112 self.addBool('Display', 'propose', True) 0113 self.addInteger('Display', 'animationSpeed', 70, 0, 99) 0114 self.addBool('Display', 'useSounds', True) 0115 self.addBool('Display', 'uploadVoice', False) 0116 0117 def callTrigger(self, name): 0118 """call registered callback for this attribute change""" 0119 newValue = getattr(self, name) 0120 if self.__oldValues[name] != newValue: 0121 if Debug.preferences: 0122 logDebug('{}: {} -> {} calling {}'.format( 0123 name, 0124 self.__oldValues[name], 0125 newValue, 0126 ','.join(x.__name__ for x in self.__watching[name]))) 0127 for method in self.__watching[name]: 0128 method(self.__oldValues[name], newValue) 0129 self.__oldValues[name] = newValue 0130 0131 def callTriggers(self): 0132 """call registered callbacks for specific attribute changes""" 0133 for name in self.__watching: 0134 self.callTrigger(name) 0135 0136 def addWatch(self, name, method): 0137 """If name changes, call method. 0138 method must accept 2 arguments: old value and new value.""" 0139 if method not in self.__watching[name]: 0140 self.__watching[name].append(method) 0141 if Debug.preferences: 0142 logDebug('addWatch on {}, hook {}'.format( 0143 name, method.__name__)) 0144 self.callTrigger(name) # initial change 0145 0146 def __getattr__(self, name): 0147 """undefined attributes might be parameters""" 0148 if name not in SetupPreferences._Parameters: 0149 return self.__getattribute__(name) 0150 par = SetupPreferences._Parameters[name] 0151 return par.itemValue() 0152 0153 def __setattr__(self, name, value): 0154 """undefined attributes might be parameters""" 0155 if name not in SetupPreferences._Parameters: 0156 KConfigSkeleton.__setattr__(self, name, value) 0157 return 0158 par = SetupPreferences._Parameters[name] 0159 par.item.setValue(value) 0160 0161 def __getitem__(self, key): 0162 return self.__getattr__(key) 0163 0164 def __setitem__(self, key, value): 0165 self.__setattr__(key, value) 0166 0167 def __delitem__(self, key): 0168 """pylint wants this for a complete container, but we do not need it""" 0169 del SetupPreferences._Parameters[key] 0170 0171 def __len__(self): 0172 """pylint wants this for a complete container, but we do not need it""" 0173 return len(SetupPreferences._Parameters) 0174 0175 def addParameter(self, par): 0176 """add a parameter to the skeleton""" 0177 if par.name not in SetupPreferences._Parameters: 0178 SetupPreferences._Parameters[par.name] = par 0179 self.setCurrentGroup(par.group) 0180 par.add(self) 0181 0182 def addString(self, group, name, default=None): 0183 """add a string parameter to the skeleton""" 0184 self.addParameter(StringParameter(group, name, default)) 0185 0186 def addBool(self, group, name, default=None): 0187 """add a string parameter to the skeleton""" 0188 self.addParameter(BoolParameter(group, name, default)) 0189 0190 def addInteger(self, group, name, default=None, 0191 minValue=None, maxValue=None): 0192 """add a string parameter to the skeleton""" 0193 self.addParameter(IntParameter( 0194 group, name, default, minValue, maxValue)) 0195 0196 def animationDuration(self): 0197 """in milliseconds""" 0198 return (99 - self.animationSpeed) * 100 // 4