src/eric7/Preferences/ThemeManager.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
23 23
24 class ThemeManager(QObject): 24 class ThemeManager(QObject):
25 """ 25 """
26 Class implementing a manager object for color themes. 26 Class implementing a manager object for color themes.
27 """ 27 """
28
28 ColorKeyPatternList = [ 29 ColorKeyPatternList = [
29 "Diff/.*Color", 30 "Diff/.*Color",
30 "Editor/Colour/", 31 "Editor/Colour/",
31 "IRC/.*Colou?r", 32 "IRC/.*Colou?r",
32 "Project/Colour", 33 "Project/Colour",
44 "UI/NotificationCriticalBackground", 45 "UI/NotificationCriticalBackground",
45 "UI/NotificationCriticalForeground", 46 "UI/NotificationCriticalForeground",
46 "UI/NotificationWarningBackground", 47 "UI/NotificationWarningBackground",
47 "UI/NotificationWarningForeground", 48 "UI/NotificationWarningForeground",
48 ] 49 ]
49 50
50 def __init__(self: "ThemeManager", parent: QObject = None): 51 def __init__(self: "ThemeManager", parent: QObject = None):
51 """ 52 """
52 Constructor 53 Constructor
53 54
54 @param parent reference to the parent object (defaults to None) 55 @param parent reference to the parent object (defaults to None)
55 @type QObject (optional) 56 @type QObject (optional)
56 """ 57 """
57 super().__init__(parent) 58 super().__init__(parent)
58 59
59 def importTheme(self: "ThemeManager") -> bool: 60 def importTheme(self: "ThemeManager") -> bool:
60 """ 61 """
61 Public method to import a theme file and set the colors. 62 Public method to import a theme file and set the colors.
62 63
63 @return flag indicating a successful import 64 @return flag indicating a successful import
64 @rtype bool 65 @rtype bool
65 """ 66 """
66 filename = EricFileDialog.getOpenFileName( 67 filename = EricFileDialog.getOpenFileName(
67 None, 68 None,
68 self.tr("Import Theme"), 69 self.tr("Import Theme"),
69 getConfig("ericThemesDir"), 70 getConfig("ericThemesDir"),
70 self.tr("eric Theme Files (*.ethj);;All Files (*)") 71 self.tr("eric Theme Files (*.ethj);;All Files (*)"),
71 ) 72 )
72 if filename: 73 if filename:
73 try: 74 try:
74 with open(filename, "r") as f: 75 with open(filename, "r") as f:
75 jsonString = f.read() 76 jsonString = f.read()
79 None, 80 None,
80 self.tr("Import Theme"), 81 self.tr("Import Theme"),
81 self.tr( 82 self.tr(
82 "<p>The theme file <b>{0}</b> could not" 83 "<p>The theme file <b>{0}</b> could not"
83 " be read.</p><p>Reason: {1}</p>" 84 " be read.</p><p>Reason: {1}</p>"
84 ).format(filename, str(err)) 85 ).format(filename, str(err)),
85 ) 86 )
86 return False 87 return False
87 88
88 # step 1: process stylesheet data 89 # step 1: process stylesheet data
89 stylesheetDict = themeDict["stylesheet"] 90 stylesheetDict = themeDict["stylesheet"]
90 if stylesheetDict["name"]: 91 if stylesheetDict["name"]:
91 stylesheetsDir = os.path.join( 92 stylesheetsDir = os.path.join(Globals.getConfigDir(), "stylesheets")
92 Globals.getConfigDir(), "stylesheets")
93 if not os.path.exists(stylesheetsDir): 93 if not os.path.exists(stylesheetsDir):
94 os.makedirs(stylesheetsDir) 94 os.makedirs(stylesheetsDir)
95 stylesheetFile = os.path.join( 95 stylesheetFile = os.path.join(stylesheetsDir, stylesheetDict["name"])
96 stylesheetsDir, stylesheetDict["name"]) 96 ok = (
97 ok = EricMessageBox.yesNo( 97 EricMessageBox.yesNo(
98 None, 98 None,
99 self.tr("Import Theme"), 99 self.tr("Import Theme"),
100 self.tr( 100 self.tr(
101 "The stylesheet file {0} exists already." 101 "The stylesheet file {0} exists already."
102 " Shall it be overwritten?" 102 " Shall it be overwritten?"
103 ).format(stylesheetDict["name"]) 103 ).format(stylesheetDict["name"]),
104 ) if os.path.exists(stylesheetFile) else True 104 )
105 if os.path.exists(stylesheetFile)
106 else True
107 )
105 if ok: 108 if ok:
106 try: 109 try:
107 with open(stylesheetFile, "w") as f: 110 with open(stylesheetFile, "w") as f:
108 f.write(stylesheetDict["contents"]) 111 f.write(stylesheetDict["contents"])
109 except OSError as err: 112 except OSError as err:
111 None, 114 None,
112 self.tr("Import Theme"), 115 self.tr("Import Theme"),
113 self.tr( 116 self.tr(
114 "<p>The stylesheet file <b>{0}</b> could" 117 "<p>The stylesheet file <b>{0}</b> could"
115 " not be written.</p><p>Reason: {1}</p>" 118 " not be written.</p><p>Reason: {1}</p>"
116 ).format(stylesheetFile, str(err)) 119 ).format(stylesheetFile, str(err)),
117 ) 120 )
118 stylesheetFile = "" 121 stylesheetFile = ""
119 Preferences.setUI("StyleSheet", stylesheetFile) 122 Preferences.setUI("StyleSheet", stylesheetFile)
120 123
121 # step 2: transfer the color entries 124 # step 2: transfer the color entries
122 settings = Preferences.getSettings() 125 settings = Preferences.getSettings()
123 colorsDict = themeDict["colors"] 126 colorsDict = themeDict["colors"]
124 for key, value in colorsDict.items(): 127 for key, value in colorsDict.items():
125 settings.setValue(key, value) 128 settings.setValue(key, value)
126 129
127 Preferences.syncPreferences() 130 Preferences.syncPreferences()
128 return True 131 return True
129 132
130 return False 133 return False
131 134
132 def exportTheme(self: "ThemeManager"): 135 def exportTheme(self: "ThemeManager"):
133 """ 136 """
134 Public method to export the current colors to a theme file. 137 Public method to export the current colors to a theme file.
135 """ 138 """
136 filename, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 139 filename, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
137 None, 140 None,
138 self.tr("Export Theme"), 141 self.tr("Export Theme"),
139 os.path.expanduser("~"), 142 os.path.expanduser("~"),
140 self.tr("eric Theme Files (*.ethj)"), 143 self.tr("eric Theme Files (*.ethj)"),
141 "", 144 "",
142 EricFileDialog.DontConfirmOverwrite 145 EricFileDialog.DontConfirmOverwrite,
143 ) 146 )
144 if filename: 147 if filename:
145 ext = os.path.splitext(filename)[1] 148 ext = os.path.splitext(filename)[1]
146 if not ext: 149 if not ext:
147 filename = "{0}{1}".format( 150 filename = "{0}{1}".format(
148 filename, 151 filename, selectedFilter.rsplit(None, 1)[-1][2:-1]
149 selectedFilter.rsplit(None, 1)[-1][2:-1]) 152 )
150 153
151 ok = ( 154 ok = (
152 EricMessageBox.yesNo( 155 EricMessageBox.yesNo(
153 None, 156 None,
154 self.tr("Export Theme"), 157 self.tr("Export Theme"),
155 self.tr( 158 self.tr(
156 """<p>The theme file <b>{0}</b> exists""" 159 """<p>The theme file <b>{0}</b> exists"""
157 """ already. Overwrite it?</p>""").format(filename)) 160 """ already. Overwrite it?</p>"""
158 if os.path.exists(filename) else 161 ).format(filename),
159 True 162 )
163 if os.path.exists(filename)
164 else True
160 ) 165 )
161 166
162 if ok: 167 if ok:
163 # step 1: generate a dictionary with all color settings 168 # step 1: generate a dictionary with all color settings
164 settings = Preferences.getSettings() 169 settings = Preferences.getSettings()
165 colorKeyFilterRe = re.compile("|".join( 170 colorKeyFilterRe = re.compile(
166 ThemeManager.ColorKeyPatternList + 171 "|".join(
167 ThemeManager.ColorKeyList 172 ThemeManager.ColorKeyPatternList + ThemeManager.ColorKeyList
168 )) 173 )
169 174 )
170 keys = [k for k in settings.allKeys() 175
171 if colorKeyFilterRe.match(k)] 176 keys = [k for k in settings.allKeys() if colorKeyFilterRe.match(k)]
172 colorsDict = {} 177 colorsDict = {}
173 for key in keys: 178 for key in keys:
174 colorsDict[key] = settings.value(key) 179 colorsDict[key] = settings.value(key)
175 180
176 # step 2: read the contents of the current stylesheet 181 # step 2: read the contents of the current stylesheet
177 stylesheetDict = { 182 stylesheetDict = {"contents": "", "name": ""}
178 "contents": "",
179 "name": ""
180 }
181 stylesheet = Preferences.getUI("StyleSheet") 183 stylesheet = Preferences.getUI("StyleSheet")
182 if stylesheet and os.path.exists(stylesheet): 184 if stylesheet and os.path.exists(stylesheet):
183 try: 185 try:
184 with open(stylesheet, "r") as f: 186 with open(stylesheet, "r") as f:
185 stylesheetDict["contents"] = f.read() 187 stylesheetDict["contents"] = f.read()
189 None, 191 None,
190 self.tr("Export Theme"), 192 self.tr("Export Theme"),
191 self.tr( 193 self.tr(
192 "<p>The stylesheet file <b>{0}</b> could not" 194 "<p>The stylesheet file <b>{0}</b> could not"
193 " be read.</p><p>Reason: {1}</p>" 195 " be read.</p><p>Reason: {1}</p>"
194 ).format(stylesheet, str(err)) 196 ).format(stylesheet, str(err)),
195 ) 197 )
196 198
197 themeDict = { 199 themeDict = {
198 "colors": colorsDict, 200 "colors": colorsDict,
199 "stylesheet": stylesheetDict, 201 "stylesheet": stylesheetDict,
200 } 202 }
201 203
202 try: 204 try:
203 jsonString = json.dumps(themeDict, indent=2) 205 jsonString = json.dumps(themeDict, indent=2)
204 with open(filename, "w") as f: 206 with open(filename, "w") as f:
205 f.write(jsonString) 207 f.write(jsonString)
206 except (TypeError, OSError) as err: 208 except (TypeError, OSError) as err:
208 None, 210 None,
209 self.tr("Export Theme"), 211 self.tr("Export Theme"),
210 self.tr( 212 self.tr(
211 "<p>The theme file <b>{0}</b> could not" 213 "<p>The theme file <b>{0}</b> could not"
212 " be written.</p><p>Reason: {1}</p>" 214 " be written.</p><p>Reason: {1}</p>"
213 ).format(filename, str(err)) 215 ).format(filename, str(err)),
214 ) 216 )

eric ide

mercurial