src/eric7/Preferences/Shortcuts.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Preferences/Shortcuts.py	Thu Jul 07 11:23:56 2022 +0200
@@ -0,0 +1,361 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2004 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing functions dealing with keyboard shortcuts.
+"""
+
+import contextlib
+
+from PyQt6.QtCore import QFile, QIODevice, QCoreApplication
+from PyQt6.QtGui import QKeySequence
+
+from EricWidgets.EricApplication import ericApp
+from EricWidgets import EricMessageBox
+
+from Preferences import Prefs, syncPreferences
+
+
+def __readShortcut(act, category, prefClass):
+    """
+    Private function to read a single keyboard shortcut from the settings.
+    
+    @param act reference to the action object (EricAction)
+    @param category category the action belongs to (string)
+    @param prefClass preferences class used as the storage area
+    """
+    if act.objectName():
+        accel = prefClass.settings.value(
+            "Shortcuts/{0}/{1}/Accel".format(category, act.objectName()))
+        if accel is not None:
+            act.setShortcut(QKeySequence(accel))
+        accel = prefClass.settings.value(
+            "Shortcuts/{0}/{1}/AltAccel".format(category, act.objectName()))
+        if accel is not None:
+            act.setAlternateShortcut(QKeySequence(accel), removeEmpty=True)
+
+
+def readShortcuts(prefClass=Prefs, helpViewer=None, pluginName=None):
+    """
+    Module function to read the keyboard shortcuts for the defined QActions.
+    
+    @param prefClass preferences class used as the storage area
+    @param helpViewer reference to the help window object
+    @param pluginName name of the plugin for which to load shortcuts
+        (string)
+    """
+    if helpViewer is None and pluginName is None:
+        for act in ericApp().getObject("Project").getActions():
+            __readShortcut(act, "Project", prefClass)
+        
+        for act in ericApp().getObject("UserInterface").getActions('ui'):
+            __readShortcut(act, "General", prefClass)
+        
+        for act in ericApp().getObject("UserInterface").getActions('wizards'):
+            __readShortcut(act, "Wizards", prefClass)
+        
+        for act in ericApp().getObject("DebugUI").getActions():
+            __readShortcut(act, "Debug", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('edit'):
+            __readShortcut(act, "Edit", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('file'):
+            __readShortcut(act, "File", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('search'):
+            __readShortcut(act, "Search", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('view'):
+            __readShortcut(act, "View", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('macro'):
+            __readShortcut(act, "Macro", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('bookmark'):
+            __readShortcut(act, "Bookmarks", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('spelling'):
+            __readShortcut(act, "Spelling", prefClass)
+        
+        actions = ericApp().getObject("ViewManager").getActions('window')
+        if actions:
+            for act in actions:
+                __readShortcut(act, "Window", prefClass)
+        
+        for category, ref in ericApp().getPluginObjects():
+            if hasattr(ref, "getActions"):
+                actions = ref.getActions()
+                for act in actions:
+                    __readShortcut(act, category, prefClass)
+    
+    if helpViewer is not None:
+        helpViewerCategory = helpViewer.getActionsCategory()
+        for act in helpViewer.getActions():
+            __readShortcut(act, helpViewerCategory, prefClass)
+    
+    if pluginName is not None:
+        with contextlib.suppress(KeyError):
+            ref = ericApp().getPluginObject(pluginName)
+            if hasattr(ref, "getActions"):
+                actions = ref.getActions()
+                for act in actions:
+                    __readShortcut(act, pluginName, prefClass)
+    
+
+def __saveShortcut(act, category, prefClass):
+    """
+    Private function to write a single keyboard shortcut to the settings.
+    
+    @param act reference to the action object (EricAction)
+    @param category category the action belongs to (string)
+    @param prefClass preferences class used as the storage area
+    """
+    if act.objectName():
+        prefClass.settings.setValue(
+            "Shortcuts/{0}/{1}/Accel".format(category, act.objectName()),
+            act.shortcut().toString())
+        prefClass.settings.setValue(
+            "Shortcuts/{0}/{1}/AltAccel".format(category, act.objectName()),
+            act.alternateShortcut().toString())
+
+
+def saveShortcuts(prefClass=Prefs, helpViewer=None):
+    """
+    Module function to write the keyboard shortcuts for the defined QActions.
+    
+    @param prefClass preferences class used as the storage area
+    @param helpViewer reference to the help window object
+    """
+    if helpViewer is None:
+        # step 1: clear all previously saved shortcuts
+        prefClass.settings.beginGroup("Shortcuts")
+        prefClass.settings.remove("")
+        prefClass.settings.endGroup()
+        
+        # step 2: save the various shortcuts
+        for act in ericApp().getObject("Project").getActions():
+            __saveShortcut(act, "Project", prefClass)
+        
+        for act in ericApp().getObject("UserInterface").getActions('ui'):
+            __saveShortcut(act, "General", prefClass)
+        
+        for act in ericApp().getObject("UserInterface").getActions('wizards'):
+            __saveShortcut(act, "Wizards", prefClass)
+        
+        for act in ericApp().getObject("DebugUI").getActions():
+            __saveShortcut(act, "Debug", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('edit'):
+            __saveShortcut(act, "Edit", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('file'):
+            __saveShortcut(act, "File", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('search'):
+            __saveShortcut(act, "Search", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('view'):
+            __saveShortcut(act, "View", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('macro'):
+            __saveShortcut(act, "Macro", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('bookmark'):
+            __saveShortcut(act, "Bookmarks", prefClass)
+        
+        for act in ericApp().getObject("ViewManager").getActions('spelling'):
+            __saveShortcut(act, "Spelling", prefClass)
+        
+        actions = ericApp().getObject("ViewManager").getActions('window')
+        if actions:
+            for act in actions:
+                __saveShortcut(act, "Window", prefClass)
+        
+        for category, ref in ericApp().getPluginObjects():
+            if hasattr(ref, "getActions"):
+                actions = ref.getActions()
+                for act in actions:
+                    __saveShortcut(act, category, prefClass)
+    
+    else:
+        helpViewerCategory = helpViewer.getActionsCategory()
+        
+        # step 1: clear all previously saved shortcuts
+        prefClass.settings.beginGroup(
+            "Shortcuts/{0}".format(helpViewerCategory)
+        )
+        prefClass.settings.remove("")
+        prefClass.settings.endGroup()
+        
+        # step 2: save the shortcuts
+        for act in helpViewer.getActions():
+            __saveShortcut(act, helpViewerCategory, prefClass)
+
+
+def exportShortcuts(fn, helpViewer=None):
+    """
+    Module function to export the keyboard shortcuts for the defined QActions.
+    
+    @param fn filename of the export file
+    @type str
+    @param helpViewer reference to the help window object
+    @type WebBrowserWindow
+    """
+    # let the plugin manager create on demand plugin objects
+    pm = ericApp().getObject("PluginManager")
+    pm.initOnDemandPlugins()
+    
+    from .ShortcutsFile import ShortcutsFile
+    shortcutsFile = ShortcutsFile()
+    shortcutsFile.writeFile(fn, helpViewer)
+
+
+def importShortcuts(fn, helpViewer=None):
+    """
+    Module function to import the keyboard shortcuts for the defined actions.
+    
+    @param fn filename of the import file
+    @type str
+    @param helpViewer reference to the help window object
+    @type WebBrowserWindow
+    """
+    # let the plugin manager create on demand plugin objects
+    pm = ericApp().getObject("PluginManager")
+    pm.initOnDemandPlugins()
+    
+    if fn.endswith(".ekj"):
+        # new JSON based file
+        from .ShortcutsFile import ShortcutsFile
+        shortcutsFile = ShortcutsFile()
+        shortcuts = shortcutsFile.readFile(fn)
+        if shortcuts:
+            setActions(shortcuts, helpViewer=helpViewer)
+            saveShortcuts()
+            syncPreferences()
+    else:
+        # old XML based file
+        f = QFile(fn)
+        if f.open(QIODevice.OpenModeFlag.ReadOnly):
+            from EricXML.ShortcutsReader import ShortcutsReader
+            reader = ShortcutsReader(f)
+            reader.readXML()
+            f.close()
+            if not reader.hasError():
+                shortcuts = reader.getShortcuts()
+                setActions(shortcuts, helpViewer=helpViewer)
+                saveShortcuts()
+                syncPreferences()
+        else:
+            EricMessageBox.critical(
+                None,
+                QCoreApplication.translate(
+                    "Shortcuts", "Import Keyboard Shortcuts"),
+                QCoreApplication.translate(
+                    "Shortcuts",
+                    "<p>The keyboard shortcuts file <b>{0}</b> could not be"
+                    " read.</p>")
+                .format(fn))
+
+
+def __setAction(actions, shortcutsDict):
+    """
+    Private function to set a single keyboard shortcut category shortcuts.
+    
+    @param actions list of actions to set
+    @type list of EricAction
+    @param shortcutsDict dictionary containing accelerator information for
+        one category
+    @type dict
+    """
+    for act in actions:
+        if act.objectName():
+            with contextlib.suppress(KeyError):
+                accel, altAccel = shortcutsDict[act.objectName()]
+                act.setShortcut(QKeySequence(accel))
+                act.setAlternateShortcut(QKeySequence(altAccel),
+                                         removeEmpty=True)
+
+
+def setActions(shortcuts, helpViewer=None):
+    """
+    Module function to set actions based on the imported shortcuts file.
+    
+    @param shortcuts dictionary containing the accelerator information
+        read from a JSON or XML file
+    @type dict
+    @param helpViewer reference to the help window object
+    @type WebBrowserWindow
+    """
+    if helpViewer is None:
+        if "Project" in shortcuts:
+            __setAction(
+                ericApp().getObject("Project").getActions(),
+                shortcuts["Project"])
+        
+        if "General" in shortcuts:
+            __setAction(
+                ericApp().getObject("UserInterface").getActions('ui'),
+                shortcuts["General"])
+        
+        if "Wizards" in shortcuts:
+            __setAction(
+                ericApp().getObject("UserInterface").getActions('wizards'),
+                shortcuts["Wizards"])
+        
+        if "Debug" in shortcuts:
+            __setAction(
+                ericApp().getObject("DebugUI").getActions(),
+                shortcuts["Debug"])
+        
+        if "Edit" in shortcuts:
+            __setAction(
+                ericApp().getObject("ViewManager").getActions('edit'),
+                shortcuts["Edit"])
+        
+        if "File" in shortcuts:
+            __setAction(
+                ericApp().getObject("ViewManager").getActions('file'),
+                shortcuts["File"])
+        
+        if "Search" in shortcuts:
+            __setAction(
+                ericApp().getObject("ViewManager").getActions('search'),
+                shortcuts["Search"])
+        
+        if "View" in shortcuts:
+            __setAction(
+                ericApp().getObject("ViewManager").getActions('view'),
+                shortcuts["View"])
+        
+        if "Macro" in shortcuts:
+            __setAction(
+                ericApp().getObject("ViewManager").getActions('macro'),
+                shortcuts["Macro"])
+        
+        if "Bookmarks" in shortcuts:
+            __setAction(
+                ericApp().getObject("ViewManager").getActions('bookmark'),
+                shortcuts["Bookmarks"])
+        
+        if "Spelling" in shortcuts:
+            __setAction(
+                ericApp().getObject("ViewManager").getActions('spelling'),
+                shortcuts["Spelling"])
+        
+        if "Window" in shortcuts:
+            actions = ericApp().getObject("ViewManager").getActions('window')
+            if actions:
+                __setAction(actions, shortcuts["Window"])
+        
+        for category, ref in ericApp().getPluginObjects():
+            if category in shortcuts and hasattr(ref, "getActions"):
+                actions = ref.getActions()
+                __setAction(actions, shortcuts[category])
+    
+    else:
+        category = helpViewer.getActionsCategory()
+        if category in shortcuts:
+            __setAction(helpViewer.getActions(), shortcuts[category])

eric ide

mercurial