|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2002 - 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the baseclass for the various project browsers. |
|
8 """ |
|
9 |
|
10 import os |
|
11 import sys |
|
12 |
|
13 from PyQt4.QtCore import * |
|
14 from PyQt4.QtGui import * |
|
15 |
|
16 from E4Gui.E4Application import e4App |
|
17 |
|
18 from UI.Browser import * |
|
19 |
|
20 from ProjectBrowserModel import * |
|
21 from ProjectBrowserSortFilterProxyModel import ProjectBrowserSortFilterProxyModel |
|
22 |
|
23 import UI.PixmapCache |
|
24 import Preferences |
|
25 |
|
26 class ProjectBaseBrowser(Browser): |
|
27 """ |
|
28 Baseclass implementing common functionality for the various project browsers. |
|
29 """ |
|
30 def __init__(self, project, type_, parent = None): |
|
31 """ |
|
32 Constructor |
|
33 |
|
34 @param project reference to the project object |
|
35 @param type project browser type (string) |
|
36 @param parent parent widget of this browser |
|
37 """ |
|
38 QTreeView.__init__(self, parent) |
|
39 |
|
40 self.project = project |
|
41 |
|
42 self._model = project.getModel() |
|
43 self._sortModel = ProjectBrowserSortFilterProxyModel(type_) |
|
44 self._sortModel.setSourceModel(self._model) |
|
45 self.setModel(self._sortModel) |
|
46 |
|
47 self.selectedItemsFilter = [ProjectBrowserFileItem] |
|
48 |
|
49 # contains codes for special menu entries |
|
50 # 1 = specials for Others browser |
|
51 self.specialMenuEntries = [] |
|
52 self.isTranslationsBrowser = False |
|
53 self.expandedNames = [] |
|
54 |
|
55 self.SelectFlags = QItemSelectionModel.SelectionFlags(\ |
|
56 QItemSelectionModel.Select | QItemSelectionModel.Rows) |
|
57 self.DeselectFlags = QItemSelectionModel.SelectionFlags(\ |
|
58 QItemSelectionModel.Deselect | QItemSelectionModel.Rows) |
|
59 |
|
60 self.setContextMenuPolicy(Qt.CustomContextMenu) |
|
61 self.connect(self, SIGNAL("customContextMenuRequested(const QPoint &)"), |
|
62 self._contextMenuRequested) |
|
63 self.connect(self, SIGNAL("activated(const QModelIndex &)"), self._openItem) |
|
64 self.connect(self._model, SIGNAL("rowsInserted(const QModelIndex &, int, int)"), |
|
65 self.__modelRowsInserted) |
|
66 self._connectExpandedCollapsed() |
|
67 |
|
68 self._createPopupMenus() |
|
69 |
|
70 self.currentItemName = None |
|
71 |
|
72 self._init() # perform common initialization tasks |
|
73 |
|
74 self._initHookMethods() # perform initialization of the hooks |
|
75 self.hooksMenuEntries = {} |
|
76 |
|
77 def _connectExpandedCollapsed(self): |
|
78 """ |
|
79 Protected method to connect the expanded and collapsed signals. |
|
80 """ |
|
81 self.connect(self, SIGNAL("expanded(const QModelIndex &)"), |
|
82 self._resizeColumns) |
|
83 self.connect(self, SIGNAL("collapsed(const QModelIndex &)"), |
|
84 self._resizeColumns) |
|
85 |
|
86 def _disconnectExpandedCollapsed(self): |
|
87 """ |
|
88 Protected method to disconnect the expanded and collapsed signals. |
|
89 """ |
|
90 self.disconnect(self, SIGNAL("expanded(const QModelIndex &)"), |
|
91 self._resizeColumns) |
|
92 self.disconnect(self, SIGNAL("collapsed(const QModelIndex &)"), |
|
93 self._resizeColumns) |
|
94 |
|
95 def _createPopupMenus(self): |
|
96 """ |
|
97 Protected overloaded method to generate the popup menus. |
|
98 """ |
|
99 # create the popup menu for source files |
|
100 self.sourceMenu = QMenu(self) |
|
101 self.sourceMenu.addAction( |
|
102 QApplication.translate('ProjectBaseBrowser', 'Open'), |
|
103 self._openItem) |
|
104 |
|
105 # create the popup menu for general use |
|
106 self.menu = QMenu(self) |
|
107 self.menu.addAction( |
|
108 QApplication.translate('ProjectBaseBrowser', 'Open'), |
|
109 self._openItem) |
|
110 |
|
111 # create the menu for multiple selected files |
|
112 self.multiMenu = QMenu(self) |
|
113 self.multiMenu.addAction(QApplication.translate('ProjectBaseBrowser', 'Open'), |
|
114 self._openItem) |
|
115 |
|
116 # create the background menu |
|
117 self.backMenu = None |
|
118 |
|
119 # create the directories menu |
|
120 self.dirMenu = None |
|
121 |
|
122 # create the directory for multiple selected directories |
|
123 self.dirMultiMenu = None |
|
124 |
|
125 self.menuActions = [] |
|
126 self.multiMenuActions = [] |
|
127 self.dirMenuActions = [] |
|
128 self.dirMultiMenuActions = [] |
|
129 |
|
130 self.mainMenu = None |
|
131 |
|
132 def _contextMenuRequested(self, coord): |
|
133 """ |
|
134 Protected slot to show the context menu. |
|
135 |
|
136 @param coord the position of the mouse pointer (QPoint) |
|
137 """ |
|
138 if not self.project.isOpen(): |
|
139 return |
|
140 |
|
141 cnt = self.getSelectedItemsCount() |
|
142 if cnt > 1: |
|
143 self.multiMenu.popup(self.mapToGlobal(coord)) |
|
144 else: |
|
145 index = self.indexAt(coord) |
|
146 |
|
147 if index.isValid(): |
|
148 self.menu.popup(self.mapToGlobal(coord)) |
|
149 else: |
|
150 self.backMenu and self.backMenu.popup(self.mapToGlobal(coord)) |
|
151 |
|
152 def _selectSingleItem(self, index): |
|
153 """ |
|
154 Protected method to select a single item. |
|
155 |
|
156 @param index index of item to be selected (QModelIndex) |
|
157 """ |
|
158 if index.isValid(): |
|
159 self.setCurrentIndex(index) |
|
160 flags = QItemSelectionModel.SelectionFlags(\ |
|
161 QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) |
|
162 self.selectionModel().select(index, flags) |
|
163 |
|
164 def _setItemSelected(self, index, selected): |
|
165 """ |
|
166 Protected method to set the selection status of an item. |
|
167 |
|
168 @param index index of item to set (QModelIndex) |
|
169 @param selected flag giving the new selection status (boolean) |
|
170 """ |
|
171 if index.isValid(): |
|
172 self.selectionModel().select(index, |
|
173 selected and self.SelectFlags or self.DeselectFlags) |
|
174 |
|
175 def _setItemRangeSelected(self, startIndex, endIndex, selected): |
|
176 """ |
|
177 Protected method to set the selection status of a range of items. |
|
178 |
|
179 @param startIndex start index of range of items to set (QModelIndex) |
|
180 @param endIndex end index of range of items to set (QModelIndex) |
|
181 @param selected flag giving the new selection status (boolean) |
|
182 """ |
|
183 selection = QItemSelection(startIndex, endIndex) |
|
184 self.selectionModel().select(selection, |
|
185 selected and self.SelectFlags or self.DeselectFlags) |
|
186 |
|
187 def __modelRowsInserted(self, parent, start, end): |
|
188 """ |
|
189 Private slot called after rows have been inserted into the model. |
|
190 |
|
191 @param parent parent index of inserted rows (QModelIndex) |
|
192 @param start start row number (integer) |
|
193 @param end end row number (integer) |
|
194 """ |
|
195 self._resizeColumns(parent) |
|
196 |
|
197 def __modelDataChanged(self, startIndex, endIndex): |
|
198 """ |
|
199 Private slot called after data has been changed in the model. |
|
200 |
|
201 @param startIndex start index of the changed data (QModelIndex) |
|
202 @param endIndex end index of the changed data (QModelIndex) |
|
203 """ |
|
204 self._resizeColumns(startIndex) |
|
205 |
|
206 def _projectClosed(self): |
|
207 """ |
|
208 Protected slot to handle the projectClosed signal. |
|
209 """ |
|
210 self.layoutDisplay() |
|
211 if self.backMenu is not None: |
|
212 self.backMenu.setEnabled(False) |
|
213 |
|
214 self._createPopupMenus() |
|
215 |
|
216 def _projectOpened(self): |
|
217 """ |
|
218 Protected slot to handle the projectOpened signal. |
|
219 """ |
|
220 self.layoutDisplay() |
|
221 self.sortByColumn(0, Qt.DescendingOrder) |
|
222 self.sortByColumn(0, Qt.AscendingOrder) |
|
223 self._initMenusAndVcs() |
|
224 |
|
225 def _initMenusAndVcs(self): |
|
226 """ |
|
227 Protected slot to initialize the menus and the Vcs interface. |
|
228 """ |
|
229 self._createPopupMenus() |
|
230 |
|
231 if self.backMenu is not None: |
|
232 self.backMenu.setEnabled(True) |
|
233 |
|
234 if self.project.vcs is not None: |
|
235 self.vcsHelper = self.project.vcs.vcsGetProjectBrowserHelper(self, |
|
236 self.project, self.isTranslationsBrowser) |
|
237 self.vcsHelper.addVCSMenus(self.mainMenu, self.multiMenu, |
|
238 self.backMenu, self.dirMenu, self.dirMultiMenu) |
|
239 |
|
240 def _newProject(self): |
|
241 """ |
|
242 Protected slot to handle the newProject signal. |
|
243 """ |
|
244 self.layoutDisplay() |
|
245 self.sortByColumn(0, Qt.DescendingOrder) |
|
246 self.sortByColumn(0, Qt.AscendingOrder) |
|
247 |
|
248 self._createPopupMenus() |
|
249 |
|
250 if self.backMenu is not None: |
|
251 self.backMenu.setEnabled(True) |
|
252 |
|
253 if self.project.vcs is not None: |
|
254 self.vcsHelper = self.project.vcs.vcsGetProjectBrowserHelper(self, |
|
255 self.project, self.isTranslationsBrowser) |
|
256 self.vcsHelper.addVCSMenus(self.mainMenu, self.multiMenu, |
|
257 self.backMenu, self.dirMenu, self.dirMultiMenu) |
|
258 |
|
259 def _removeFile(self): |
|
260 """ |
|
261 Protected method to remove a file or files from the project. |
|
262 """ |
|
263 itmList = self.getSelectedItems() |
|
264 |
|
265 for itm in itmList[:]: |
|
266 fn = itm.fileName() |
|
267 self.emit(SIGNAL('closeSourceWindow'), fn) |
|
268 self.project.removeFile(fn) |
|
269 |
|
270 def _removeDir(self): |
|
271 """ |
|
272 Protected method to remove a (single) directory from the project. |
|
273 """ |
|
274 itmList = self.getSelectedItems(\ |
|
275 [ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem]) |
|
276 for itm in itmList[:]: |
|
277 dn = itm.dirName() |
|
278 self.project.removeDirectory(dn) |
|
279 |
|
280 def _renameFile(self): |
|
281 """ |
|
282 Protected method to rename a file of the project. |
|
283 """ |
|
284 itm = self.model().item(self.currentIndex()) |
|
285 fn = itm.fileName() |
|
286 self.project.renameFile(fn) |
|
287 |
|
288 def _copyToClipboard(self): |
|
289 """ |
|
290 Protected method to copy the path of an entry to the clipboard. |
|
291 """ |
|
292 itm = self.model().item(self.currentIndex()) |
|
293 try: |
|
294 fn = itm.fileName() |
|
295 except AttributeError: |
|
296 try: |
|
297 fn = itm.dirName() |
|
298 except AttributeError: |
|
299 fn = "" |
|
300 |
|
301 cb = QApplication.clipboard() |
|
302 cb.setText(fn) |
|
303 |
|
304 def selectFile(self, fn): |
|
305 """ |
|
306 Public method to highlight a node given its filename. |
|
307 |
|
308 @param fn filename of file to be highlighted (string) |
|
309 """ |
|
310 newfn = os.path.abspath(fn) |
|
311 newfn = newfn.replace(self.project.ppath + os.sep, '') |
|
312 sindex = self._model.itemIndexByName(newfn) |
|
313 if sindex.isValid(): |
|
314 index = self.model().mapFromSource(sindex) |
|
315 if index.isValid(): |
|
316 self._selectSingleItem(index) |
|
317 self.scrollTo(index, QAbstractItemView.PositionAtTop) |
|
318 |
|
319 def _expandAllDirs(self): |
|
320 """ |
|
321 Protected slot to handle the 'Expand all directories' menu action. |
|
322 """ |
|
323 self._disconnectExpandedCollapsed() |
|
324 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
|
325 QApplication.processEvents() |
|
326 index = self.model().index(0, 0) |
|
327 while index.isValid(): |
|
328 itm = self.model().item(index) |
|
329 if (isinstance(itm, ProjectBrowserSimpleDirectoryItem) or \ |
|
330 isinstance(itm, ProjectBrowserDirectoryItem)) and \ |
|
331 not self.isExpanded(index): |
|
332 self.expand(index) |
|
333 index = self.indexBelow(index) |
|
334 self.layoutDisplay() |
|
335 self._connectExpandedCollapsed() |
|
336 QApplication.restoreOverrideCursor() |
|
337 |
|
338 def _collapseAllDirs(self): |
|
339 """ |
|
340 Protected slot to handle the 'Collapse all directories' menu action. |
|
341 """ |
|
342 self._disconnectExpandedCollapsed() |
|
343 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
|
344 QApplication.processEvents() |
|
345 # step 1: find last valid index |
|
346 vindex = QModelIndex() |
|
347 index = self.model().index(0, 0) |
|
348 while index.isValid(): |
|
349 vindex = index |
|
350 index = self.indexBelow(index) |
|
351 |
|
352 # step 2: go up collapsing all directory items |
|
353 index = vindex |
|
354 while index.isValid(): |
|
355 itm = self.model().item(index) |
|
356 if (isinstance(itm, ProjectBrowserSimpleDirectoryItem) or \ |
|
357 isinstance(itm, ProjectBrowserDirectoryItem)) and \ |
|
358 self.isExpanded(index): |
|
359 self.collapse(index) |
|
360 index = self.indexAbove(index) |
|
361 self.layoutDisplay() |
|
362 self._connectExpandedCollapsed() |
|
363 QApplication.restoreOverrideCursor() |
|
364 |
|
365 def _showContextMenu(self, menu): |
|
366 """ |
|
367 Protected slot called before the context menu is shown. |
|
368 |
|
369 It enables/disables the VCS menu entries depending on the overall |
|
370 VCS status and the file status. |
|
371 |
|
372 @param menu reference to the menu to be shown (QMenu) |
|
373 """ |
|
374 if self.project.vcs is None: |
|
375 for act in self.menuActions: |
|
376 act.setEnabled(True) |
|
377 else: |
|
378 self.vcsHelper.showContextMenu(menu, self.menuActions) |
|
379 |
|
380 def _showContextMenuMulti(self, menu): |
|
381 """ |
|
382 Protected slot called before the context menu (multiple selections) is shown. |
|
383 |
|
384 It enables/disables the VCS menu entries depending on the overall |
|
385 VCS status and the files status. |
|
386 |
|
387 @param menu reference to the menu to be shown (QMenu) |
|
388 """ |
|
389 if self.project.vcs is None: |
|
390 for act in self.multiMenuActions: |
|
391 act.setEnabled(True) |
|
392 else: |
|
393 self.vcsHelper.showContextMenuMulti(menu, self.multiMenuActions) |
|
394 |
|
395 def _showContextMenuDir(self, menu): |
|
396 """ |
|
397 Protected slot called before the context menu is shown. |
|
398 |
|
399 It enables/disables the VCS menu entries depending on the overall |
|
400 VCS status and the directory status. |
|
401 |
|
402 @param menu reference to the menu to be shown (QMenu) |
|
403 """ |
|
404 if self.project.vcs is None: |
|
405 for act in self.dirMenuActions: |
|
406 act.setEnabled(True) |
|
407 else: |
|
408 self.vcsHelper.showContextMenuDir(menu, self.dirMenuActions) |
|
409 |
|
410 def _showContextMenuDirMulti(self, menu): |
|
411 """ |
|
412 Protected slot called before the context menu is shown. |
|
413 |
|
414 It enables/disables the VCS menu entries depending on the overall |
|
415 VCS status and the directory status. |
|
416 |
|
417 @param menu reference to the menu to be shown (QMenu) |
|
418 """ |
|
419 if self.project.vcs is None: |
|
420 for act in self.dirMultiMenuActions: |
|
421 act.setEnabled(True) |
|
422 else: |
|
423 self.vcsHelper.showContextMenuDirMulti(menu, self.dirMultiMenuActions) |
|
424 |
|
425 def _showContextMenuBack(self, menu): |
|
426 """ |
|
427 Protected slot called before the context menu is shown. |
|
428 |
|
429 @param menu reference to the menu to be shown (QMenu) |
|
430 """ |
|
431 # nothing to do for now |
|
432 return |
|
433 |
|
434 def _selectEntries(self, local = True, filter = None): |
|
435 """ |
|
436 Protected method to select entries based on their VCS status. |
|
437 |
|
438 @param local flag indicating local (i.e. non VCS controlled) file/directory |
|
439 entries should be selected (boolean) |
|
440 @param filter list of classes to check against |
|
441 """ |
|
442 if self.project.vcs is None: |
|
443 return |
|
444 |
|
445 if local: |
|
446 compareString = QApplication.translate('ProjectBaseBrowser', "local") |
|
447 else: |
|
448 compareString = self.project.vcs.vcsName() |
|
449 |
|
450 # expand all directories in order to iterate over all entries |
|
451 self._expandAllDirs() |
|
452 |
|
453 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
|
454 QApplication.processEvents() |
|
455 self.selectionModel().clear() |
|
456 QApplication.processEvents() |
|
457 |
|
458 # now iterate over all entries |
|
459 startIndex = None |
|
460 endIndex = None |
|
461 selectedEntries = 0 |
|
462 index = self.model().index(0, 0) |
|
463 while index.isValid(): |
|
464 itm = self.model().item(index) |
|
465 if self.wantedItem(itm, filter) and \ |
|
466 compareString == itm.data(1): |
|
467 if startIndex is not None and \ |
|
468 startIndex.parent() != index.parent(): |
|
469 self._setItemRangeSelected(startIndex, endIndex, True) |
|
470 startIndex = None |
|
471 selectedEntries += 1 |
|
472 if startIndex is None: |
|
473 startIndex = index |
|
474 endIndex = index |
|
475 else: |
|
476 if startIndex is not None: |
|
477 self._setItemRangeSelected(startIndex, endIndex, True) |
|
478 startIndex = None |
|
479 index = self.indexBelow(index) |
|
480 if startIndex is not None: |
|
481 self._setItemRangeSelected(startIndex, endIndex, True) |
|
482 QApplication.restoreOverrideCursor() |
|
483 QApplication.processEvents() |
|
484 |
|
485 if selectedEntries == 0: |
|
486 QMessageBox.information(None, |
|
487 QApplication.translate('ProjectBaseBrowser', "Select entries"), |
|
488 QApplication.translate('ProjectBaseBrowser', |
|
489 """There were no matching entries found.""")) |
|
490 |
|
491 def selectLocalEntries(self): |
|
492 """ |
|
493 Public slot to handle the select local files context menu entries |
|
494 """ |
|
495 self._selectEntries(local = True, filter = [ProjectBrowserFileItem]) |
|
496 |
|
497 def selectVCSEntries(self): |
|
498 """ |
|
499 Public slot to handle the select VCS files context menu entries |
|
500 """ |
|
501 self._selectEntries(local = False, filter = [ProjectBrowserFileItem]) |
|
502 |
|
503 def selectLocalDirEntries(self): |
|
504 """ |
|
505 Public slot to handle the select local directories context menu entries |
|
506 """ |
|
507 self._selectEntries(local = True, |
|
508 filter=[ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem]) |
|
509 |
|
510 def selectVCSDirEntries(self): |
|
511 """ |
|
512 Public slot to handle the select VCS directories context menu entries |
|
513 """ |
|
514 self._selectEntries(local = False, |
|
515 filter=[ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem]) |
|
516 |
|
517 def _prepareRepopulateItem(self, name): |
|
518 """ |
|
519 Protected slot to handle the prepareRepopulateItem signal. |
|
520 |
|
521 @param name relative name of file item to be repopulated (string) |
|
522 """ |
|
523 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
|
524 QApplication.processEvents() |
|
525 itm = self.currentItem() |
|
526 if itm is not None: |
|
527 self.currentItemName = itm.data(0) |
|
528 self.expandedNames = [] |
|
529 sindex = self._model.itemIndexByName(name) |
|
530 if not sindex.isValid(): |
|
531 return |
|
532 |
|
533 index = self.model().mapFromSource(sindex) |
|
534 if not index.isValid(): |
|
535 return |
|
536 |
|
537 childIndex = self.indexBelow(index) |
|
538 while childIndex.isValid(): |
|
539 if childIndex.parent() == index.parent(): |
|
540 break |
|
541 if self.isExpanded(childIndex): |
|
542 self.expandedNames.append(self.model().item(childIndex).data(0)) |
|
543 childIndex = self.indexBelow(childIndex) |
|
544 |
|
545 def _completeRepopulateItem(self, name): |
|
546 """ |
|
547 Protected slot to handle the completeRepopulateItem signal. |
|
548 |
|
549 @param name relative name of file item to be repopulated (string) |
|
550 """ |
|
551 sindex = self._model.itemIndexByName(name) |
|
552 if sindex.isValid(): |
|
553 index = self.model().mapFromSource(sindex) |
|
554 if index.isValid(): |
|
555 childIndex = self.indexBelow(index) |
|
556 while childIndex.isValid(): |
|
557 if not childIndex.isValid() or childIndex.parent() == index.parent(): |
|
558 break |
|
559 itm = self.model().item(childIndex) |
|
560 if itm is not None: |
|
561 itemData = itm.data(0) |
|
562 if self.currentItemName and self.currentItemName == itemData: |
|
563 self._selectSingleItem(childIndex) |
|
564 if itemData in self.expandedNames: |
|
565 self.setExpanded(childIndex, True) |
|
566 childIndex = self.indexBelow(childIndex) |
|
567 self.expandedNames = [] |
|
568 self.currentItemName = None |
|
569 QApplication.restoreOverrideCursor() |
|
570 QApplication.processEvents() |
|
571 self._resort() |
|
572 |
|
573 def currentItem(self): |
|
574 """ |
|
575 Public method to get a reference to the current item. |
|
576 |
|
577 @return reference to the current item |
|
578 """ |
|
579 itm = self.model().item(self.currentIndex()) |
|
580 return itm |
|
581 |
|
582 ############################################################################ |
|
583 ## Support for hooks below |
|
584 ############################################################################ |
|
585 |
|
586 def _initHookMethods(self): |
|
587 """ |
|
588 Protected method to initialize the hooks dictionary. |
|
589 |
|
590 This method should be overridden by subclasses. All supported |
|
591 hook methods should be initialized with a None value. The keys |
|
592 must be strings. |
|
593 """ |
|
594 self.hooks = {} |
|
595 |
|
596 def __checkHookKey(self, key): |
|
597 """ |
|
598 Private method to check a hook key |
|
599 """ |
|
600 if len(self.hooks) == 0: |
|
601 raise KeyError("Hooks are not initialized.") |
|
602 |
|
603 if key not in self.hooks: |
|
604 raise KeyError(key) |
|
605 |
|
606 def addHookMethod(self, key, method): |
|
607 """ |
|
608 Public method to add a hook method to the dictionary. |
|
609 |
|
610 @param key for the hook method (string) |
|
611 @param method reference to the hook method (method object) |
|
612 """ |
|
613 self.__checkHookKey(key) |
|
614 self.hooks[key] = method |
|
615 |
|
616 def addHookMethodAndMenuEntry(self, key, method, menuEntry): |
|
617 """ |
|
618 Public method to add a hook method to the dictionary. |
|
619 |
|
620 @param key for the hook method (string) |
|
621 @param method reference to the hook method (method object) |
|
622 @param menuEntry entry to be shown in the context menu (string) |
|
623 """ |
|
624 self.addHookMethod(key, method) |
|
625 self.hooksMenuEntries[key] = menuEntry |
|
626 |
|
627 def removeHookMethod(self, key): |
|
628 """ |
|
629 Public method to remove a hook method from the dictionary. |
|
630 |
|
631 @param key for the hook method (string) |
|
632 """ |
|
633 self.__checkHookKey(key) |
|
634 self.hooks[key] = None |
|
635 if key in self.hooksMenuEntries: |
|
636 del self.hooksMenuEntries[key] |
|
637 |
|
638 ################################################################## |
|
639 ## Configure method below |
|
640 ################################################################## |
|
641 |
|
642 def _configure(self): |
|
643 """ |
|
644 Protected method to open the configuration dialog. |
|
645 """ |
|
646 e4App().getObject("UserInterface").showPreferences("projectBrowserPage") |