eric7/Preferences/Shortcuts.py

branch
eric7
changeset 8312
800c432b34c8
parent 8243
cc717c2ae956
child 8318
962bce857696
equal deleted inserted replaced
8311:4e8b98454baa 8312:800c432b34c8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing functions dealing with keyboard shortcuts.
8 """
9
10 import contextlib
11
12 from PyQt5.QtCore import QFile, QIODevice, QCoreApplication
13 from PyQt5.QtGui import QKeySequence
14
15 from E5Gui.E5Application import e5App
16 from E5Gui import E5MessageBox
17
18 from Preferences import Prefs, syncPreferences
19
20
21 def __readShortcut(act, category, prefClass):
22 """
23 Private function to read a single keyboard shortcut from the settings.
24
25 @param act reference to the action object (E5Action)
26 @param category category the action belongs to (string)
27 @param prefClass preferences class used as the storage area
28 """
29 if act.objectName():
30 accel = prefClass.settings.value(
31 "Shortcuts/{0}/{1}/Accel".format(category, act.objectName()))
32 if accel is not None:
33 act.setShortcut(QKeySequence(accel))
34 accel = prefClass.settings.value(
35 "Shortcuts/{0}/{1}/AltAccel".format(category, act.objectName()))
36 if accel is not None:
37 act.setAlternateShortcut(QKeySequence(accel), removeEmpty=True)
38
39
40 def readShortcuts(prefClass=Prefs, helpViewer=None, pluginName=None):
41 """
42 Module function to read the keyboard shortcuts for the defined QActions.
43
44 @param prefClass preferences class used as the storage area
45 @param helpViewer reference to the help window object
46 @param pluginName name of the plugin for which to load shortcuts
47 (string)
48 """
49 if helpViewer is None and pluginName is None:
50 for act in e5App().getObject("Project").getActions():
51 __readShortcut(act, "Project", prefClass)
52
53 for act in e5App().getObject("UserInterface").getActions('ui'):
54 __readShortcut(act, "General", prefClass)
55
56 for act in e5App().getObject("UserInterface").getActions('wizards'):
57 __readShortcut(act, "Wizards", prefClass)
58
59 for act in e5App().getObject("DebugUI").getActions():
60 __readShortcut(act, "Debug", prefClass)
61
62 for act in e5App().getObject("ViewManager").getActions('edit'):
63 __readShortcut(act, "Edit", prefClass)
64
65 for act in e5App().getObject("ViewManager").getActions('file'):
66 __readShortcut(act, "File", prefClass)
67
68 for act in e5App().getObject("ViewManager").getActions('search'):
69 __readShortcut(act, "Search", prefClass)
70
71 for act in e5App().getObject("ViewManager").getActions('view'):
72 __readShortcut(act, "View", prefClass)
73
74 for act in e5App().getObject("ViewManager").getActions('macro'):
75 __readShortcut(act, "Macro", prefClass)
76
77 for act in e5App().getObject("ViewManager").getActions('bookmark'):
78 __readShortcut(act, "Bookmarks", prefClass)
79
80 for act in e5App().getObject("ViewManager").getActions('spelling'):
81 __readShortcut(act, "Spelling", prefClass)
82
83 actions = e5App().getObject("ViewManager").getActions('window')
84 if actions:
85 for act in actions:
86 __readShortcut(act, "Window", prefClass)
87
88 for category, ref in e5App().getPluginObjects():
89 if hasattr(ref, "getActions"):
90 actions = ref.getActions()
91 for act in actions:
92 __readShortcut(act, category, prefClass)
93
94 if helpViewer is not None:
95 helpViewerCategory = helpViewer.getActionsCategory()
96 for act in helpViewer.getActions():
97 __readShortcut(act, helpViewerCategory, prefClass)
98
99 if pluginName is not None:
100 with contextlib.suppress(KeyError):
101 ref = e5App().getPluginObject(pluginName)
102 if hasattr(ref, "getActions"):
103 actions = ref.getActions()
104 for act in actions:
105 __readShortcut(act, pluginName, prefClass)
106
107
108 def __saveShortcut(act, category, prefClass):
109 """
110 Private function to write a single keyboard shortcut to the settings.
111
112 @param act reference to the action object (E5Action)
113 @param category category the action belongs to (string)
114 @param prefClass preferences class used as the storage area
115 """
116 if act.objectName():
117 prefClass.settings.setValue(
118 "Shortcuts/{0}/{1}/Accel".format(category, act.objectName()),
119 act.shortcut().toString())
120 prefClass.settings.setValue(
121 "Shortcuts/{0}/{1}/AltAccel".format(category, act.objectName()),
122 act.alternateShortcut().toString())
123
124
125 def saveShortcuts(prefClass=Prefs, helpViewer=None):
126 """
127 Module function to write the keyboard shortcuts for the defined QActions.
128
129 @param prefClass preferences class used as the storage area
130 @param helpViewer reference to the help window object
131 """
132 if helpViewer is None:
133 # step 1: clear all previously saved shortcuts
134 prefClass.settings.beginGroup("Shortcuts")
135 prefClass.settings.remove("")
136 prefClass.settings.endGroup()
137
138 # step 2: save the various shortcuts
139 for act in e5App().getObject("Project").getActions():
140 __saveShortcut(act, "Project", prefClass)
141
142 for act in e5App().getObject("UserInterface").getActions('ui'):
143 __saveShortcut(act, "General", prefClass)
144
145 for act in e5App().getObject("UserInterface").getActions('wizards'):
146 __saveShortcut(act, "Wizards", prefClass)
147
148 for act in e5App().getObject("DebugUI").getActions():
149 __saveShortcut(act, "Debug", prefClass)
150
151 for act in e5App().getObject("ViewManager").getActions('edit'):
152 __saveShortcut(act, "Edit", prefClass)
153
154 for act in e5App().getObject("ViewManager").getActions('file'):
155 __saveShortcut(act, "File", prefClass)
156
157 for act in e5App().getObject("ViewManager").getActions('search'):
158 __saveShortcut(act, "Search", prefClass)
159
160 for act in e5App().getObject("ViewManager").getActions('view'):
161 __saveShortcut(act, "View", prefClass)
162
163 for act in e5App().getObject("ViewManager").getActions('macro'):
164 __saveShortcut(act, "Macro", prefClass)
165
166 for act in e5App().getObject("ViewManager").getActions('bookmark'):
167 __saveShortcut(act, "Bookmarks", prefClass)
168
169 for act in e5App().getObject("ViewManager").getActions('spelling'):
170 __saveShortcut(act, "Spelling", prefClass)
171
172 actions = e5App().getObject("ViewManager").getActions('window')
173 if actions:
174 for act in actions:
175 __saveShortcut(act, "Window", prefClass)
176
177 for category, ref in e5App().getPluginObjects():
178 if hasattr(ref, "getActions"):
179 actions = ref.getActions()
180 for act in actions:
181 __saveShortcut(act, category, prefClass)
182
183 else:
184 helpViewerCategory = helpViewer.getActionsCategory()
185
186 # step 1: clear all previously saved shortcuts
187 prefClass.settings.beginGroup(
188 "Shortcuts/{0}".format(helpViewerCategory)
189 )
190 prefClass.settings.remove("")
191 prefClass.settings.endGroup()
192
193 # step 2: save the shortcuts
194 for act in helpViewer.getActions():
195 __saveShortcut(act, helpViewerCategory, prefClass)
196
197
198 def exportShortcuts(fn, helpViewer=None):
199 """
200 Module function to export the keyboard shortcuts for the defined QActions.
201
202 @param fn filename of the export file
203 @type str
204 @param helpViewer reference to the help window object
205 @type WebBrowserWindow
206 """
207 # let the plugin manager create on demand plugin objects
208 pm = e5App().getObject("PluginManager")
209 pm.initOnDemandPlugins()
210
211 if fn.endswith(".ekj"):
212 # new JSON based file
213 from .ShortcutsFile import ShortcutsFile
214 shortcutsFile = ShortcutsFile()
215 shortcutsFile.writeFile(fn, helpViewer)
216 else:
217 # old XML based file
218 f = QFile(fn)
219 if f.open(QIODevice.OpenModeFlag.WriteOnly):
220 from E5XML.ShortcutsWriter import ShortcutsWriter
221 ShortcutsWriter(f).writeXML(helpViewer=helpViewer)
222 f.close()
223 else:
224 E5MessageBox.critical(
225 None,
226 QCoreApplication.translate(
227 "Shortcuts", "Export Keyboard Shortcuts"),
228 QCoreApplication.translate(
229 "Shortcuts",
230 "<p>The keyboard shortcuts file <b>{0}</b> could not"
231 " be written.</p>")
232 .format(fn))
233
234
235 def importShortcuts(fn, helpViewer=None):
236 """
237 Module function to import the keyboard shortcuts for the defined actions.
238
239 @param fn filename of the import file
240 @type str
241 @param helpViewer reference to the help window object
242 @type WebBrowserWindow
243 """
244 # let the plugin manager create on demand plugin objects
245 pm = e5App().getObject("PluginManager")
246 pm.initOnDemandPlugins()
247
248 if fn.endswith(".ekj"):
249 # new JSON based file
250 from .ShortcutsFile import ShortcutsFile
251 shortcutsFile = ShortcutsFile()
252 shortcuts = shortcutsFile.readFile(fn)
253 if shortcuts:
254 setActions(shortcuts, helpViewer=helpViewer)
255 saveShortcuts()
256 syncPreferences()
257 else:
258 # old XML based file
259 f = QFile(fn)
260 if f.open(QIODevice.OpenModeFlag.ReadOnly):
261 from E5XML.ShortcutsReader import ShortcutsReader
262 reader = ShortcutsReader(f)
263 reader.readXML()
264 f.close()
265 if not reader.hasError():
266 shortcuts = reader.getShortcuts()
267 setActions(shortcuts, helpViewer=helpViewer)
268 saveShortcuts()
269 syncPreferences()
270 else:
271 E5MessageBox.critical(
272 None,
273 QCoreApplication.translate(
274 "Shortcuts", "Import Keyboard Shortcuts"),
275 QCoreApplication.translate(
276 "Shortcuts",
277 "<p>The keyboard shortcuts file <b>{0}</b> could not be"
278 " read.</p>")
279 .format(fn))
280
281
282 def __setAction(actions, shortcutsDict):
283 """
284 Private function to set a single keyboard shortcut category shortcuts.
285
286 @param actions list of actions to set
287 @type list of E5Action
288 @param shortcutsDict dictionary containing accelerator information for
289 one category
290 @type dict
291 """
292 for act in actions:
293 if act.objectName():
294 with contextlib.suppress(KeyError):
295 accel, altAccel = shortcutsDict[act.objectName()]
296 act.setShortcut(QKeySequence(accel))
297 act.setAlternateShortcut(QKeySequence(altAccel),
298 removeEmpty=True)
299
300
301 def setActions(shortcuts, helpViewer=None):
302 """
303 Module function to set actions based on the imported shortcuts file.
304
305 @param shortcuts dictionary containing the accelerator information
306 read from a JSON or XML file
307 @type dict
308 @param helpViewer reference to the help window object
309 @type WebBrowserWindow
310 """
311 if helpViewer is None:
312 if "Project" in shortcuts:
313 __setAction(
314 e5App().getObject("Project").getActions(),
315 shortcuts["Project"])
316
317 if "General" in shortcuts:
318 __setAction(
319 e5App().getObject("UserInterface").getActions('ui'),
320 shortcuts["General"])
321
322 if "Wizards" in shortcuts:
323 __setAction(
324 e5App().getObject("UserInterface").getActions('wizards'),
325 shortcuts["Wizards"])
326
327 if "Debug" in shortcuts:
328 __setAction(
329 e5App().getObject("DebugUI").getActions(),
330 shortcuts["Debug"])
331
332 if "Edit" in shortcuts:
333 __setAction(
334 e5App().getObject("ViewManager").getActions('edit'),
335 shortcuts["Edit"])
336
337 if "File" in shortcuts:
338 __setAction(
339 e5App().getObject("ViewManager").getActions('file'),
340 shortcuts["File"])
341
342 if "Search" in shortcuts:
343 __setAction(
344 e5App().getObject("ViewManager").getActions('search'),
345 shortcuts["Search"])
346
347 if "View" in shortcuts:
348 __setAction(
349 e5App().getObject("ViewManager").getActions('view'),
350 shortcuts["View"])
351
352 if "Macro" in shortcuts:
353 __setAction(
354 e5App().getObject("ViewManager").getActions('macro'),
355 shortcuts["Macro"])
356
357 if "Bookmarks" in shortcuts:
358 __setAction(
359 e5App().getObject("ViewManager").getActions('bookmark'),
360 shortcuts["Bookmarks"])
361
362 if "Spelling" in shortcuts:
363 __setAction(
364 e5App().getObject("ViewManager").getActions('spelling'),
365 shortcuts["Spelling"])
366
367 if "Window" in shortcuts:
368 actions = e5App().getObject("ViewManager").getActions('window')
369 if actions:
370 __setAction(actions, shortcuts["Window"])
371
372 for category, ref in e5App().getPluginObjects():
373 if category in shortcuts and hasattr(ref, "getActions"):
374 actions = ref.getActions()
375 __setAction(actions, shortcuts[category])
376
377 else:
378 category = helpViewer.getActionsCategory()
379 if category in shortcuts:
380 __setAction(helpViewer.getActions(), shortcuts[category])

eric ide

mercurial