1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2006 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing an Action class extending QAction. |
|
8 |
|
9 This extension is necessary in order to support alternate keyboard |
|
10 shortcuts. |
|
11 """ |
|
12 |
|
13 from PyQt6.QtGui import QIcon, QKeySequence, QAction, QActionGroup |
|
14 |
|
15 from E5Gui.E5Application import e5App |
|
16 |
|
17 |
|
18 class ArgumentsError(RuntimeError): |
|
19 """ |
|
20 Class implementing an exception, which is raised, if the wrong number of |
|
21 arguments are given. |
|
22 """ |
|
23 def __init__(self, error): |
|
24 """ |
|
25 Constructor |
|
26 |
|
27 @param error error message of the exception (string) |
|
28 """ |
|
29 self.errorMessage = str(error) |
|
30 |
|
31 def __repr__(self): |
|
32 """ |
|
33 Special method returning a representation of the exception. |
|
34 |
|
35 @return string representing the error message |
|
36 """ |
|
37 return str(self.errorMessage) |
|
38 |
|
39 def __str__(self): |
|
40 """ |
|
41 Special method returning a string representation of the exception. |
|
42 |
|
43 @return string representing the error message |
|
44 """ |
|
45 return str(self.errorMessage) |
|
46 |
|
47 |
|
48 class E5Action(QAction): |
|
49 """ |
|
50 Class implementing an Action class extending QAction. |
|
51 """ |
|
52 def __init__(self, *args): |
|
53 """ |
|
54 Constructor |
|
55 |
|
56 @param args argument list of the constructor. This list is one of |
|
57 <ul> |
|
58 <li>text (string), icon (QIcon), menu text (string), |
|
59 accelarator (QKeySequence), alternative accelerator |
|
60 (QKeySequence), parent (QObject), name (string), toggle |
|
61 (boolean)</li> |
|
62 <li>text (string), icon (QIcon), menu text (string), |
|
63 accelarator (QKeySequence), alternative accelerator |
|
64 (QKeySequence), parent (QObject), name (string)</li> |
|
65 <li>text (string), menu text (string), |
|
66 accelarator (QKeySequence), alternative accelerator |
|
67 (QKeySequence), parent (QObject), name (string), toggle |
|
68 (boolean)</li> |
|
69 <li>text (string), menu text (string), |
|
70 accelarator (QKeySequence), alternative accelerator |
|
71 (QKeySequence), parent (QObject), name (string)</li> |
|
72 </ul> |
|
73 @exception ArgumentsError raised to indicate invalid arguments |
|
74 """ |
|
75 if isinstance(args[1], QIcon): |
|
76 icon = args[1] |
|
77 incr = 1 |
|
78 else: |
|
79 icon = None |
|
80 incr = 0 |
|
81 if len(args) < 6 + incr: |
|
82 raise ArgumentsError( |
|
83 "Not enough arguments, {0:d} expected, got {1:d}".format( |
|
84 6 + incr, len(args))) |
|
85 elif len(args) > 7 + incr: |
|
86 raise ArgumentsError( |
|
87 "Too many arguments, max. {0:d} expected, got {1:d}".format( |
|
88 7 + incr, len(args))) |
|
89 |
|
90 parent = args[4 + incr] |
|
91 super().__init__(parent) |
|
92 name = args[5 + incr] |
|
93 if name: |
|
94 self.setObjectName(name) |
|
95 |
|
96 if args[1 + incr]: |
|
97 self.setText(args[1 + incr]) |
|
98 |
|
99 if args[0]: |
|
100 self.setIconText(args[0]) |
|
101 if args[2 + incr]: |
|
102 self.setShortcut(QKeySequence(args[2 + incr])) |
|
103 |
|
104 if args[3 + incr]: |
|
105 self.setAlternateShortcut(QKeySequence(args[3 + incr])) |
|
106 |
|
107 if icon: |
|
108 self.setIcon(icon) |
|
109 |
|
110 if len(args) == 7 + incr: |
|
111 self.setCheckable(args[6 + incr]) |
|
112 |
|
113 self.__ammendToolTip() |
|
114 |
|
115 def setAlternateShortcut(self, shortcut, removeEmpty=False): |
|
116 """ |
|
117 Public slot to set the alternative keyboard shortcut. |
|
118 |
|
119 @param shortcut the alternative accelerator (QKeySequence) |
|
120 @param removeEmpty flag indicating to remove the alternate shortcut, |
|
121 if it is empty (boolean) |
|
122 """ |
|
123 if not shortcut.isEmpty(): |
|
124 shortcuts = self.shortcuts() |
|
125 if len(shortcuts) > 0: |
|
126 if len(shortcuts) == 1: |
|
127 shortcuts.append(shortcut) |
|
128 else: |
|
129 shortcuts[1] = shortcut |
|
130 self.setShortcuts(shortcuts) |
|
131 elif removeEmpty: |
|
132 shortcuts = self.shortcuts() |
|
133 if len(shortcuts) == 2: |
|
134 del shortcuts[1] |
|
135 self.setShortcuts(shortcuts) |
|
136 |
|
137 def alternateShortcut(self): |
|
138 """ |
|
139 Public method to retrieve the alternative keyboard shortcut. |
|
140 |
|
141 @return the alternative accelerator (QKeySequence) |
|
142 """ |
|
143 shortcuts = self.shortcuts() |
|
144 if len(shortcuts) < 2: |
|
145 return QKeySequence() |
|
146 else: |
|
147 return shortcuts[1] |
|
148 |
|
149 def setShortcut(self, shortcut): |
|
150 """ |
|
151 Public slot to set the keyboard shortcut. |
|
152 |
|
153 @param shortcut the accelerator (QKeySequence) |
|
154 """ |
|
155 super().setShortcut(shortcut) |
|
156 self.__ammendToolTip() |
|
157 |
|
158 def setShortcuts(self, shortcuts): |
|
159 """ |
|
160 Public slot to set the list of keyboard shortcuts. |
|
161 |
|
162 @param shortcuts list of keyboard accelerators (list of QKeySequence) |
|
163 or key for a platform dependent list of accelerators |
|
164 (QKeySequence.StandardKey) |
|
165 """ |
|
166 super().setShortcuts(shortcuts) |
|
167 self.__ammendToolTip() |
|
168 |
|
169 def setIconText(self, text): |
|
170 """ |
|
171 Public slot to set the icon text of the action. |
|
172 |
|
173 @param text new icon text (string) |
|
174 """ |
|
175 super().setIconText(text) |
|
176 self.__ammendToolTip() |
|
177 |
|
178 def __ammendToolTip(self): |
|
179 """ |
|
180 Private slot to add the primary keyboard accelerator to the tooltip. |
|
181 """ |
|
182 shortcut = self.shortcut().toString( |
|
183 QKeySequence.SequenceFormat.NativeText) |
|
184 if shortcut: |
|
185 if e5App().isLeftToRight(): |
|
186 fmt = "{0} ({1})" |
|
187 else: |
|
188 fmt = "({1}) {0}" |
|
189 self.setToolTip(fmt.format(self.iconText(), shortcut)) |
|
190 |
|
191 |
|
192 def addActions(target, actions): |
|
193 """ |
|
194 Module function to add a list of actions to a widget. |
|
195 |
|
196 @param target reference to the target widget (QWidget) |
|
197 @param actions list of actions to be added to the target. A |
|
198 None indicates a separator (list of QActions) |
|
199 """ |
|
200 if target is None: |
|
201 return |
|
202 |
|
203 for action in actions: |
|
204 if action is None: |
|
205 target.addSeparator() |
|
206 else: |
|
207 target.addAction(action) |
|
208 |
|
209 |
|
210 def createActionGroup(parent, name=None, exclusive=False): |
|
211 """ |
|
212 Module function to create an action group. |
|
213 |
|
214 @param parent parent object of the action group (QObject) |
|
215 @param name name of the action group object (string) |
|
216 @param exclusive flag indicating an exclusive action group (boolean) |
|
217 @return reference to the created action group (QActionGroup) |
|
218 """ |
|
219 actGrp = QActionGroup(parent) |
|
220 if name: |
|
221 actGrp.setObjectName(name) |
|
222 actGrp.setExclusive(exclusive) |
|
223 return actGrp |
|