Plugins/ViewManagerPlugins/Listspace/Listspace.py

branch
maintenance
changeset 6097
bf18415da0c7
parent 6056
bfc5153d0224
parent 6072
059c8f981ef4
child 6166
bace7fb85a01
equal deleted inserted replaced
6071:e9bda9b4260b 6097:bf18415da0c7
9 9
10 from __future__ import unicode_literals 10 from __future__ import unicode_literals
11 11
12 import os 12 import os
13 13
14 from PyQt5.QtCore import pyqtSignal, QFileInfo, QEvent, Qt 14 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QFileInfo, QEvent, Qt
15 from PyQt5.QtWidgets import QStackedWidget, QSplitter, QListWidget, \ 15 from PyQt5.QtWidgets import QStackedWidget, QSplitter, QListWidget, \
16 QListWidgetItem, QSizePolicy, QMenu, QApplication 16 QListWidgetItem, QSizePolicy, QMenu, QApplication
17 17
18 from ViewManager.ViewManager import ViewManager 18 from ViewManager.ViewManager import ViewManager
19 19
20 import QScintilla.Editor 20 import QScintilla.Editor
21 from QScintilla.Editor import Editor 21 from QScintilla.Editor import Editor
22 from QScintilla.EditorAssembly import EditorAssembly
22 23
23 import UI.PixmapCache 24 import UI.PixmapCache
24 25
25 26
26 class StackedWidget(QStackedWidget): 27 class StackedWidget(QStackedWidget):
29 """ 30 """
30 def __init__(self, parent): 31 def __init__(self, parent):
31 """ 32 """
32 Constructor 33 Constructor
33 34
34 @param parent parent widget (QWidget) 35 @param parent parent widget
36 @type QWidget
35 """ 37 """
36 super(StackedWidget, self).__init__(parent) 38 super(StackedWidget, self).__init__(parent)
37 39
38 self.editors = [] 40 self.editors = []
39 41
40 def addWidget(self, assembly): 42 def addWidget(self, assembly):
41 """ 43 """
42 Public method to add a new widget. 44 Public method to add a new widget.
43 45
44 @param assembly editor assembly object to be added 46 @param assembly editor assembly object to be added
45 (QScintilla.EditorAssembly.EditorAssembly) 47 @type QScintilla.EditorAssembly.EditorAssembly
46 """ 48 """
47 editor = assembly.getEditor() 49 editor = assembly.getEditor()
48 super(StackedWidget, self).addWidget(assembly) 50 super(StackedWidget, self).addWidget(assembly)
49 if editor not in self.editors: 51 if editor not in self.editors:
50 self.editors.append(editor) 52 self.editors.append(editor)
51 53
52 def removeWidget(self, widget): 54 def removeWidget(self, widget):
53 """ 55 """
54 Public method to remove a widget. 56 Public method to remove a widget.
55 57
56 @param widget widget to be removed (QWidget) 58 @param widget widget to be removed
59 @type QWidget
57 """ 60 """
58 if isinstance(widget, QScintilla.Editor.Editor): 61 if isinstance(widget, QScintilla.Editor.Editor):
59 self.editors.remove(widget) 62 self.editors.remove(widget)
60 widget = widget.parent() 63 widget = widget.parent()
61 super(StackedWidget, self).removeWidget(widget) 64 super(StackedWidget, self).removeWidget(widget)
62 65
63 def currentWidget(self): 66 def currentWidget(self):
64 """ 67 """
65 Public method to get a reference to the current editor. 68 Public method to get a reference to the current editor.
66 69
67 @return reference to the current editor (Editor) 70 @return reference to the current editor
71 @rtype Editor
68 """ 72 """
69 widget = super(StackedWidget, self).currentWidget() 73 widget = super(StackedWidget, self).currentWidget()
70 if widget is not None: 74 if widget is not None:
71 widget = widget.getEditor() 75 widget = widget.getEditor()
72 return widget 76 return widget
73 77
74 def setCurrentWidget(self, widget): 78 def setCurrentWidget(self, widget):
75 """ 79 """
76 Public method to set the current widget. 80 Public method to set the current widget.
77 81
78 @param widget widget to be made current (QWidget) 82 @param widget widget to be made current
83 @type QWidget
79 """ 84 """
80 if widget is not None: 85 if widget is not None:
81 if isinstance(widget, QScintilla.Editor.Editor): 86 if isinstance(widget, QScintilla.Editor.Editor):
82 self.editors.remove(widget) 87 self.editors.remove(widget)
83 self.editors.insert(0, widget) 88 self.editors.insert(0, widget)
86 91
87 def setCurrentIndex(self, index): 92 def setCurrentIndex(self, index):
88 """ 93 """
89 Public method to set the current widget by its index. 94 Public method to set the current widget by its index.
90 95
91 @param index index of widget to be made current (integer) 96 @param index index of widget to be made current
97 @type int
92 """ 98 """
93 widget = self.widget(index) 99 widget = self.widget(index)
94 if widget is not None: 100 if widget is not None:
95 self.setCurrentWidget(widget) 101 self.setCurrentWidget(widget)
96 102
119 def hasEditor(self, editor): 125 def hasEditor(self, editor):
120 """ 126 """
121 Public method to check for an editor. 127 Public method to check for an editor.
122 128
123 @param editor editor object to check for 129 @param editor editor object to check for
130 @type Editor
124 @return flag indicating, whether the editor to be checked belongs 131 @return flag indicating, whether the editor to be checked belongs
125 to the list of editors managed by this stacked widget. 132 to the list of editors managed by this stacked widget.
133 @rtype bool
126 """ 134 """
127 return editor in self.editors 135 return editor in self.editors
128 136
129 def firstEditor(self): 137 def firstEditor(self):
130 """ 138 """
131 Public method to retrieve the first editor in the list of managed 139 Public method to retrieve the first editor in the list of managed
132 editors. 140 editors.
133 141
134 @return first editor in list (QScintilla.Editor.Editor) 142 @return first editor in list
143 @rtype QScintilla.Editor.Editor
135 """ 144 """
136 return len(self.editors) and self.editors[0] or None 145 return len(self.editors) and self.editors[0] or None
137 146
138 147
139 class Listspace(ViewManager): 148 class Listspace(ViewManager):
193 202
194 def __init__(self, parent): 203 def __init__(self, parent):
195 """ 204 """
196 Constructor 205 Constructor
197 206
198 @param parent parent widget (QWidget) 207 @param parent parent widget
208 @type QWidget
199 """ 209 """
200 self.stacks = [] 210 self.stacks = []
201 211
202 self.__splitter = QSplitter(parent) 212 self.__splitter = QSplitter(parent)
203 ViewManager.__init__(self) 213 ViewManager.__init__(self)
271 def __showMenu(self, point): 281 def __showMenu(self, point):
272 """ 282 """
273 Private slot to handle the customContextMenuRequested signal of 283 Private slot to handle the customContextMenuRequested signal of
274 the viewlist. 284 the viewlist.
275 285
276 @param point position to open the menu at (QPoint) 286 @param point position to open the menu at
287 @type QPoint
277 """ 288 """
278 if self.editors: 289 if self.editors:
279 itm = self.viewlist.itemAt(point) 290 itm = self.viewlist.itemAt(point)
280 if itm is not None: 291 if itm is not None:
281 row = self.viewlist.row(itm) 292 row = self.viewlist.row(itm)
311 def canCascade(self): 322 def canCascade(self):
312 """ 323 """
313 Public method to signal if cascading of managed windows is available. 324 Public method to signal if cascading of managed windows is available.
314 325
315 @return flag indicating cascading of windows is available 326 @return flag indicating cascading of windows is available
327 @rtype bool
316 """ 328 """
317 return False 329 return False
318 330
319 def canTile(self): 331 def canTile(self):
320 """ 332 """
321 Public method to signal if tiling of managed windows is available. 333 Public method to signal if tiling of managed windows is available.
322 334
323 @return flag indicating tiling of windows is available 335 @return flag indicating tiling of windows is available
336 @rtype bool
324 """ 337 """
325 return False 338 return False
326 339
327 def canSplit(self): 340 def canSplit(self):
328 """ 341 """
329 public method to signal if splitting of the view is available. 342 public method to signal if splitting of the view is available.
330 343
331 @return flag indicating splitting of the view is available. 344 @return flag indicating splitting of the view is available
345 @rtype bool
332 """ 346 """
333 return True 347 return True
334 348
335 def tile(self): 349 def tile(self):
336 """ 350 """
359 def _removeView(self, win): 373 def _removeView(self, win):
360 """ 374 """
361 Protected method to remove a view (i.e. window). 375 Protected method to remove a view (i.e. window).
362 376
363 @param win editor window to be removed 377 @param win editor window to be removed
378 @type Editor
364 """ 379 """
365 self.__inRemoveView = True 380 self.__inRemoveView = True
366 ind = self.editors.index(win) 381 ind = self.editors.index(win)
367 itm = self.viewlist.takeItem(ind) 382 itm = self.viewlist.takeItem(ind)
368 if itm: 383 if itm:
391 self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1) 406 self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1)
392 else: 407 else:
393 self.changeCaption.emit("") 408 self.changeCaption.emit("")
394 self.editorChangedEd.emit(aw) 409 self.editorChangedEd.emit(aw)
395 410
396 def _addView(self, win, fn=None, noName="", addNext=False): 411 def _addView(self, win, fn=None, noName="", addNext=False, indexes=None):
397 """ 412 """
398 Protected method to add a view (i.e. window). 413 Protected method to add a view (i.e. window).
399 414
400 @param win editor assembly to be added 415 @param win editor assembly to be added
401 @param fn filename of this editor (string) 416 @type EditorAssembly
402 @param noName name to be used for an unnamed editor (string) 417 @param fn filename of this editor
418 @type str
419 @param noName name to be used for an unnamed editor
420 @type str
403 @param addNext flag indicating to add the view next to the current 421 @param addNext flag indicating to add the view next to the current
404 view (bool) 422 view
423 @type bool
424 @param indexes of the editor, first the split view index, second the
425 index within the view
426 @type tuple of two int
405 """ 427 """
406 editor = win.getEditor() 428 editor = win.getEditor()
407 if not fn: 429 if not fn:
408 if not noName: 430 if not noName:
409 self.untitledCount += 1 431 self.untitledCount += 1
415 if not QFileInfo(fn).isWritable(): 437 if not QFileInfo(fn).isWritable():
416 txt = self.tr("{0} (ro)").format(txt) 438 txt = self.tr("{0} (ro)").format(txt)
417 itm = QListWidgetItem(txt) 439 itm = QListWidgetItem(txt)
418 itm.setToolTip(fn) 440 itm.setToolTip(fn)
419 self.viewlist.addItem(itm) 441 self.viewlist.addItem(itm)
420 self.currentStack.addWidget(win) 442 if indexes:
421 self.currentStack.setCurrentWidget(win) 443 if indexes[0] < len(self.stacks):
444 stack = self.stacks[indexes[0]]
445 else:
446 stack = self.stacks[-1]
447 stack.addWidget(win)
448 else:
449 self.currentStack.addWidget(win)
450 self.currentStack.setCurrentWidget(win)
422 editor.captionChanged.connect(self.__captionChange) 451 editor.captionChanged.connect(self.__captionChange)
423 editor.cursorLineChanged.connect(self.__cursorLineChanged) 452 editor.cursorLineChanged.connect(self.__cursorLineChanged)
424 453
425 index = self.editors.index(editor) 454 index = self.editors.index(editor)
426 self.viewlist.setCurrentRow(index) 455 self.viewlist.setCurrentRow(index)
437 """ 466 """
438 Private method to handle caption change signals from the editor. 467 Private method to handle caption change signals from the editor.
439 468
440 Updates the listwidget text to reflect the new caption information. 469 Updates the listwidget text to reflect the new caption information.
441 470
442 @param cap Caption for the editor (string) 471 @param cap Caption for the editor
472 @type str
443 @param editor Editor to update the caption for 473 @param editor Editor to update the caption for
474 @type Editor
444 """ 475 """
445 fn = editor.getFileName() 476 fn = editor.getFileName()
446 if fn: 477 if fn:
447 self.setEditorName(editor, fn) 478 self.setEditorName(editor, fn)
448 479
449 def __cursorLineChanged(self, lineno): 480 def __cursorLineChanged(self, lineno):
450 """ 481 """
451 Private slot to handle a change of the current editor's cursor line. 482 Private slot to handle a change of the current editor's cursor line.
452 483
453 @param lineno line number of the current editor's cursor (zero based) 484 @param lineno line number of the current editor's cursor (zero based)
485 @type int
454 """ 486 """
455 editor = self.sender() 487 editor = self.sender()
456 if editor: 488 if editor:
457 fn = editor.getFileName() 489 fn = editor.getFileName()
458 if fn: 490 if fn:
461 def _showView(self, win, fn=None): 493 def _showView(self, win, fn=None):
462 """ 494 """
463 Protected method to show a view (i.e. window). 495 Protected method to show a view (i.e. window).
464 496
465 @param win editor assembly to be shown 497 @param win editor assembly to be shown
466 @param fn filename of this editor (string) 498 @type EditorAssembly
499 @param fn filename of this editor
500 @type string
467 """ 501 """
468 editor = win.getEditor() 502 editor = win.getEditor()
469 for stack in self.stacks: 503 for stack in self.stacks:
470 if stack.hasEditor(editor): 504 if stack.hasEditor(editor):
471 stack.setCurrentWidget(win) 505 stack.setCurrentWidget(win)
485 519
486 def __showSelectedView(self, row): 520 def __showSelectedView(self, row):
487 """ 521 """
488 Private slot called to show a view selected in the list. 522 Private slot called to show a view selected in the list.
489 523
490 @param row row number of the item clicked on (integer) 524 @param row row number of the item clicked on
525 @type int
491 """ 526 """
492 if row != -1: 527 if row != -1:
493 self._showView(self.editors[row].parent()) 528 self._showView(self.editors[row].parent())
494 self._checkActions(self.editors[row]) 529 self._checkActions(self.editors[row])
495 530
496 def activeWindow(self): 531 def activeWindow(self):
497 """ 532 """
498 Public method to return the active (i.e. current) window. 533 Public method to return the active (i.e. current) window.
499 534
500 @return reference to the active editor 535 @return reference to the active editor
536 @rtype EditorAssembly
501 """ 537 """
502 return self.currentStack.currentWidget() 538 return self.currentStack.currentWidget()
503 539
504 def showWindowMenu(self, windowMenu): 540 def showWindowMenu(self, windowMenu):
505 """ 541 """
506 Public method to set up the viewmanager part of the Window menu. 542 Public method to set up the viewmanager part of the Window menu.
507 543
508 @param windowMenu reference to the window menu 544 @param windowMenu reference to the window menu
545 @type QMenu
509 """ 546 """
510 pass 547 pass
511 548
512 def _initWindowActions(self): 549 def _initWindowActions(self):
513 """ 550 """
519 def setEditorName(self, editor, newName): 556 def setEditorName(self, editor, newName):
520 """ 557 """
521 Public method to change the displayed name of the editor. 558 Public method to change the displayed name of the editor.
522 559
523 @param editor editor window to be changed 560 @param editor editor window to be changed
524 @param newName new name to be shown (string) 561 @type Editor
562 @param newName new name to be shown
563 @type str
525 """ 564 """
526 if newName: 565 if newName:
527 currentRow = self.viewlist.currentRow() 566 currentRow = self.viewlist.currentRow()
528 index = self.editors.index(editor) 567 index = self.editors.index(editor)
529 txt = os.path.basename(newName) 568 txt = os.path.basename(newName)
538 577
539 def _modificationStatusChanged(self, m, editor): 578 def _modificationStatusChanged(self, m, editor):
540 """ 579 """
541 Protected slot to handle the modificationStatusChanged signal. 580 Protected slot to handle the modificationStatusChanged signal.
542 581
543 @param m flag indicating the modification status (boolean) 582 @param m flag indicating the modification status
583 @type bool
544 @param editor editor window changed 584 @param editor editor window changed
585 @type Editor
545 """ 586 """
546 currentRow = self.viewlist.currentRow() 587 currentRow = self.viewlist.currentRow()
547 index = self.editors.index(editor) 588 index = self.editors.index(editor)
548 keys = [] 589 keys = []
549 if m: 590 if m:
563 def _syntaxErrorToggled(self, editor): 604 def _syntaxErrorToggled(self, editor):
564 """ 605 """
565 Protected slot to handle the syntaxerrorToggled signal. 606 Protected slot to handle the syntaxerrorToggled signal.
566 607
567 @param editor editor that sent the signal 608 @param editor editor that sent the signal
609 @type Editor
568 """ 610 """
569 currentRow = self.viewlist.currentRow() 611 currentRow = self.viewlist.currentRow()
570 index = self.editors.index(editor) 612 index = self.editors.index(editor)
571 keys = [] 613 keys = []
572 if editor.isModified(): 614 if editor.isModified():
603 [int(size / len(self.stacks))] * len(self.stacks)) 645 [int(size / len(self.stacks))] * len(self.stacks))
604 self.splitRemoveAct.setEnabled(True) 646 self.splitRemoveAct.setEnabled(True)
605 self.nextSplitAct.setEnabled(True) 647 self.nextSplitAct.setEnabled(True)
606 self.prevSplitAct.setEnabled(True) 648 self.prevSplitAct.setEnabled(True)
607 649
608 def removeSplit(self): 650 @pyqtSlot()
609 """ 651 def removeSplit(self, index=-1):
610 Public method used to remove the current split view. 652 """
611 653 Public method used to remove the current split view or a split view
612 @return flag indicating successfull removal 654 by index.
655
656 @param index index of the split to be removed (-1 means to
657 delete the current split)
658 @type int
659 @return flag indicating successful deletion
660 @rtype bool
613 """ 661 """
614 if len(self.stacks) > 1: 662 if len(self.stacks) > 1:
615 stack = self.currentStack 663 if index == -1:
664 stack = self.currentStack
665 else:
666 if index < len(self.stacks):
667 stack = self.stacks[index]
668 else:
669 stack = self.stacks[-1]
616 res = True 670 res = True
617 savedEditors = stack.editors[:] 671 savedEditors = stack.editors[:]
618 for editor in savedEditors: 672 for editor in savedEditors:
619 res &= self.closeEditor(editor) 673 res &= self.closeEditor(editor)
620 if res: 674 if res:
633 self.prevSplitAct.setEnabled(False) 687 self.prevSplitAct.setEnabled(False)
634 return True 688 return True
635 689
636 return False 690 return False
637 691
692 def splitCount(self):
693 """
694 Public method to get the number of splitted views.
695
696 @return number of splitted views
697 @rtype int
698 """
699 return len(self.stacks)
700
701 def setSplitCount(self, count):
702 """
703 Public method to set the number of split views.
704
705 @param count number of split views
706 @type int
707 """
708 if count > self.splitCount():
709 while self.splitCount() < count:
710 self.addSplit()
711 elif count < self.splitCount():
712 while self.splitCount() > count:
713 # use an arbitrarily large index to remove the last one
714 self.removeSplit(index=100)
715
638 def getSplitOrientation(self): 716 def getSplitOrientation(self):
639 """ 717 """
640 Public method to get the orientation of the split view. 718 Public method to get the orientation of the split view.
641 719
642 @return orientation of the split (Qt.Horizontal or Qt.Vertical) 720 @return orientation of the split
721 @rtype Qt.Horizontal or Qt.Vertical
643 """ 722 """
644 return self.stackArea.orientation() 723 return self.stackArea.orientation()
645 724
646 def setSplitOrientation(self, orientation): 725 def setSplitOrientation(self, orientation):
647 """ 726 """
648 Public method used to set the orientation of the split view. 727 Public method used to set the orientation of the split view.
649 728
650 @param orientation orientation of the split 729 @param orientation orientation of the split
651 (Qt.Horizontal or Qt.Vertical) 730 @type Qt.Horizontal or Qt.Vertical
652 """ 731 """
653 self.stackArea.setOrientation(orientation) 732 self.stackArea.setOrientation(orientation)
654 733
655 def nextSplit(self): 734 def nextSplit(self):
656 """ 735 """
772 def __currentChanged(self, index): 851 def __currentChanged(self, index):
773 """ 852 """
774 Private slot to handle the currentChanged signal. 853 Private slot to handle the currentChanged signal.
775 854
776 @param index index of the current editor 855 @param index index of the current editor
856 @type int
777 """ 857 """
778 if index == -1 or not self.editors: 858 if index == -1 or not self.editors:
779 return 859 return
780 860
781 editor = self.activeWindow() 861 editor = self.activeWindow()
801 def eventFilter(self, watched, event): 881 def eventFilter(self, watched, event):
802 """ 882 """
803 Public method called to filter the event queue. 883 Public method called to filter the event queue.
804 884
805 @param watched the QObject being watched 885 @param watched the QObject being watched
886 @type QObject
806 @param event the event that occurred 887 @param event the event that occurred
888 @type QEvent
807 @return flag indicating, if we handled the event 889 @return flag indicating, if we handled the event
890 @rtype bool
808 """ 891 """
809 if event.type() == QEvent.MouseButtonPress and \ 892 if event.type() == QEvent.MouseButtonPress and \
810 not event.button() == Qt.RightButton: 893 not event.button() == Qt.RightButton:
811 switched = True 894 switched = True
812 if isinstance(watched, QStackedWidget): 895 if isinstance(watched, QStackedWidget):
837 else: 920 else:
838 self.changeCaption.emit("") 921 self.changeCaption.emit("")
839 self.editorChangedEd.emit(aw) 922 self.editorChangedEd.emit(aw)
840 923
841 return False 924 return False
925
926 def getOpenEditorsForSession(self):
927 """
928 Public method to get a lists of all open editors.
929
930 The returned list contains one list per split view. If the view manager
931 cannot split the view, only one list of editors is returned.
932
933 @return list of list of editor references
934 @rtype list of list of Editor
935 """
936 editorLists = []
937 for stack in self.stacks:
938 editors = []
939 for index in range(stack.count()):
940 widget = stack.widget(index)
941 if isinstance(widget, EditorAssembly):
942 editor = widget.getEditor()
943 editors.append(editor)
944 editorLists.append(editors)
945 return editorLists

eric ide

mercurial