src/eric7/Plugins/ViewManagerPlugins/Listspace/Listspace.py

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

eric ide

mercurial