eric7/Plugins/ViewManagerPlugins/Listspace/Listspace.py

branch
eric7
changeset 8312
800c432b34c8
parent 8259
2bbec88047dd
child 8318
962bce857696
equal deleted inserted replaced
8311:4e8b98454baa 8312:800c432b34c8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2002 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the listspace viewmanager class.
8 """
9
10 import os
11
12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QFileInfo, QEvent, Qt
13 from PyQt5.QtWidgets import (
14 QStackedWidget, QSplitter, QListWidget, QListWidgetItem, QSizePolicy,
15 QMenu, QApplication
16 )
17
18 from ViewManager.ViewManager import ViewManager
19
20 import QScintilla.Editor
21 from QScintilla.Editor import Editor
22 from QScintilla.EditorAssembly import EditorAssembly
23
24 import UI.PixmapCache
25
26
27 class StackedWidget(QStackedWidget):
28 """
29 Class implementing a custimized StackedWidget.
30 """
31 def __init__(self, parent):
32 """
33 Constructor
34
35 @param parent parent widget
36 @type QWidget
37 """
38 super().__init__(parent)
39
40 self.editors = []
41
42 def addWidget(self, assembly):
43 """
44 Public method to add a new widget.
45
46 @param assembly editor assembly object to be added
47 @type QScintilla.EditorAssembly.EditorAssembly
48 """
49 editor = assembly.getEditor()
50 super().addWidget(assembly)
51 if editor not in self.editors:
52 self.editors.append(editor)
53
54 def removeWidget(self, widget):
55 """
56 Public method to remove a widget.
57
58 @param widget widget to be removed
59 @type QWidget
60 """
61 if isinstance(widget, QScintilla.Editor.Editor):
62 self.editors.remove(widget)
63 widget = widget.parent()
64 super().removeWidget(widget)
65
66 def currentWidget(self):
67 """
68 Public method to get a reference to the current editor.
69
70 @return reference to the current editor
71 @rtype Editor
72 """
73 widget = super().currentWidget()
74 if widget is not None:
75 widget = widget.getEditor()
76 return widget
77
78 def setCurrentWidget(self, widget):
79 """
80 Public method to set the current widget.
81
82 @param widget widget to be made current
83 @type QWidget
84 """
85 if widget is not None:
86 if isinstance(widget, QScintilla.Editor.Editor):
87 self.editors.remove(widget)
88 self.editors.insert(0, widget)
89 widget = widget.parent()
90 super().setCurrentWidget(widget)
91
92 def setCurrentIndex(self, index):
93 """
94 Public method to set the current widget by its index.
95
96 @param index index of widget to be made current
97 @type int
98 """
99 widget = self.widget(index)
100 if widget is not None:
101 self.setCurrentWidget(widget)
102
103 def nextTab(self):
104 """
105 Public slot used to show the next tab.
106 """
107 ind = self.currentIndex() + 1
108 if ind == self.count():
109 ind = 0
110
111 self.setCurrentIndex(ind)
112 self.currentWidget().setFocus()
113
114 def prevTab(self):
115 """
116 Public slot used to show the previous tab.
117 """
118 ind = self.currentIndex() - 1
119 if ind == -1:
120 ind = self.count() - 1
121
122 self.setCurrentIndex(ind)
123 self.currentWidget().setFocus()
124
125 def hasEditor(self, editor):
126 """
127 Public method to check for an editor.
128
129 @param editor editor object to check for
130 @type Editor
131 @return flag indicating, whether the editor to be checked belongs
132 to the list of editors managed by this stacked widget.
133 @rtype bool
134 """
135 return editor in self.editors
136
137 def firstEditor(self):
138 """
139 Public method to retrieve the first editor in the list of managed
140 editors.
141
142 @return first editor in list
143 @rtype QScintilla.Editor.Editor
144 """
145 return len(self.editors) and self.editors[0] or None
146
147
148 class Listspace(ViewManager):
149 """
150 Class implementing the listspace viewmanager class.
151
152 @signal changeCaption(str) emitted if a change of the caption is necessary
153 @signal editorChanged(str) emitted when the current editor has changed
154 @signal editorChangedEd(Editor) emitted when the current editor has changed
155 @signal lastEditorClosed() emitted after the last editor window was closed
156 @signal editorOpened(str) emitted after an editor window was opened
157 @signal editorOpenedEd(Editor) emitted after an editor window was opened
158 @signal editorClosed(str) emitted just before an editor window gets closed
159 @signal editorClosedEd(Editor) emitted just before an editor window gets
160 closed
161 @signal editorRenamed(str) emitted after an editor was renamed
162 @signal editorRenamedEd(Editor) emitted after an editor was renamed
163 @signal editorSaved(str) emitted after an editor window was saved
164 @signal editorSavedEd(Editor) emitted after an editor window was saved
165 @signal checkActions(Editor) emitted when some actions should be checked
166 for their status
167 @signal cursorChanged(Editor) emitted after the cursor position of the
168 active window has changed
169 @signal breakpointToggled(Editor) emitted when a breakpoint is toggled.
170 @signal bookmarkToggled(Editor) emitted when a bookmark is toggled.
171 @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled.
172 @signal previewStateChanged(bool) emitted to signal a change in the
173 preview state
174 @signal previewStateChanged(bool) emitted to signal a change in the
175 preview state
176 @signal astViewerStateChanged(bool) emitted to signal a change in the
177 AST viewer state
178 @signal editorLanguageChanged(Editor) emitted to signal a change of an
179 editors language
180 @signal editorTextChanged(Editor) emitted to signal a change of an
181 editor's text
182 @signal editorLineChanged(str,int) emitted to signal a change of an
183 editor's current line (line is given one based)
184 @signal editorLineChangedEd(Editor,int) emitted to signal a change of an
185 editor's current line (line is given one based)
186 """
187 changeCaption = pyqtSignal(str)
188 editorChanged = pyqtSignal(str)
189 editorChangedEd = pyqtSignal(Editor)
190 lastEditorClosed = pyqtSignal()
191 editorOpened = pyqtSignal(str)
192 editorOpenedEd = pyqtSignal(Editor)
193 editorClosed = pyqtSignal(str)
194 editorClosedEd = pyqtSignal(Editor)
195 editorRenamed = pyqtSignal(str)
196 editorRenamedEd = pyqtSignal(Editor)
197 editorSaved = pyqtSignal(str)
198 editorSavedEd = pyqtSignal(Editor)
199 checkActions = pyqtSignal(Editor)
200 cursorChanged = pyqtSignal(Editor)
201 breakpointToggled = pyqtSignal(Editor)
202 bookmarkToggled = pyqtSignal(Editor)
203 syntaxerrorToggled = pyqtSignal(Editor)
204 previewStateChanged = pyqtSignal(bool)
205 astViewerStateChanged = pyqtSignal(bool)
206 editorLanguageChanged = pyqtSignal(Editor)
207 editorTextChanged = pyqtSignal(Editor)
208 editorLineChanged = pyqtSignal(str, int)
209 editorLineChangedEd = pyqtSignal(Editor, int)
210
211 def __init__(self, parent):
212 """
213 Constructor
214
215 @param parent parent widget
216 @type QWidget
217 """
218 self.stacks = []
219
220 self.__splitter = QSplitter(parent)
221 ViewManager.__init__(self)
222 self.__splitter.setChildrenCollapsible(False)
223
224 self.viewlist = QListWidget(self)
225 policy = self.viewlist.sizePolicy()
226 policy.setHorizontalPolicy(QSizePolicy.Policy.Ignored)
227 self.viewlist.setSizePolicy(policy)
228 self.__splitter.addWidget(self.viewlist)
229 self.viewlist.setContextMenuPolicy(
230 Qt.ContextMenuPolicy.CustomContextMenu)
231 self.viewlist.currentRowChanged.connect(self.__showSelectedView)
232 self.viewlist.customContextMenuRequested.connect(self.__showMenu)
233
234 self.stackArea = QSplitter(self)
235 self.stackArea.setChildrenCollapsible(False)
236 self.__splitter.addWidget(self.stackArea)
237 self.stackArea.setOrientation(Qt.Orientation.Vertical)
238 stack = StackedWidget(self.stackArea)
239 self.stackArea.addWidget(stack)
240 self.stacks.append(stack)
241 self.currentStack = stack
242 stack.currentChanged.connect(self.__currentChanged)
243 stack.installEventFilter(self)
244 self.__splitter.setSizes(
245 [int(self.width() * 0.2), int(self.width() * 0.8)])
246 # 20% for viewlist, 80% for the editors
247 self.__inRemoveView = False
248
249 self.__initMenu()
250 self.contextMenuEditor = None
251 self.contextMenuIndex = -1
252
253 def __initMenu(self):
254 """
255 Private method to initialize the viewlist context menu.
256 """
257 self.__menu = QMenu(self)
258 self.__menu.addAction(
259 UI.PixmapCache.getIcon("tabClose"),
260 self.tr('Close'), self.__contextMenuClose)
261 self.closeOthersMenuAct = self.__menu.addAction(
262 UI.PixmapCache.getIcon("tabCloseOther"),
263 self.tr("Close Others"),
264 self.__contextMenuCloseOthers)
265 self.__menu.addAction(
266 self.tr('Close All'), self.__contextMenuCloseAll)
267 self.__menu.addSeparator()
268 self.saveMenuAct = self.__menu.addAction(
269 UI.PixmapCache.getIcon("fileSave"),
270 self.tr('Save'), self.__contextMenuSave)
271 self.__menu.addAction(
272 UI.PixmapCache.getIcon("fileSaveAs"),
273 self.tr('Save As...'), self.__contextMenuSaveAs)
274 self.__menu.addAction(
275 UI.PixmapCache.getIcon("fileSaveAll"),
276 self.tr('Save All'), self.__contextMenuSaveAll)
277 self.__menu.addSeparator()
278 self.openRejectionsMenuAct = self.__menu.addAction(
279 self.tr("Open 'rejection' file"),
280 self.__contextMenuOpenRejections)
281 self.__menu.addSeparator()
282 self.__menu.addAction(
283 UI.PixmapCache.getIcon("print"),
284 self.tr('Print'), self.__contextMenuPrintFile)
285 self.__menu.addSeparator()
286 self.copyPathAct = self.__menu.addAction(
287 self.tr("Copy Path to Clipboard"),
288 self.__contextMenuCopyPathToClipboard)
289
290 def __showMenu(self, point):
291 """
292 Private slot to handle the customContextMenuRequested signal of
293 the viewlist.
294
295 @param point position to open the menu at
296 @type QPoint
297 """
298 if self.editors:
299 itm = self.viewlist.itemAt(point)
300 if itm is not None:
301 row = self.viewlist.row(itm)
302 self.contextMenuEditor = self.editors[row]
303 self.contextMenuIndex = row
304 if self.contextMenuEditor:
305 self.saveMenuAct.setEnabled(
306 self.contextMenuEditor.isModified())
307 fileName = self.contextMenuEditor.getFileName()
308 self.copyPathAct.setEnabled(bool(fileName))
309 if fileName:
310 rej = "{0}.rej".format(fileName)
311 self.openRejectionsMenuAct.setEnabled(
312 os.path.exists(rej))
313 else:
314 self.openRejectionsMenuAct.setEnabled(False)
315
316 self.closeOthersMenuAct.setEnabled(
317 self.viewlist.count() > 1)
318
319 self.__menu.popup(self.viewlist.mapToGlobal(point))
320
321 def mainWidget(self):
322 """
323 Public method to return a reference to the main Widget of a
324 specific view manager subclass.
325
326 @return reference to the main widget
327 @rtype QWidget
328 """
329 return self.__splitter
330
331 def canCascade(self):
332 """
333 Public method to signal if cascading of managed windows is available.
334
335 @return flag indicating cascading of windows is available
336 @rtype bool
337 """
338 return False
339
340 def canTile(self):
341 """
342 Public method to signal if tiling of managed windows is available.
343
344 @return flag indicating tiling of windows is available
345 @rtype bool
346 """
347 return False
348
349 def canSplit(self):
350 """
351 public method to signal if splitting of the view is available.
352
353 @return flag indicating splitting of the view is available
354 @rtype bool
355 """
356 return True
357
358 def tile(self):
359 """
360 Public method to tile the managed windows.
361 """
362 pass
363
364 def cascade(self):
365 """
366 Public method to cascade the managed windows.
367 """
368 pass
369
370 def _removeAllViews(self):
371 """
372 Protected method to remove all views (i.e. windows).
373 """
374 self.viewlist.clear()
375 for win in self.editors:
376 for stack in self.stacks:
377 if stack.hasEditor(win):
378 stack.removeWidget(win)
379 break
380 win.closeIt()
381
382 def _removeView(self, win):
383 """
384 Protected method to remove a view (i.e. window).
385
386 @param win editor window to be removed
387 @type Editor
388 """
389 self.__inRemoveView = True
390 ind = self.editors.index(win)
391 itm = self.viewlist.takeItem(ind)
392 if itm:
393 del itm
394 for stack in self.stacks:
395 if stack.hasEditor(win):
396 stack.removeWidget(win)
397 break
398 win.closeIt()
399 self.__inRemoveView = False
400 if ind > 0:
401 ind -= 1
402 else:
403 if len(self.editors) > 1:
404 ind = 1
405 else:
406 return
407 stack.setCurrentWidget(stack.firstEditor())
408 self._showView(self.editors[ind].parent())
409
410 aw = self.activeWindow()
411 fn = aw and aw.getFileName() or None
412 if fn:
413 self.changeCaption.emit(fn)
414 self.editorChanged.emit(fn)
415 self.editorLineChanged.emit(fn, aw.getCursorPosition()[0] + 1)
416 else:
417 self.changeCaption.emit("")
418 self.editorChangedEd.emit(aw)
419
420 def _addView(self, win, fn=None, noName="", addNext=False, indexes=None):
421 """
422 Protected method to add a view (i.e. window).
423
424 @param win editor assembly to be added
425 @type EditorAssembly
426 @param fn filename of this editor
427 @type str
428 @param noName name to be used for an unnamed editor
429 @type str
430 @param addNext flag indicating to add the view next to the current
431 view
432 @type bool
433 @param indexes of the editor, first the split view index, second the
434 index within the view
435 @type tuple of two int
436 """
437 editor = win.getEditor()
438 if not fn:
439 if not noName:
440 self.untitledCount += 1
441 noName = self.tr("Untitled {0}").format(self.untitledCount)
442 self.viewlist.addItem(noName)
443 editor.setNoName(noName)
444 else:
445 txt = os.path.basename(fn)
446 if not QFileInfo(fn).isWritable():
447 txt = self.tr("{0} (ro)").format(txt)
448 itm = QListWidgetItem(txt)
449 itm.setToolTip(fn)
450 self.viewlist.addItem(itm)
451 if indexes:
452 if indexes[0] < len(self.stacks):
453 stack = self.stacks[indexes[0]]
454 else:
455 stack = self.stacks[-1]
456 stack.addWidget(win)
457 else:
458 self.currentStack.addWidget(win)
459 self.currentStack.setCurrentWidget(win)
460 editor.captionChanged.connect(self.__captionChange)
461 editor.cursorLineChanged.connect(
462 lambda lineno: self.__cursorLineChanged(lineno, editor))
463
464 index = self.editors.index(editor)
465 self.viewlist.setCurrentRow(index)
466 editor.setFocus()
467 if fn:
468 self.changeCaption.emit(fn)
469 self.editorChanged.emit(fn)
470 self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1)
471 else:
472 self.changeCaption.emit("")
473 self.editorChangedEd.emit(editor)
474
475 def __captionChange(self, cap, editor):
476 """
477 Private method to handle caption change signals from the editor.
478
479 Updates the listwidget text to reflect the new caption information.
480
481 @param cap Caption for the editor
482 @type str
483 @param editor Editor to update the caption for
484 @type Editor
485 """
486 fn = editor.getFileName()
487 if fn:
488 self.setEditorName(editor, fn)
489
490 def __cursorLineChanged(self, lineno, editor):
491 """
492 Private slot to handle a change of the current editor's cursor line.
493
494 @param lineno line number of the editor's cursor (zero based)
495 @type int
496 @param editor reference to the editor
497 @type Editor
498 """
499 if editor:
500 fn = editor.getFileName()
501 if fn:
502 self.editorLineChanged.emit(fn, lineno + 1)
503 self.editorLineChangedEd.emit(editor, lineno + 1)
504
505 def _showView(self, win, fn=None):
506 """
507 Protected method to show a view (i.e. window).
508
509 @param win editor assembly to be shown
510 @type EditorAssembly
511 @param fn filename of this editor
512 @type string
513 """
514 editor = win.getEditor()
515 for stack in self.stacks:
516 if stack.hasEditor(editor):
517 stack.setCurrentWidget(win)
518 self.currentStack = stack
519 break
520 index = self.editors.index(editor)
521 self.viewlist.setCurrentRow(index)
522 editor.setFocus()
523 fn = editor.getFileName()
524 if fn:
525 self.changeCaption.emit(fn)
526 self.editorChanged.emit(fn)
527 self.editorLineChanged.emit(fn, editor.getCursorPosition()[0] + 1)
528 else:
529 self.changeCaption.emit("")
530 self.editorChangedEd.emit(editor)
531
532 def __showSelectedView(self, row):
533 """
534 Private slot called to show a view selected in the list.
535
536 @param row row number of the item clicked on
537 @type int
538 """
539 if row != -1:
540 self._showView(self.editors[row].parent())
541 self._checkActions(self.editors[row])
542
543 def activeWindow(self):
544 """
545 Public method to return the active (i.e. current) window.
546
547 @return reference to the active editor
548 @rtype EditorAssembly
549 """
550 return self.currentStack.currentWidget()
551
552 def showWindowMenu(self, windowMenu):
553 """
554 Public method to set up the viewmanager part of the Window menu.
555
556 @param windowMenu reference to the window menu
557 @type QMenu
558 """
559 pass
560
561 def _initWindowActions(self):
562 """
563 Protected method to define the user interface actions for window
564 handling.
565 """
566 pass
567
568 def setEditorName(self, editor, newName):
569 """
570 Public method to change the displayed name of the editor.
571
572 @param editor editor window to be changed
573 @type Editor
574 @param newName new name to be shown
575 @type str
576 """
577 if newName:
578 currentRow = self.viewlist.currentRow()
579 index = self.editors.index(editor)
580 txt = os.path.basename(newName)
581 if not QFileInfo(newName).isWritable():
582 txt = self.tr("{0} (ro)").format(txt)
583 itm = self.viewlist.item(index)
584 if itm:
585 itm.setText(txt)
586 itm.setToolTip(newName)
587 self.viewlist.setCurrentRow(currentRow)
588 self.changeCaption.emit(newName)
589
590 def _modificationStatusChanged(self, m, editor):
591 """
592 Protected slot to handle the modificationStatusChanged signal.
593
594 @param m flag indicating the modification status
595 @type bool
596 @param editor editor window changed
597 @type Editor
598 """
599 currentRow = self.viewlist.currentRow()
600 index = self.editors.index(editor)
601 keys = []
602 if m:
603 keys.append("fileModified")
604 if editor.hasSyntaxErrors():
605 keys.append("syntaxError22")
606 elif editor.hasWarnings():
607 keys.append("warning22")
608 if not keys:
609 keys.append("empty")
610 item = self.viewlist.item(index)
611 if item:
612 item.setIcon(UI.PixmapCache.getCombinedIcon(keys))
613 self.viewlist.setCurrentRow(currentRow)
614 self._checkActions(editor)
615
616 def _syntaxErrorToggled(self, editor):
617 """
618 Protected slot to handle the syntaxerrorToggled signal.
619
620 @param editor editor that sent the signal
621 @type Editor
622 """
623 currentRow = self.viewlist.currentRow()
624 index = self.editors.index(editor)
625 keys = []
626 if editor.isModified():
627 keys.append("fileModified")
628 if editor.hasSyntaxErrors():
629 keys.append("syntaxError22")
630 elif editor.hasWarnings():
631 keys.append("warning22")
632 if not keys:
633 keys.append("empty")
634 item = self.viewlist.item(index)
635 if item:
636 item.setIcon(UI.PixmapCache.getCombinedIcon(keys))
637 self.viewlist.setCurrentRow(currentRow)
638
639 ViewManager._syntaxErrorToggled(self, editor)
640
641 def addSplit(self):
642 """
643 Public method used to split the current view.
644 """
645 stack = StackedWidget(self.stackArea)
646 stack.show()
647 self.stackArea.addWidget(stack)
648 self.stacks.append(stack)
649 self.currentStack = stack
650 stack.currentChanged.connect(self.__currentChanged)
651 stack.installEventFilter(self)
652 size = (
653 self.stackArea.width()
654 if self.stackArea.orientation() == Qt.Orientation.Horizontal else
655 self.stackArea.height()
656 )
657 self.stackArea.setSizes(
658 [int(size / len(self.stacks))] * len(self.stacks))
659 self.splitRemoveAct.setEnabled(True)
660 self.nextSplitAct.setEnabled(True)
661 self.prevSplitAct.setEnabled(True)
662
663 @pyqtSlot()
664 def removeSplit(self, index=-1):
665 """
666 Public method used to remove the current split view or a split view
667 by index.
668
669 @param index index of the split to be removed (-1 means to
670 delete the current split)
671 @type int
672 @return flag indicating successful deletion
673 @rtype bool
674 """
675 if len(self.stacks) > 1:
676 if index == -1:
677 stack = self.currentStack
678 else:
679 if index < len(self.stacks):
680 stack = self.stacks[index]
681 else:
682 stack = self.stacks[-1]
683 res = True
684 savedEditors = stack.editors[:]
685 for editor in savedEditors:
686 res &= self.closeEditor(editor)
687 if res:
688 try:
689 i = self.stacks.index(stack)
690 except ValueError:
691 return True
692 if i == len(self.stacks) - 1:
693 i -= 1
694 self.stacks.remove(stack)
695 stack.close()
696 self.currentStack = self.stacks[i]
697 if len(self.stacks) == 1:
698 self.splitRemoveAct.setEnabled(False)
699 self.nextSplitAct.setEnabled(False)
700 self.prevSplitAct.setEnabled(False)
701 return True
702
703 return False
704
705 def splitCount(self):
706 """
707 Public method to get the number of splitted views.
708
709 @return number of splitted views
710 @rtype int
711 """
712 return len(self.stacks)
713
714 def setSplitCount(self, count):
715 """
716 Public method to set the number of split views.
717
718 @param count number of split views
719 @type int
720 """
721 if count > self.splitCount():
722 while self.splitCount() < count:
723 self.addSplit()
724 elif count < self.splitCount():
725 while self.splitCount() > count:
726 # use an arbitrarily large index to remove the last one
727 self.removeSplit(index=100)
728
729 def getSplitOrientation(self):
730 """
731 Public method to get the orientation of the split view.
732
733 @return orientation of the split
734 @rtype Qt.Orientation.Horizontal or Qt.Orientation.Vertical
735 """
736 return self.stackArea.orientation()
737
738 def setSplitOrientation(self, orientation):
739 """
740 Public method used to set the orientation of the split view.
741
742 @param orientation orientation of the split
743 @type Qt.Orientation.Horizontal or Qt.Orientation.Vertical
744 """
745 self.stackArea.setOrientation(orientation)
746
747 def nextSplit(self):
748 """
749 Public slot used to move to the next split.
750 """
751 aw = self.activeWindow()
752 _hasFocus = aw and aw.hasFocus()
753 ind = self.stacks.index(self.currentStack) + 1
754 if ind == len(self.stacks):
755 ind = 0
756
757 self.currentStack = self.stacks[ind]
758 if _hasFocus:
759 aw = self.activeWindow()
760 if aw:
761 aw.setFocus()
762
763 cw = self.currentStack.currentWidget()
764 if cw:
765 index = self.editors.index(cw)
766 self.viewlist.setCurrentRow(index)
767
768 def prevSplit(self):
769 """
770 Public slot used to move to the previous split.
771 """
772 aw = self.activeWindow()
773 _hasFocus = aw and aw.hasFocus()
774 ind = self.stacks.index(self.currentStack) - 1
775 if ind == -1:
776 ind = len(self.stacks) - 1
777
778 self.currentStack = self.stacks[ind]
779 if _hasFocus:
780 aw = self.activeWindow()
781 if aw:
782 aw.setFocus()
783
784 cw = self.currentStack.currentWidget()
785 if cw:
786 index = self.editors.index(cw)
787 self.viewlist.setCurrentRow(index)
788
789 def __contextMenuClose(self):
790 """
791 Private method to close the selected editor.
792 """
793 if self.contextMenuEditor:
794 self.closeEditorWindow(self.contextMenuEditor)
795
796 def __contextMenuCloseOthers(self):
797 """
798 Private method to close the other editors.
799 """
800 index = self.contextMenuIndex
801 for i in (
802 list(range(self.viewlist.count() - 1, index, -1)) +
803 list(range(index - 1, -1, -1))
804 ):
805 editor = self.editors[i]
806 self.closeEditorWindow(editor)
807
808 def __contextMenuCloseAll(self):
809 """
810 Private method to close all editors.
811 """
812 savedEditors = self.editors[:]
813 for editor in savedEditors:
814 self.closeEditorWindow(editor)
815
816 def __contextMenuSave(self):
817 """
818 Private method to save the selected editor.
819 """
820 if self.contextMenuEditor:
821 self.saveEditorEd(self.contextMenuEditor)
822
823 def __contextMenuSaveAs(self):
824 """
825 Private method to save the selected editor to a new file.
826 """
827 if self.contextMenuEditor:
828 self.saveAsEditorEd(self.contextMenuEditor)
829
830 def __contextMenuSaveAll(self):
831 """
832 Private method to save all editors.
833 """
834 self.saveEditorsList(self.editors)
835
836 def __contextMenuOpenRejections(self):
837 """
838 Private slot to open a rejections file associated with the selected
839 editor.
840 """
841 if self.contextMenuEditor:
842 fileName = self.contextMenuEditor.getFileName()
843 if fileName:
844 rej = "{0}.rej".format(fileName)
845 if os.path.exists(rej):
846 self.openSourceFile(rej)
847
848 def __contextMenuPrintFile(self):
849 """
850 Private method to print the selected editor.
851 """
852 if self.contextMenuEditor:
853 self.printEditor(self.contextMenuEditor)
854
855 def __contextMenuCopyPathToClipboard(self):
856 """
857 Private method to copy the file name of the selected editor to the
858 clipboard.
859 """
860 if self.contextMenuEditor:
861 fn = self.contextMenuEditor.getFileName()
862 if fn:
863 cb = QApplication.clipboard()
864 cb.setText(fn)
865
866 def __currentChanged(self, index):
867 """
868 Private slot to handle the currentChanged signal.
869
870 @param index index of the current editor
871 @type int
872 """
873 if index == -1 or not self.editors:
874 return
875
876 editor = self.activeWindow()
877 if editor is None:
878 return
879
880 self._checkActions(editor)
881 editor.setFocus()
882 fn = editor.getFileName()
883 if fn:
884 self.changeCaption.emit(fn)
885 if not self.__inRemoveView:
886 self.editorChanged.emit(fn)
887 self.editorLineChanged.emit(
888 fn, editor.getCursorPosition()[0] + 1)
889 else:
890 self.changeCaption.emit("")
891 self.editorChangedEd.emit(editor)
892
893 cindex = self.editors.index(editor)
894 self.viewlist.setCurrentRow(cindex)
895
896 def eventFilter(self, watched, event):
897 """
898 Public method called to filter the event queue.
899
900 @param watched the QObject being watched
901 @type QObject
902 @param event the event that occurred
903 @type QEvent
904 @return flag indicating, if we handled the event
905 @rtype bool
906 """
907 if (
908 event.type() == QEvent.Type.MouseButtonPress and
909 event.button() != Qt.MouseButton.RightButton
910 ):
911 switched = True
912 if isinstance(watched, QStackedWidget):
913 switched = watched is not self.currentStack
914 self.currentStack = watched
915 elif isinstance(watched, QScintilla.Editor.Editor):
916 for stack in self.stacks:
917 if stack.hasEditor(watched):
918 switched = stack is not self.currentStack
919 self.currentStack = stack
920 break
921 currentWidget = self.currentStack.currentWidget()
922 if currentWidget:
923 index = self.editors.index(currentWidget)
924 self.viewlist.setCurrentRow(index)
925
926 aw = self.activeWindow()
927 if aw is not None:
928 self._checkActions(aw)
929 aw.setFocus()
930 fn = aw.getFileName()
931 if fn:
932 self.changeCaption.emit(fn)
933 if switched:
934 self.editorChanged.emit(fn)
935 self.editorLineChanged.emit(
936 fn, aw.getCursorPosition()[0] + 1)
937 else:
938 self.changeCaption.emit("")
939 self.editorChangedEd.emit(aw)
940
941 return False
942
943 def getOpenEditorsForSession(self):
944 """
945 Public method to get a lists of all open editors.
946
947 The returned list contains one list per split view. If the view manager
948 cannot split the view, only one list of editors is returned.
949
950 @return list of list of editor references
951 @rtype list of list of Editor
952 """
953 editorLists = []
954 for stack in self.stacks:
955 editors = []
956 for index in range(stack.count()):
957 widget = stack.widget(index)
958 if isinstance(widget, EditorAssembly):
959 editor = widget.getEditor()
960 editors.append(editor)
961 editorLists.append(editors)
962 return editorLists

eric ide

mercurial