Plugins/ViewManagerPlugins/Tabview/Tabview.py

changeset 1416
c547d0b2e9c6
parent 1358
c1622c708cd9
child 1419
e200f9084c5d
equal deleted inserted replaced
1415:28fa9633d57e 1416:c547d0b2e9c6
34 """ 34 """
35 Class implementing a customized tab bar supporting drag & drop. 35 Class implementing a customized tab bar supporting drag & drop.
36 36
37 @signal tabMoveRequested(int, int) emitted to signal a tab move request giving 37 @signal tabMoveRequested(int, int) emitted to signal a tab move request giving
38 the old and new index position 38 the old and new index position
39 @signal tabRelocateRequested(long, int, int) emitted to signal a tab relocation 39 @signal tabRelocateRequested(str, int, int) emitted to signal a tab relocation
40 request giving the id of the old tab widget, the index in the old tab widget 40 request giving the string encoded id of the old tab widget, the index in
41 and the new index position 41 the old tab widget and the new index position
42 @signal tabCopyRequested(long, int, int) emitted to signal a clone request 42 @signal tabCopyRequested(str, int, int) emitted to signal a clone request
43 giving the id of the source tab widget, the index in the source tab widget 43 giving the string encoded id of the source tab widget, the index in the
44 and the new index position 44 source tab widget and the new index position
45 @signal tabCopyRequested(int, int) emitted to signal a clone request giving 45 @signal tabCopyRequested(int, int) emitted to signal a clone request giving
46 the old and new index position 46 the old and new index position
47 """ 47 """
48 tabMoveRequested = pyqtSignal(int, int) 48 tabMoveRequested = pyqtSignal(int, int)
49 tabRelocateRequested = pyqtSignal(int, int, int) 49 tabRelocateRequested = pyqtSignal(str, int, int)
50 tabCopyRequested = pyqtSignal(int, int, int) 50 tabCopyRequested = pyqtSignal((str, int, int), (int, int))
51 tabCopyRequested = pyqtSignal(int, int)
52 51
53 def __init__(self, parent=None): 52 def __init__(self, parent=None):
54 """ 53 """
55 Constructor 54 Constructor
56 55
83 drag = QDrag(self) 82 drag = QDrag(self)
84 mimeData = QMimeData() 83 mimeData = QMimeData()
85 index = self.tabAt(event.pos()) 84 index = self.tabAt(event.pos())
86 mimeData.setText(self.tabText(index)) 85 mimeData.setText(self.tabText(index))
87 mimeData.setData("action", "tab-reordering") 86 mimeData.setData("action", "tab-reordering")
88 mimeData.setData("tabbar-id", QByteArray.number(id(self))) 87 mimeData.setData("tabbar-id", str(id(self)))
89 mimeData.setData("source-index", 88 mimeData.setData("source-index",
90 QByteArray.number(self.tabAt(self.__dragStartPos))) 89 QByteArray.number(self.tabAt(self.__dragStartPos)))
91 mimeData.setData("tabwidget-id", QByteArray.number(id(self.parentWidget()))) 90 mimeData.setData("tabwidget-id", str(id(self.parentWidget())))
92 drag.setMimeData(mimeData) 91 drag.setMimeData(mimeData)
93 if event.modifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier): 92 if event.modifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier):
94 drag.exec_(Qt.DropActions(Qt.CopyAction)) 93 drag.exec_(Qt.DropActions(Qt.CopyAction))
95 elif event.modifiers() == Qt.KeyboardModifiers(Qt.NoModifier): 94 elif event.modifiers() == Qt.KeyboardModifiers(Qt.NoModifier):
96 drag.exec_(Qt.DropActions(Qt.MoveAction)) 95 drag.exec_(Qt.DropActions(Qt.MoveAction))
117 Protected method to handle drop events. 116 Protected method to handle drop events.
118 117
119 @param event reference to the drop event (QDropEvent) 118 @param event reference to the drop event (QDropEvent)
120 """ 119 """
121 mimeData = event.mimeData() 120 mimeData = event.mimeData()
122 oldID = mimeData.data("tabbar-id").toLong()[0] 121 oldID = int(mimeData.data("tabbar-id"))
123 fromIndex = mimeData.data("source-index").toInt()[0] 122 fromIndex = mimeData.data("source-index").toInt()[0]
124 toIndex = self.tabAt(event.pos()) 123 toIndex = self.tabAt(event.pos())
125 if oldID != id(self): 124 if oldID != id(self):
126 parentID = mimeData.data("tabwidget-id").toLong()[0] 125 parentID = int(mimeData.data("tabwidget-id"))
127 if event.proposedAction() == Qt.MoveAction: 126 if event.proposedAction() == Qt.MoveAction:
128 self.tabRelocateRequested.emit(parentID, fromIndex, toIndex) 127 self.tabRelocateRequested.emit(str(parentID), fromIndex, toIndex)
129 event.acceptProposedAction() 128 event.acceptProposedAction()
130 elif event.proposedAction() == Qt.CopyAction: 129 elif event.proposedAction() == Qt.CopyAction:
131 self.tabCopyRequested.emit(parentID, fromIndex, toIndex) 130 self.tabCopyRequested[str, int, int].emit(
131 str(parentID), fromIndex, toIndex)
132 event.acceptProposedAction() 132 event.acceptProposedAction()
133 else: 133 else:
134 if fromIndex != toIndex: 134 if fromIndex != toIndex:
135 if event.proposedAction() == Qt.MoveAction: 135 if event.proposedAction() == Qt.MoveAction:
136 self.tabMoveRequested.emit(fromIndex, toIndex) 136 self.tabMoveRequested.emit(fromIndex, toIndex)
137 event.acceptProposedAction() 137 event.acceptProposedAction()
138 elif event.proposedAction() == Qt.CopyAction: 138 elif event.proposedAction() == Qt.CopyAction:
139 self.tabCopyRequested.emit(fromIndex, toIndex) 139 self.tabCopyRequested[int, int].emit(fromIndex, toIndex)
140 event.acceptProposedAction() 140 event.acceptProposedAction()
141 super().dropEvent(event) 141 super().dropEvent(event)
142 142
143 143
144 class TabWidget(E5TabWidget): 144 class TabWidget(E5TabWidget):
156 156
157 self.__tabBar = TabBar(self) 157 self.__tabBar = TabBar(self)
158 self.setTabBar(self.__tabBar) 158 self.setTabBar(self.__tabBar)
159 159
160 self.__tabBar.tabMoveRequested.connect(self.moveTab) 160 self.__tabBar.tabMoveRequested.connect(self.moveTab)
161 self.__tabBar.tabRelocateRequested.connect(self.relocateTab) 161 self.__tabBar.tabRelocateRequested.connect(self.__relocateTab)
162 self.__tabBar.tabCopyRequested.connect(self.copyTabOther) 162 self.__tabBar.tabCopyRequested[str, int, int].connect(self.__copyTabOther)
163 self.__tabBar.tabCopyRequested.connect(self.copyTab) 163 self.__tabBar.tabCopyRequested[int, int].connect(self.__copyTab)
164 164
165 self.vm = vm 165 self.vm = vm
166 self.editors = [] 166 self.editors = []
167 167
168 self.indicator = E5Led(self) 168 self.indicator = E5Led(self)
314 if on: 314 if on:
315 self.indicator.setColor(QColor("green")) 315 self.indicator.setColor(QColor("green"))
316 else: 316 else:
317 self.indicator.setColor(QColor("red")) 317 self.indicator.setColor(QColor("red"))
318 318
319 def addTab(self, editor, title): 319 def addTab(self, assembly, title):
320 """ 320 """
321 Overwritten method to add a new tab. 321 Overwritten method to add a new tab.
322 322
323 @param editor the editor object to be added (QScintilla.Editor.Editor) 323 @param assembly editor assembly object to be added
324 (QScintilla.EditorAssembly.EditorAssembly)
324 @param title title for the new tab (string) 325 @param title title for the new tab (string)
325 """ 326 """
326 assembly = editor.parent() 327 editor = assembly.getEditor()
327 super().addTab(assembly, UI.PixmapCache.getIcon("empty.png"), title) 328 super().addTab(assembly, UI.PixmapCache.getIcon("empty.png"), title)
328 if self.closeButton: 329 if self.closeButton:
329 self.closeButton.setEnabled(True) 330 self.closeButton.setEnabled(True)
330 else: 331 else:
331 self.setTabsClosable(True) 332 self.setTabsClosable(True)
337 338
338 emptyIndex = self.indexOf(self.emptyLabel) 339 emptyIndex = self.indexOf(self.emptyLabel)
339 if emptyIndex > -1: 340 if emptyIndex > -1:
340 self.removeTab(emptyIndex) 341 self.removeTab(emptyIndex)
341 342
342 def insertWidget(self, index, editor, title): 343 def insertWidget(self, index, assembly, title):
343 """ 344 """
344 Overwritten method to insert a new tab. 345 Overwritten method to insert a new tab.
345 346
346 @param index index position for the new tab (integer) 347 @param index index position for the new tab (integer)
347 @param editor the editor object to be added (QScintilla.Editor.Editor) 348 @param assembly editor assembly object to be added
349 (QScintilla.EditorAssembly.EditorAssembly)
348 @param title title for the new tab (string) 350 @param title title for the new tab (string)
349 @return index of the inserted tab (integer) 351 @return index of the inserted tab (integer)
350 """ 352 """
351 assembly = editor.parent() 353 editor = assembly.getEditor()
352 newIndex = super().insertTab(index, assembly, 354 newIndex = super().insertTab(index, assembly,
353 UI.PixmapCache.getIcon("empty.png"), 355 UI.PixmapCache.getIcon("empty.png"),
354 title) 356 title)
355 if self.closeButton: 357 if self.closeButton:
356 self.closeButton.setEnabled(True) 358 self.closeButton.setEnabled(True)
418 self.closeButton.setEnabled(False) 420 self.closeButton.setEnabled(False)
419 else: 421 else:
420 self.setTabsClosable(False) 422 self.setTabsClosable(False)
421 self.navigationButton.setEnabled(False) 423 self.navigationButton.setEnabled(False)
422 424
423 def relocateTab(self, sourceId, sourceIndex, targetIndex): 425 def __relocateTab(self, sourceId, sourceIndex, targetIndex):
424 """ 426 """
425 Public method to relocate an editor from another TabWidget. 427 Private method to relocate an editor from another TabWidget.
426 428
427 @param sourceId id of the TabWidget to get the editor from (long) 429 @param sourceId id of the TabWidget to get the editor from (string)
428 @param sourceIndex index of the tab in the old tab widget (integer) 430 @param sourceIndex index of the tab in the old tab widget (integer)
429 @param targetIndex index position to place it to (integer) 431 @param targetIndex index position to place it to (integer)
430 """ 432 """
431 tw = self.vm.getTabWidgetById(sourceId) 433 tw = self.vm.getTabWidgetById(int(sourceId))
432 if tw is not None: 434 if tw is not None:
433 # step 1: get data of the tab of the source 435 # step 1: get data of the tab of the source
434 toolTip = tw.tabToolTip(sourceIndex) 436 toolTip = tw.tabToolTip(sourceIndex)
435 text = tw.tabText(sourceIndex) 437 text = tw.tabText(sourceIndex)
436 icon = tw.tabIcon(sourceIndex) 438 icon = tw.tabIcon(sourceIndex)
437 whatsThis = tw.tabWhatsThis(sourceIndex) 439 whatsThis = tw.tabWhatsThis(sourceIndex)
438 editor = tw.widget(sourceIndex).getEditor() 440 assembly = tw.widget(sourceIndex)
439 441
440 # step 2: relocate the tab 442 # step 2: relocate the tab
441 tw.removeWidget(editor) 443 tw.removeWidget(assembly.getEditor())
442 self.insertWidget(targetIndex, editor, text) 444 self.insertWidget(targetIndex, assembly, text)
443 445
444 # step 3: set the tab data again 446 # step 3: set the tab data again
445 self.setTabIcon(targetIndex, icon) 447 self.setTabIcon(targetIndex, icon)
446 self.setTabToolTip(targetIndex, toolTip) 448 self.setTabToolTip(targetIndex, toolTip)
447 self.setTabWhatsThis(targetIndex, whatsThis) 449 self.setTabWhatsThis(targetIndex, whatsThis)
448 450
449 # step 4: set current widget 451 # step 4: set current widget
450 self.setCurrentIndex(targetIndex) 452 self.setCurrentIndex(targetIndex)
451 453
452 def copyTabOther(self, sourceId, sourceIndex, targetIndex): 454 def __copyTabOther(self, sourceId, sourceIndex, targetIndex):
453 """ 455 """
454 Public method to copy an editor from another TabWidget. 456 Private method to copy an editor from another TabWidget.
455 457
456 @param sourceId id of the TabWidget to get the editor from (long) 458 @param sourceId id of the TabWidget to get the editor from (string)
457 @param sourceIndex index of the tab in the old tab widget (integer) 459 @param sourceIndex index of the tab in the old tab widget (integer)
458 @param targetIndex index position to place it to (integer) 460 @param targetIndex index position to place it to (integer)
459 """ 461 """
460 tw = self.vm.getTabWidgetById(sourceId) 462 tw = self.vm.getTabWidgetById(int(sourceId))
461 if tw is not None: 463 if tw is not None:
462 editor = tw.widget(sourceIndex).getEditor() 464 editor = tw.widget(sourceIndex).getEditor()
463 newEditor = self.vm.cloneEditor(editor, editor.getFileType(), 465 newEditor, assembly = self.vm.cloneEditor(editor, editor.getFileType(),
464 editor.getFileName()) 466 editor.getFileName())
465 self.vm.insertView(newEditor, self, targetIndex, 467 self.vm.insertView(assembly, self, targetIndex,
466 editor.getFileName(), editor.getNoName()) 468 editor.getFileName(), editor.getNoName())
467 469
468 def copyTab(self, sourceIndex, targetIndex): 470 def __copyTab(self, sourceIndex, targetIndex):
469 """ 471 """
470 Public method to copy an editor. 472 Private method to copy an editor.
471 473
472 @param sourceIndex index of the tab (integer) 474 @param sourceIndex index of the tab (integer)
473 @param targetIndex index position to place it to (integer) 475 @param targetIndex index position to place it to (integer)
474 """ 476 """
475 editor = self.widget(sourceIndex).getEditor() 477 editor = self.widget(sourceIndex).getEditor()
476 newEditor = self.vm.cloneEditor(editor, editor.getFileType(), 478 newEditor, assembly = self.vm.cloneEditor(editor, editor.getFileType(),
477 editor.getFileName()) 479 editor.getFileName())
478 self.vm.insertView(newEditor, self, targetIndex, 480 self.vm.insertView(assembly, self, targetIndex,
479 editor.getFileName(), editor.getNoName()) 481 editor.getFileName(), editor.getNoName())
480 482
481 def currentWidget(self): 483 def currentWidget(self):
482 """ 484 """
483 Overridden method to return a reference to the current page. 485 Overridden method to return a reference to the current page.
788 790
789 def _addView(self, win, fn=None, noName=""): 791 def _addView(self, win, fn=None, noName=""):
790 """ 792 """
791 Protected method to add a view (i.e. window) 793 Protected method to add a view (i.e. window)
792 794
793 @param win editor window to be added 795 @param win editor assembly to be added
794 @param fn filename of this editor (string) 796 @param fn filename of this editor (string)
795 @param noName name to be used for an unnamed editor (string) 797 @param noName name to be used for an unnamed editor (string)
796 """ 798 """
799 editor = win.getEditor()
797 if fn is None: 800 if fn is None:
798 if not noName: 801 if not noName:
799 self.untitledCount += 1 802 self.untitledCount += 1
800 noName = self.trUtf8("Untitled {0}").format(self.untitledCount) 803 noName = self.trUtf8("Untitled {0}").format(self.untitledCount)
801 self.currentTabWidget.addTab(win, noName) 804 self.currentTabWidget.addTab(win, noName)
802 win.setNoName(noName) 805 editor.setNoName(noName)
803 else: 806 else:
804 if self.filenameOnly: 807 if self.filenameOnly:
805 txt = os.path.basename(fn) 808 txt = os.path.basename(fn)
806 else: 809 else:
807 txt = e5App().getObject("Project").getRelativePath(fn) 810 txt = e5App().getObject("Project").getRelativePath(fn)
812 self.currentTabWidget.addTab(win, txt) 815 self.currentTabWidget.addTab(win, txt)
813 index = self.currentTabWidget.indexOf(win) 816 index = self.currentTabWidget.indexOf(win)
814 self.currentTabWidget.setTabToolTip(index, fn) 817 self.currentTabWidget.setTabToolTip(index, fn)
815 self.currentTabWidget.setCurrentWidget(win) 818 self.currentTabWidget.setCurrentWidget(win)
816 win.show() 819 win.show()
817 win.setFocus() 820 editor.setFocus()
818 if fn: 821 if fn:
819 self.changeCaption.emit(fn) 822 self.changeCaption.emit(fn)
820 self.editorChanged.emit(fn) 823 self.editorChanged.emit(fn)
821 else: 824 else:
822 self.changeCaption.emit("") 825 self.changeCaption.emit("")
823 826
824 def insertView(self, win, tabWidget, index, fn=None, noName=""): 827 def insertView(self, win, tabWidget, index, fn=None, noName=""):
825 """ 828 """
826 Protected method to add a view (i.e. window) 829 Protected method to add a view (i.e. window)
827 830
828 @param win editor window to be added 831 @param win editor assembly to be inserted
829 @param tabWidget reference to the tab widget to insert the editor into (TabWidget) 832 @param tabWidget reference to the tab widget to insert the editor into (TabWidget)
830 @param index index position to insert at (integer) 833 @param index index position to insert at (integer)
831 @param fn filename of this editor (string) 834 @param fn filename of this editor (string)
832 @param noName name to be used for an unnamed editor (string) 835 @param noName name to be used for an unnamed editor (string)
833 """ 836 """
837 editor = win.getEditor()
834 if fn is None: 838 if fn is None:
835 if not noName: 839 if not noName:
836 self.untitledCount += 1 840 self.untitledCount += 1
837 noName = self.trUtf8("Untitled {0}").format(self.untitledCount) 841 noName = self.trUtf8("Untitled {0}").format(self.untitledCount)
838 tabWidget.insertWidget(index, win, noName) 842 tabWidget.insertWidget(index, win, noName)
839 win.setNoName(noName) 843 editor.setNoName(noName)
840 else: 844 else:
841 if self.filenameOnly: 845 if self.filenameOnly:
842 txt = os.path.basename(fn) 846 txt = os.path.basename(fn)
843 else: 847 else:
844 txt = e5App().getObject("Project").getRelativePath(fn) 848 txt = e5App().getObject("Project").getRelativePath(fn)
848 txt = self.trUtf8("{0} (ro)").format(txt) 852 txt = self.trUtf8("{0} (ro)").format(txt)
849 nindex = tabWidget.insertWidget(index, win, txt) 853 nindex = tabWidget.insertWidget(index, win, txt)
850 tabWidget.setTabToolTip(nindex, fn) 854 tabWidget.setTabToolTip(nindex, fn)
851 tabWidget.setCurrentWidget(win) 855 tabWidget.setCurrentWidget(win)
852 win.show() 856 win.show()
853 win.setFocus() 857 editor.setFocus()
854 if fn: 858 if fn:
855 self.changeCaption.emit(fn) 859 self.changeCaption.emit(fn)
856 self.editorChanged.emit(fn) 860 self.editorChanged.emit(fn)
857 else: 861 else:
858 self.changeCaption.emit("") 862 self.changeCaption.emit("")
859 863
860 self._modificationStatusChanged(win.isModified(), win) 864 self._modificationStatusChanged(editor.isModified(), editor)
861 self._checkActions(win) 865 self._checkActions(editor)
862 866
863 def _showView(self, win, fn=None): 867 def _showView(self, win, fn=None):
864 """ 868 """
865 Protected method to show a view (i.e. window) 869 Protected method to show a view (i.e. window)
866 870

eric ide

mercurial