File indexing completed on 2024-04-21 04:01:55
0001 # -*- coding: utf-8 -*- 0002 0003 """ 0004 Copyright (C) 2008-2016 Wolfgang Rohdewald <wolfgang@rohdewald.de> 0005 0006 SPDX-License-Identifier: GPL-2.0 0007 0008 """ 0009 0010 from qt import QObject, QByteArray, QEvent, QSplitter, QHeaderView 0011 0012 from common import Internal, isAlive 0013 from mi18n import english 0014 0015 0016 class StateSaver(QObject): 0017 0018 """saves and restores the state for widgets""" 0019 0020 savers = {} 0021 0022 def __init__(self, *widgets): 0023 QObject.__init__(self) 0024 pref = Internal.Preferences 0025 if widgets[0] not in StateSaver.savers: 0026 StateSaver.savers[widgets[0]] = self 0027 widgets[0].installEventFilter(self) 0028 self.widgets = [] 0029 for widget in widgets: 0030 name = self.__generateName(widget) 0031 self.widgets.append((name, widget)) 0032 pref.addString('States', name + 'State') 0033 pref.addString('States', name + 'Geometry') 0034 for name, widget in self.widgets: 0035 stateFound = self.__restore(widget, name + 'State') 0036 geometryFound = self.__restore(widget, name + 'Geometry') 0037 if not stateFound and not geometryFound: 0038 pref.addString('States', name) 0039 self.__restore(widget, name) 0040 0041 @staticmethod 0042 def __restore(widget, name): 0043 """decode the saved string""" 0044 # pylint: disable=unsubscriptable-object 0045 def canRestore(name,what): 0046 return name.endswith(what) and hasattr(widget, 'restore' + what) 0047 state = QByteArray.fromHex(Internal.Preferences[name].encode()) 0048 if state: 0049 if canRestore(name, 'State'): 0050 widget.restoreState(state) 0051 elif canRestore(name, 'Geometry'): 0052 widget.restoreGeometry(state) 0053 else: 0054 # legacy 0055 if isinstance(widget, (QSplitter, QHeaderView)): 0056 widget.restoreState(state) 0057 else: 0058 widget.restoreGeometry(state) 0059 return bool(state) 0060 0061 @staticmethod 0062 def __generateName(widget): 0063 """generate a name for this widget to be used in the config file""" 0064 orgWidget = widget 0065 name = english(widget.objectName()) 0066 if not name: 0067 while widget.parentWidget(): 0068 name = widget.__class__.__name__ + name 0069 widget = widget.parentWidget() 0070 if widget.parentWidget(): 0071 widgetName = english(widget.parentWidget().objectName()) 0072 if widgetName: 0073 name = widgetName + name 0074 break 0075 if not name: 0076 name = orgWidget.__class__.__name__ 0077 return str(name) 0078 0079 def eventFilter(self, unusedWatched, event): 0080 """if the watched widget hides, save its state. 0081 Return False if the event should be handled further""" 0082 if QEvent is not None: 0083 # while appquit, QEvent may be None. Maybe not anymore 0084 # with later versions? 0085 if event.type() == QEvent.Hide: 0086 self.save() 0087 elif event.type() == QEvent.Close: 0088 self.save() 0089 widget = self.widgets[0][1] 0090 if widget in StateSaver.savers: 0091 del StateSaver.savers[widget] 0092 return False 0093 0094 @staticmethod 0095 def saveAll(): 0096 """execute all registered savers and write states to config file""" 0097 for saver in StateSaver.savers.values(): 0098 saver.save() 0099 Internal.Preferences.writeConfig() 0100 0101 @staticmethod 0102 def stateStr(state): 0103 """convert hex string to str""" 0104 return str(bytes(state.toHex()).decode()) 0105 0106 def save(self): 0107 """writes the state into Preferences, but does not save""" 0108 for name, widget in self.widgets: 0109 if isAlive(widget): 0110 # pylint: disable=unsupported-assignment-operation 0111 if hasattr(widget, 'saveState'): 0112 Internal.Preferences[name + 'State'] = self.stateStr(widget.saveState()) 0113 if hasattr(widget, 'saveGeometry'): 0114 Internal.Preferences[name + 'Geometry'] = self.stateStr(widget.saveGeometry())