E5Gui/E5ToolBarDialog.py

changeset 55
b5c84934de9c
child 410
e5d1addeb90c
child 792
a13346916170
equal deleted inserted replaced
54:31463df17fd5 55:b5c84934de9c
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2008 - 2010 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a toolbar configuration dialog.
8 """
9
10 from PyQt4.QtGui import *
11 from PyQt4.QtCore import *
12
13 from .Ui_E5ToolBarDialog import Ui_E5ToolBarDialog
14
15 import UI.PixmapCache
16
17 class E5ToolBarItem(object):
18 """
19 Class storing data belonging to a toolbar entry of the toolbar dialog.
20 """
21 def __init__(self, toolBarId, actionIDs, default):
22 """
23 Constructor
24
25 @param toolBarId id of the toolbar object (integer)
26 @param actionIDs list of action IDs belonging to the toolbar (list of integer)
27 @param default flag indicating a default toolbar (boolean)
28 """
29 self.toolBarId = toolBarId
30 self.actionIDs = actionIDs[:]
31 self.isDefault = default
32 self.title = ""
33 self.isChanged = False
34
35 class E5ToolBarDialog(QDialog, Ui_E5ToolBarDialog):
36 """
37 Class implementing a toolbar configuration dialog.
38 """
39 ActionIdRole = Qt.UserRole
40 WidgetActionRole = Qt.UserRole + 1
41
42 def __init__(self, toolBarManager, parent = None):
43 """
44 Constructor
45
46 @param toolBarManager reference to a toolbar manager object (E5ToolBarManager)
47 @param parent reference to the parent widget (QWidget)
48 """
49 QDialog.__init__(self, parent)
50 self.setupUi(self)
51
52 self.__manager = toolBarManager
53 self.__toolbarItems = {} # maps toolbar item IDs to toolbar items
54 self.__currentToolBarItem = None
55 self.__removedToolBarIDs = [] # remember custom toolbars to be deleted
56
57 self.__widgetActionToToolBarItemID = {} # maps widget action IDs to toolbar item IDs
58 self.__toolBarItemToWidgetActionID = {} # maps toolbar item IDs to widget action IDs
59
60 self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow.png"))
61 self.downButton.setIcon(UI.PixmapCache.getIcon("1downarrow.png"))
62 self.leftButton.setIcon(UI.PixmapCache.getIcon("1leftarrow.png"))
63 self.rightButton.setIcon(UI.PixmapCache.getIcon("1rightarrow.png"))
64
65 self.__restoreDefaultsButton = \
66 self.buttonBox.button(QDialogButtonBox.RestoreDefaults)
67 self.__resetButton = self.buttonBox.button(QDialogButtonBox.Reset)
68
69 self.actionsTree.header().hide()
70 self.__separatorText = self.trUtf8("--Separator--")
71 itm = QTreeWidgetItem(self.actionsTree, [self.__separatorText])
72 self.actionsTree.setCurrentItem(itm)
73
74 for category in sorted(self.__manager.categories()):
75 categoryItem = QTreeWidgetItem(self.actionsTree, [category])
76 for action in self.__manager.categoryActions(category):
77 item = QTreeWidgetItem(categoryItem)
78 item.setText(0, action.text())
79 item.setIcon(0, action.icon())
80 item.setTextAlignment(0, Qt.AlignLeft | Qt.AlignVCenter)
81 item.setData(0, E5ToolBarDialog.ActionIdRole, int(id(action)))
82 item.setData(0, E5ToolBarDialog.WidgetActionRole, False)
83 if self.__manager.isWidgetAction(action):
84 item.setData(0, E5ToolBarDialog.WidgetActionRole, True)
85 item.setData(0, Qt.TextColorRole, QColor(Qt.blue))
86 self.__widgetActionToToolBarItemID[id(action)] = None
87 categoryItem.setExpanded(True)
88
89 for tbID, actions in list(self.__manager.toolBarsActions().items()):
90 tb = self.__manager.toolBarById(tbID)
91 default = self.__manager.isDefaultToolBar(tb)
92 tbItem = E5ToolBarItem(tbID, [], default)
93 self.__toolbarItems[id(tbItem)] = tbItem
94 self.__toolBarItemToWidgetActionID[id(tbItem)] = []
95 actionIDs = []
96 for action in actions:
97 if action is None:
98 actionIDs.append(None)
99 else:
100 aID = id(action)
101 actionIDs.append(aID)
102 if aID in self.__widgetActionToToolBarItemID:
103 self.__widgetActionToToolBarItemID[aID] = id(tbItem)
104 self.__toolBarItemToWidgetActionID[id(tbItem)].append(aID)
105 tbItem.actionIDs = actionIDs
106 self.toolbarComboBox.addItem(tb.windowTitle(), int(id(tbItem)))
107 if default:
108 self.toolbarComboBox.setItemData(self.toolbarComboBox.count() - 1,
109 QColor(Qt.darkGreen), Qt.ForegroundRole)
110 self.toolbarComboBox.model().sort(0)
111
112 self.connect(self.toolbarComboBox, SIGNAL("currentIndexChanged(int)"),
113 self.__toolbarComboBox_currentIndexChanged)
114 self.toolbarComboBox.setCurrentIndex(0)
115
116 @pyqtSlot()
117 def on_newButton_clicked(self):
118 """
119 Private slot to create a new toolbar.
120 """
121 name, ok = QInputDialog.getText(\
122 self,
123 self.trUtf8("New Toolbar"),
124 self.trUtf8("Toolbar Name:"),
125 QLineEdit.Normal)
126 if ok and name:
127 if self.toolbarComboBox.findText(name) != -1:
128 # toolbar with this name already exists
129 QMessageBox.critical(self,
130 self.trUtf8("New Toolbar"),
131 self.trUtf8("""A toolbar with the name <b>{0}</b> already exists.""")\
132 .format(name),
133 QMessageBox.StandardButtons(\
134 QMessageBox.Abort))
135 return
136
137 tbItem = E5ToolBarItem(None, [], False)
138 tbItem.title = name
139 tbItem.isChanged = True
140 self.__toolbarItems[id(tbItem)] = tbItem
141 self.__toolBarItemToWidgetActionID[id(tbItem)] = []
142 self.toolbarComboBox.addItem(name, int(id(tbItem)))
143 self.toolbarComboBox.model().sort(0)
144 self.toolbarComboBox.setCurrentIndex(self.toolbarComboBox.findText(name))
145
146 @pyqtSlot()
147 def on_removeButton_clicked(self):
148 """
149 Private slot to remove a custom toolbar
150 """
151 name = self.toolbarComboBox.currentText()
152 res = QMessageBox.question(self,
153 self.trUtf8("Remove Toolbar"),
154 self.trUtf8("""Should the toolbar <b>{0}</b> really be removed?""")\
155 .format(name),
156 QMessageBox.StandardButtons(\
157 QMessageBox.No | \
158 QMessageBox.Yes),
159 QMessageBox.No)
160 if res == QMessageBox.Yes:
161 index = self.toolbarComboBox.currentIndex()
162 tbItemID = self.toolbarComboBox.itemData(index)
163 tbItem = self.__toolbarItems[tbItemID]
164 if tbItem.toolBarId is not None and \
165 tbItem.toolBarId not in self.__removedToolBarIDs:
166 self.__removedToolBarIDs.append(tbItem.toolBarId)
167 del self.__toolbarItems[tbItemID]
168 for widgetActionID in self.__toolBarItemToWidgetActionID[tbItemID]:
169 self.__widgetActionToToolBarItemID[widgetActionID] = None
170 del self.__toolBarItemToWidgetActionID[tbItemID]
171 self.toolbarComboBox.removeItem(index)
172
173 @pyqtSlot()
174 def on_renameButton_clicked(self):
175 """
176 Private slot to rename a custom toolbar.
177 """
178 oldName = self.toolbarComboBox.currentText()
179 newName, ok = QInputDialog.getText(\
180 self,
181 self.trUtf8("Rename Toolbar"),
182 self.trUtf8("New Toolbar Name:"),
183 QLineEdit.Normal,
184 oldName)
185 if ok and newName:
186 if oldName == newName:
187 return
188 if self.toolbarComboBox.findText(newName) != -1:
189 # toolbar with this name already exists
190 QMessageBox.critical(self,
191 self.trUtf8("Rename Toolbar"),
192 self.trUtf8("""A toolbar with the name <b>{0}</b> already exists.""")\
193 .format(newName),
194 QMessageBox.StandardButtons(\
195 QMessageBox.Abort))
196 return
197 index = self.toolbarComboBox.currentIndex()
198 self.toolbarComboBox.setItemText(index, newName)
199 tbItem = \
200 self.__toolbarItems[self.toolbarComboBox.itemData(index)]
201 tbItem.title = newName
202 tbItem.isChanged = True
203
204 def __setupButtons(self):
205 """
206 Private slot to set the buttons state.
207 """
208 index = self.toolbarComboBox.currentIndex()
209 if index > -1:
210 itemID = self.toolbarComboBox.itemData(index)
211 self.__currentToolBarItem = self.__toolbarItems[itemID]
212 self.renameButton.setEnabled(not self.__currentToolBarItem.isDefault)
213 self.removeButton.setEnabled(not self.__currentToolBarItem.isDefault)
214 self.__restoreDefaultsButton.setEnabled(self.__currentToolBarItem.isDefault)
215 self.__resetButton.setEnabled(self.__currentToolBarItem.toolBarId is not None)
216
217 row = self.toolbarActionsList.currentRow()
218 self.upButton.setEnabled(row > 0)
219 self.downButton.setEnabled(row < self.toolbarActionsList.count() - 1)
220 self.leftButton.setEnabled(self.toolbarActionsList.count() > 0)
221 rightEnable = self.actionsTree.currentItem().parent() is not None or \
222 self.actionsTree.currentItem().text(0) == self.__separatorText
223 self.rightButton.setEnabled(rightEnable)
224
225 @pyqtSlot(int)
226 def __toolbarComboBox_currentIndexChanged(self, index):
227 """
228 Private slot called upon a selection of the current toolbar.
229
230 @param index index of the new current toolbar (integer)
231 """
232 itemID = self.toolbarComboBox.itemData(index)
233 self.__currentToolBarItem = self.__toolbarItems[itemID]
234 self.toolbarActionsList.clear()
235 for actionID in self.__currentToolBarItem.actionIDs:
236 item = QListWidgetItem(self.toolbarActionsList)
237 if actionID is None:
238 item.setText(self.__separatorText)
239 else:
240 action = self.__manager.actionById(actionID)
241 item.setText(action.text())
242 item.setIcon(action.icon())
243 item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter)
244 item.setData(E5ToolBarDialog.ActionIdRole, int(id(action)))
245 item.setData(E5ToolBarDialog.WidgetActionRole, False)
246 if self.__manager.isWidgetAction(action):
247 item.setData(E5ToolBarDialog.WidgetActionRole, True)
248 item.setData(Qt.TextColorRole, QColor(Qt.blue))
249 self.toolbarActionsList.setCurrentRow(0)
250
251 self.__setupButtons()
252
253 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
254 def on_actionsTree_currentItemChanged(self, current, previous):
255 """
256 Private slot called, when the currently selected action changes.
257 """
258 self.__setupButtons()
259
260 @pyqtSlot(QListWidgetItem, QListWidgetItem)
261 def on_toolbarActionsList_currentItemChanged(self, current, previous):
262 """
263 Slot documentation goes here.
264 """
265 self.__setupButtons()
266
267 @pyqtSlot()
268 def on_upButton_clicked(self):
269 """
270 Private slot used to move an action up in the list.
271 """
272 row = self.toolbarActionsList.currentRow()
273 if row == 0:
274 # we're already at the top
275 return
276
277 actionID = self.__currentToolBarItem.actionIDs.pop(row)
278 self.__currentToolBarItem.actionIDs.insert(row - 1, actionID)
279 self.__currentToolBarItem.isChanged = True
280 itm = self.toolbarActionsList.takeItem(row)
281 self.toolbarActionsList.insertItem(row - 1, itm)
282 self.toolbarActionsList.setCurrentItem(itm)
283 self.__setupButtons()
284
285 @pyqtSlot()
286 def on_downButton_clicked(self):
287 """
288 Private slot used to move an action down in the list.
289 """
290 row = self.toolbarActionsList.currentRow()
291 if row == self.toolbarActionsList.count() - 1:
292 # we're already at the end
293 return
294
295 actionID = self.__currentToolBarItem.actionIDs.pop(row)
296 self.__currentToolBarItem.actionIDs.insert(row + 1, actionID)
297 self.__currentToolBarItem.isChanged = True
298 itm = self.toolbarActionsList.takeItem(row)
299 self.toolbarActionsList.insertItem(row + 1, itm)
300 self.toolbarActionsList.setCurrentItem(itm)
301 self.__setupButtons()
302
303 @pyqtSlot()
304 def on_leftButton_clicked(self):
305 """
306 Private slot to delete an action from the list.
307 """
308 row = self.toolbarActionsList.currentRow()
309 actionID = self.__currentToolBarItem.actionIDs.pop(row)
310 self.__currentToolBarItem.isChanged = True
311 if actionID in self.__widgetActionToToolBarItemID:
312 self.__widgetActionToToolBarItemID[actionID] = None
313 self.__toolBarItemToWidgetActionID[id(self.__currentToolBarItem)]\
314 .remove(actionID)
315 itm = self.toolbarActionsList.takeItem(row)
316 del itm
317 self.toolbarActionsList.setCurrentRow(row)
318 self.__setupButtons()
319
320 @pyqtSlot()
321 def on_rightButton_clicked(self):
322 """
323 Private slot to add an action to the list.
324 """
325 row = self.toolbarActionsList.currentRow() + 1
326
327 item = QListWidgetItem()
328 if self.actionsTree.currentItem().text(0) == self.__separatorText:
329 item.setText(self.__separatorText)
330 actionID = None
331 else:
332 actionID = self.actionsTree.currentItem()\
333 .data(0, E5ToolBarDialog.ActionIdRole)
334 action = self.__manager.actionById(actionID)
335 item.setText(action.text())
336 item.setIcon(action.icon())
337 item.setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter)
338 item.setData(E5ToolBarDialog.ActionIdRole, int(id(action)))
339 item.setData(E5ToolBarDialog.WidgetActionRole, False)
340 if self.__manager.isWidgetAction(action):
341 item.setData(E5ToolBarDialog.WidgetActionRole, True)
342 item.setData(Qt.TextColorRole, QColor(Qt.blue))
343 oldTbItemID = self.__widgetActionToToolBarItemID[actionID]
344 if oldTbItemID is not None:
345 self.__toolbarItems[oldTbItemID].actionIDs.remove(actionID)
346 self.__toolbarItems[oldTbItemID].isChanged = True
347 self.__toolBarItemToWidgetActionID[oldTbItemID].remove(actionID)
348 self.__widgetActionToToolBarItemID[actionID] = \
349 id(self.__currentToolBarItem)
350 self.__toolBarItemToWidgetActionID[id(self.__currentToolBarItem)]\
351 .append(actionID)
352 self.toolbarActionsList.insertItem(row, item)
353 self.__currentToolBarItem.actionIDs.insert(row, actionID)
354 self.__currentToolBarItem.isChanged = True
355 self.toolbarActionsList.setCurrentRow(row)
356 self.__setupButtons()
357
358 @pyqtSlot(QAbstractButton)
359 def on_buttonBox_clicked(self, button):
360 """
361 Private slot called, when a button of the button box was clicked.
362 """
363 if button == self.buttonBox.button(QDialogButtonBox.Cancel):
364 self.reject()
365 elif button == self.buttonBox.button(QDialogButtonBox.Apply):
366 self.__saveToolBars()
367 self.__setupButtons()
368 elif button == self.buttonBox.button(QDialogButtonBox.Ok):
369 self.__saveToolBars()
370 self.accept()
371 elif button == self.buttonBox.button(QDialogButtonBox.Reset):
372 self.__resetCurrentToolbar()
373 self.__setupButtons()
374 elif button == self.buttonBox.button(QDialogButtonBox.RestoreDefaults):
375 self.__restoreCurrentToolbarToDefault()
376 self.__setupButtons()
377
378 def __saveToolBars(self):
379 """
380 Private method to save the configured toolbars.
381 """
382 # step 1: remove toolbars marked for deletion
383 for tbID in self.__removedToolBarIDs:
384 tb = self.__manager.toolBarById(tbID)
385 self.__manager.deleteToolBar(tb)
386 self.__removedToolBarIDs = []
387
388 # step 2: save configured toolbars
389 for tbItem in list(self.__toolbarItems.values()):
390 if not tbItem.isChanged:
391 continue
392
393 if tbItem.toolBarId is None:
394 # new custom toolbar
395 tb = self.__manager.createToolBar(tbItem.title)
396 tbItem.toolBarId = id(tb)
397 else:
398 tb = self.__manager.toolBarById(tbItem.toolBarId)
399 if not tbItem.isDefault and tbItem.title:
400 self.__manager.renameToolBar(tb, tbItem.title)
401
402 actions = []
403 for actionID in tbItem.actionIDs:
404 if actionID is None:
405 actions.append(None)
406 else:
407 action = self.__manager.actionById(actionID)
408 if action is None:
409 raise RuntimeError("No such action, id: 0x%x" % actionID)
410 actions.append(action)
411 self.__manager.setToolBar(tb, actions)
412 tbItem.isChanged = False
413
414 def __restoreCurrentToolbar(self, actions):
415 """
416 Private methdo to restore the current toolbar to the given list of actions.
417
418 @param actions list of actions to set for the current toolbar (list of QAction)
419 """
420 tbItemID = id(self.__currentToolBarItem)
421 for widgetActionID in self.__toolBarItemToWidgetActionID[tbItemID]:
422 self.__widgetActionToToolBarItemID[widgetActionID] = None
423 self.__toolBarItemToWidgetActionID[tbItemID] = []
424 self.__currentToolBarItem.actionIDs = []
425
426 for action in actions:
427 if action is None:
428 self.__currentToolBarItem.actionIDs.append(None)
429 else:
430 actionID = id(action)
431 self.__currentToolBarItem.actionIDs.append(actionID)
432 if actionID in self.__widgetActionToToolBarItemID:
433 oldTbItemID = self.__widgetActionToToolBarItemID[actionID]
434 if oldTbItemID is not None:
435 self.__toolbarItems[oldTbItemID].actionIDs.remove(actionID)
436 self.__toolbarItems[oldTbItemID].isChanged = True
437 self.__toolBarItemToWidgetActionID[oldTbItemID].remove(actionID)
438 self.__widgetActionToToolBarItemID[actionID] = tbItemID
439 self.__toolBarItemToWidgetActionID[tbItemID].append(actionID)
440 self.__toolbarComboBox_currentIndexChanged(self.toolbarComboBox.currentIndex())
441
442 def __resetCurrentToolbar(self):
443 """
444 Private method to revert all changes made to the current toolbar.
445 """
446 tbID = self.__currentToolBarItem.toolBarId
447 actions = self.__manager.toolBarActions(tbID)
448 self.__restoreCurrentToolbar(actions)
449 self.__currentToolBarItem.isChanged = False
450
451 def __restoreCurrentToolbarToDefault(self):
452 """
453 Private method to set the current toolbar to it's default configuration.
454 """
455 if not self.__currentToolBarItem.isDefault:
456 return
457
458 tbID = self.__currentToolBarItem.toolBarId
459 actions = self.__manager.defaultToolBarActions(tbID)
460 self.__restoreCurrentToolbar(actions)
461 self.__currentToolBarItem.isChanged = True

eric ide

mercurial