PrEditor 1.1.0__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PrEditor might be problematic. Click here for more details.
- preditor/__init__.py +4 -1
- preditor/about_module.py +6 -2
- preditor/dccs/.hab.json +10 -0
- preditor/dccs/maya/PrEditor_maya.mod +0 -1
- preditor/dccs/maya/README.md +22 -0
- preditor/dccs/maya/plug-ins/PrEditor_maya.py +32 -1
- preditor/dccs/studiomax/PackageContents.xml +32 -0
- preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr +8 -0
- preditor/dccs/studiomax/README.md +17 -0
- preditor/dccs/studiomax/preditor.ms +16 -0
- preditor/dccs/studiomax/preditor_menu.mnx +7 -0
- preditor/debug.py +7 -3
- preditor/excepthooks.py +1 -1
- preditor/gui/app.py +2 -2
- preditor/gui/codehighlighter.py +10 -24
- preditor/gui/completer.py +17 -6
- preditor/gui/console.py +94 -47
- preditor/gui/dialog.py +10 -7
- preditor/gui/drag_tab_bar.py +7 -7
- preditor/gui/errordialog.py +2 -2
- preditor/gui/find_files.py +7 -5
- preditor/gui/fuzzy_search/fuzzy_search.py +8 -4
- preditor/gui/group_tab_widget/__init__.py +32 -4
- preditor/gui/group_tab_widget/grouped_tab_models.py +4 -4
- preditor/gui/group_tab_widget/grouped_tab_widget.py +6 -4
- preditor/gui/level_buttons.py +16 -1
- preditor/gui/loggerwindow.py +48 -27
- preditor/gui/set_text_editor_path_dialog.py +3 -1
- preditor/gui/ui/loggerwindow.ui +11 -1
- preditor/gui/window.py +4 -4
- preditor/gui/workbox_mixin.py +43 -14
- preditor/gui/workbox_text_edit.py +7 -5
- preditor/gui/workboxwidget.py +25 -16
- preditor/logging_config.py +5 -2
- preditor/scintilla/__init__.py +19 -1
- preditor/scintilla/delayables/smart_highlight.py +7 -4
- preditor/scintilla/delayables/spell_check.py +5 -4
- preditor/scintilla/documenteditor.py +228 -135
- preditor/scintilla/finddialog.py +3 -3
- preditor/scintilla/lang/language.py +1 -1
- preditor/scintilla/lexers/cpplexer.py +3 -2
- preditor/scintilla/lexers/javascriptlexer.py +6 -4
- preditor/scintilla/lexers/maxscriptlexer.py +8 -7
- preditor/scintilla/lexers/mellexer.py +3 -2
- preditor/scintilla/lexers/mulexer.py +3 -2
- preditor/scintilla/lexers/pythonlexer.py +7 -6
- preditor/utils/cute.py +9 -8
- preditor/version.py +16 -3
- {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/METADATA +69 -32
- {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/RECORD +56 -47
- preditor-1.3.0.dist-info/top_level.txt +3 -0
- tests/find_files/test_find_files.py +74 -0
- tests/ide/test_delayable_engine.py +171 -0
- preditor-1.1.0.dist-info/top_level.txt +0 -1
- {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/WHEEL +0 -0
- {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/entry_points.txt +0 -0
- {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/licenses/LICENSE +0 -0
preditor/gui/console.py
CHANGED
|
@@ -15,7 +15,14 @@ from functools import partial
|
|
|
15
15
|
import __main__
|
|
16
16
|
from Qt import QtCompat
|
|
17
17
|
from Qt.QtCore import QPoint, Qt, QTimer
|
|
18
|
-
from Qt.QtGui import
|
|
18
|
+
from Qt.QtGui import (
|
|
19
|
+
QColor,
|
|
20
|
+
QFontMetrics,
|
|
21
|
+
QKeySequence,
|
|
22
|
+
QTextCharFormat,
|
|
23
|
+
QTextCursor,
|
|
24
|
+
QTextDocument,
|
|
25
|
+
)
|
|
19
26
|
from Qt.QtWidgets import QAbstractItemView, QAction, QApplication, QTextEdit
|
|
20
27
|
|
|
21
28
|
from .. import settings, stream
|
|
@@ -32,7 +39,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
32
39
|
|
|
33
40
|
# These Qt Properties can be customized using style sheets.
|
|
34
41
|
commentColor = QtPropertyInit('_commentColor', QColor(0, 206, 52))
|
|
35
|
-
errorMessageColor = QtPropertyInit('_errorMessageColor', QColor(Qt.red))
|
|
42
|
+
errorMessageColor = QtPropertyInit('_errorMessageColor', QColor(Qt.GlobalColor.red))
|
|
36
43
|
keywordColor = QtPropertyInit('_keywordColor', QColor(17, 154, 255))
|
|
37
44
|
resultColor = QtPropertyInit('_resultColor', QColor(128, 128, 128))
|
|
38
45
|
stdoutColor = QtPropertyInit('_stdoutColor', QColor(17, 154, 255))
|
|
@@ -56,6 +63,8 @@ class ConsolePrEdit(QTextEdit):
|
|
|
56
63
|
|
|
57
64
|
self._firstShow = True
|
|
58
65
|
|
|
66
|
+
self.addSepNewline = False
|
|
67
|
+
|
|
59
68
|
# When executing code, that takes longer than this seconds, flash the window
|
|
60
69
|
self.flash_time = 1.0
|
|
61
70
|
self.flash_window = None
|
|
@@ -99,7 +108,9 @@ class ConsolePrEdit(QTextEdit):
|
|
|
99
108
|
|
|
100
109
|
self.uiClearToLastPromptACT = QAction('Clear to Last', self)
|
|
101
110
|
self.uiClearToLastPromptACT.triggered.connect(self.clearToLastPrompt)
|
|
102
|
-
self.uiClearToLastPromptACT.setShortcut(
|
|
111
|
+
self.uiClearToLastPromptACT.setShortcut(
|
|
112
|
+
QKeySequence(Qt.Modifier.CTRL | Qt.Modifier.SHIFT | Qt.Key.Key_Backspace)
|
|
113
|
+
)
|
|
103
114
|
self.addAction(self.uiClearToLastPromptACT)
|
|
104
115
|
|
|
105
116
|
self.x = 0
|
|
@@ -155,8 +166,8 @@ class ConsolePrEdit(QTextEdit):
|
|
|
155
166
|
workbox = self.window().current_workbox()
|
|
156
167
|
if workbox:
|
|
157
168
|
tab_width = workbox.__tab_width__()
|
|
158
|
-
fontPixelWidth = QFontMetrics(font).
|
|
159
|
-
self.
|
|
169
|
+
fontPixelWidth = QFontMetrics(font).horizontalAdvance(" ")
|
|
170
|
+
self.setTabStopDistance(fontPixelWidth * tab_width)
|
|
160
171
|
|
|
161
172
|
# Scroll to same relative position where we started
|
|
162
173
|
if origPercent is not None:
|
|
@@ -170,7 +181,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
170
181
|
self.clickPos = event.pos()
|
|
171
182
|
self.anchor = self.anchorAt(event.pos())
|
|
172
183
|
if self.anchor:
|
|
173
|
-
QApplication.setOverrideCursor(Qt.PointingHandCursor)
|
|
184
|
+
QApplication.setOverrideCursor(Qt.CursorShape.PointingHandCursor)
|
|
174
185
|
return super(ConsolePrEdit, self).mousePressEvent(event)
|
|
175
186
|
|
|
176
187
|
def mouseReleaseEvent(self, event):
|
|
@@ -178,7 +189,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
178
189
|
click position is the same as release position, if so, call errorHyperlink.
|
|
179
190
|
"""
|
|
180
191
|
samePos = event.pos() == self.clickPos
|
|
181
|
-
left = event.button() == Qt.LeftButton
|
|
192
|
+
left = event.button() == Qt.MouseButton.LeftButton
|
|
182
193
|
if samePos and left and self.anchor:
|
|
183
194
|
self.errorHyperlink()
|
|
184
195
|
|
|
@@ -192,7 +203,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
192
203
|
# scrolling. If used in LoggerWindow, use that wheel event
|
|
193
204
|
# May not want to import LoggerWindow, so perhaps
|
|
194
205
|
# check by str(type())
|
|
195
|
-
ctrlPressed = event.modifiers() == Qt.ControlModifier
|
|
206
|
+
ctrlPressed = event.modifiers() == Qt.KeyboardModifier.ControlModifier
|
|
196
207
|
if ctrlPressed and "LoggerWindow" in str(type(self.window())):
|
|
197
208
|
self.window().wheelEvent(event)
|
|
198
209
|
else:
|
|
@@ -202,7 +213,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
202
213
|
"""Override of keyReleaseEvent to determine when to end navigation of
|
|
203
214
|
previous commands
|
|
204
215
|
"""
|
|
205
|
-
if event.key() == Qt.Key_Alt:
|
|
216
|
+
if event.key() == Qt.Key.Key_Alt:
|
|
206
217
|
self._prevCommandIndex = 0
|
|
207
218
|
else:
|
|
208
219
|
event.ignore()
|
|
@@ -319,7 +330,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
319
330
|
prevCommand = self._prevCommands[self._prevCommandIndex]
|
|
320
331
|
|
|
321
332
|
cursor = self.textCursor()
|
|
322
|
-
cursor.select(QTextCursor.LineUnderCursor)
|
|
333
|
+
cursor.select(QTextCursor.SelectionType.LineUnderCursor)
|
|
323
334
|
if cursor.selectedText().startswith(self._consolePrompt):
|
|
324
335
|
prevCommand = "{}{}".format(self._consolePrompt, prevCommand)
|
|
325
336
|
cursor.insertText(prevCommand)
|
|
@@ -335,7 +346,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
335
346
|
currentCursor = self.textCursor()
|
|
336
347
|
# move to the end of the document so we can search backwards
|
|
337
348
|
cursor = self.textCursor()
|
|
338
|
-
cursor.movePosition(
|
|
349
|
+
cursor.movePosition(QTextCursor.MoveOperation.End)
|
|
339
350
|
self.setTextCursor(cursor)
|
|
340
351
|
# Check if the last line is a empty prompt. If so, then preform two finds so we
|
|
341
352
|
# find the prompt we are looking for instead of this empty prompt
|
|
@@ -343,12 +354,14 @@ class ConsolePrEdit(QTextEdit):
|
|
|
343
354
|
2 if self.toPlainText()[-len(self.prompt()) :] == self.prompt() else 1
|
|
344
355
|
)
|
|
345
356
|
for _ in range(findCount):
|
|
346
|
-
self.find(self.prompt(), QTextDocument.FindBackward)
|
|
357
|
+
self.find(self.prompt(), QTextDocument.FindFlag.FindBackward)
|
|
347
358
|
# move to the end of the found line, select the rest of the text and remove it
|
|
348
359
|
# preserving history if there is anything to remove.
|
|
349
360
|
cursor = self.textCursor()
|
|
350
|
-
cursor.movePosition(
|
|
351
|
-
cursor.movePosition(
|
|
361
|
+
cursor.movePosition(QTextCursor.MoveOperation.EndOfLine)
|
|
362
|
+
cursor.movePosition(
|
|
363
|
+
QTextCursor.MoveOperation.End, QTextCursor.MoveMode.KeepAnchor
|
|
364
|
+
)
|
|
352
365
|
txt = cursor.selectedText()
|
|
353
366
|
if txt:
|
|
354
367
|
self.setTextCursor(cursor)
|
|
@@ -364,7 +377,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
364
377
|
if self.clearExecutionTime is not None:
|
|
365
378
|
self.clearExecutionTime()
|
|
366
379
|
cursor = self.textCursor()
|
|
367
|
-
cursor.select(QTextCursor.BlockUnderCursor)
|
|
380
|
+
cursor.select(QTextCursor.SelectionType.BlockUnderCursor)
|
|
368
381
|
line = cursor.selectedText()
|
|
369
382
|
if line and line[0] not in string.printable:
|
|
370
383
|
line = line[1:]
|
|
@@ -472,7 +485,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
472
485
|
"""inserts the completion text into the editor"""
|
|
473
486
|
if self.completer().widget() == self:
|
|
474
487
|
cursor = self.textCursor()
|
|
475
|
-
cursor.select(QTextCursor.WordUnderCursor)
|
|
488
|
+
cursor.select(QTextCursor.SelectionType.WordUnderCursor)
|
|
476
489
|
cursor.insertText(completion)
|
|
477
490
|
self.setTextCursor(cursor)
|
|
478
491
|
|
|
@@ -535,21 +548,21 @@ class ConsolePrEdit(QTextEdit):
|
|
|
535
548
|
# character, or remove it if backspace or delete has just been pressed.
|
|
536
549
|
key = event.text()
|
|
537
550
|
_, prefix = completer.currentObject(scope=__main__.__dict__)
|
|
538
|
-
isBackspaceOrDel = event.key() in (Qt.Key_Backspace, Qt.Key_Delete)
|
|
551
|
+
isBackspaceOrDel = event.key() in (Qt.Key.Key_Backspace, Qt.Key.Key_Delete)
|
|
539
552
|
if key.isalnum() or key in ("-", "_"):
|
|
540
553
|
prefix += str(key)
|
|
541
554
|
elif isBackspaceOrDel and prefix:
|
|
542
555
|
prefix = prefix[:-1]
|
|
543
556
|
|
|
544
557
|
if completer and event.key() in (
|
|
545
|
-
Qt.Key_Backspace,
|
|
546
|
-
Qt.Key_Delete,
|
|
547
|
-
Qt.Key_Escape,
|
|
558
|
+
Qt.Key.Key_Backspace,
|
|
559
|
+
Qt.Key.Key_Delete,
|
|
560
|
+
Qt.Key.Key_Escape,
|
|
548
561
|
):
|
|
549
562
|
completer.hideDocumentation()
|
|
550
563
|
|
|
551
564
|
# enter || return keys will execute the command
|
|
552
|
-
if event.key() in (Qt.Key_Return, Qt.Key_Enter):
|
|
565
|
+
if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
|
|
553
566
|
if completer.popup().isVisible():
|
|
554
567
|
completer.clear()
|
|
555
568
|
event.ignore()
|
|
@@ -557,11 +570,11 @@ class ConsolePrEdit(QTextEdit):
|
|
|
557
570
|
self.executeCommand()
|
|
558
571
|
|
|
559
572
|
# home key will move the cursor to home
|
|
560
|
-
elif event.key() == Qt.Key_Home:
|
|
573
|
+
elif event.key() == Qt.Key.Key_Home:
|
|
561
574
|
self.moveToHome()
|
|
562
575
|
|
|
563
576
|
# otherwise, ignore the event for completion events
|
|
564
|
-
elif event.key() in (Qt.Key_Tab, Qt.Key_Backtab):
|
|
577
|
+
elif event.key() in (Qt.Key.Key_Tab, Qt.Key.Key_Backtab):
|
|
565
578
|
if not completer.popup().isVisible():
|
|
566
579
|
# The completer does not get updated if its not visible while typing.
|
|
567
580
|
# We are about to complete the text using it so ensure its updated.
|
|
@@ -571,19 +584,28 @@ class ConsolePrEdit(QTextEdit):
|
|
|
571
584
|
)
|
|
572
585
|
# Insert the correct text and clear the completion model
|
|
573
586
|
index = completer.popup().currentIndex()
|
|
574
|
-
self.insertCompletion(index.data(Qt.DisplayRole))
|
|
587
|
+
self.insertCompletion(index.data(Qt.ItemDataRole.DisplayRole))
|
|
575
588
|
completer.clear()
|
|
576
589
|
|
|
577
|
-
elif event.key() == Qt.Key_Escape and completer.popup().isVisible():
|
|
590
|
+
elif event.key() == Qt.Key.Key_Escape and completer.popup().isVisible():
|
|
578
591
|
completer.clear()
|
|
579
592
|
|
|
580
593
|
# other wise handle the keypress
|
|
581
594
|
else:
|
|
582
595
|
# define special key sequences
|
|
583
596
|
modifiers = QApplication.instance().keyboardModifiers()
|
|
584
|
-
ctrlSpace =
|
|
585
|
-
|
|
586
|
-
|
|
597
|
+
ctrlSpace = (
|
|
598
|
+
event.key() == Qt.Key.Key_Space
|
|
599
|
+
and modifiers == Qt.KeyboardModifier.ControlModifier
|
|
600
|
+
)
|
|
601
|
+
ctrlM = (
|
|
602
|
+
event.key() == Qt.Key.Key_M
|
|
603
|
+
and modifiers == Qt.KeyboardModifier.ControlModifier
|
|
604
|
+
)
|
|
605
|
+
ctrlI = (
|
|
606
|
+
event.key() == Qt.Key.Key_I
|
|
607
|
+
and modifiers == Qt.KeyboardModifier.ControlModifier
|
|
608
|
+
)
|
|
587
609
|
|
|
588
610
|
# Process all events we do not want to override
|
|
589
611
|
if not (ctrlSpace or ctrlM or ctrlI):
|
|
@@ -602,20 +624,20 @@ class ConsolePrEdit(QTextEdit):
|
|
|
602
624
|
# check for particular events for the completion
|
|
603
625
|
if completer:
|
|
604
626
|
# look for documentation popups
|
|
605
|
-
if event.key() == Qt.Key_ParenLeft:
|
|
627
|
+
if event.key() == Qt.Key.Key_ParenLeft:
|
|
606
628
|
rect = self.cursorRect()
|
|
607
629
|
point = self.mapToGlobal(QPoint(rect.x(), rect.y()))
|
|
608
630
|
completer.showDocumentation(pos=point, scope=__main__.__dict__)
|
|
609
631
|
|
|
610
632
|
# hide documentation popups
|
|
611
|
-
elif event.key() == Qt.Key_ParenRight:
|
|
633
|
+
elif event.key() == Qt.Key.Key_ParenRight:
|
|
612
634
|
completer.hideDocumentation()
|
|
613
635
|
|
|
614
636
|
# determine if we need to show the popup or if it already is visible, we
|
|
615
637
|
# need to update it
|
|
616
638
|
elif (
|
|
617
|
-
event.key() == Qt.Key_Period
|
|
618
|
-
or event.key() == Qt.Key_Escape
|
|
639
|
+
event.key() == Qt.Key.Key_Period
|
|
640
|
+
or event.key() == Qt.Key.Key_Escape
|
|
619
641
|
or completer.popup().isVisible()
|
|
620
642
|
or ctrlSpace
|
|
621
643
|
or ctrlI
|
|
@@ -646,7 +668,9 @@ class ConsolePrEdit(QTextEdit):
|
|
|
646
668
|
completer.setCurrentRow(index.row())
|
|
647
669
|
|
|
648
670
|
# Make sure that current selection is visible, ie scroll to it
|
|
649
|
-
completer.popup().scrollTo(
|
|
671
|
+
completer.popup().scrollTo(
|
|
672
|
+
index, QAbstractItemView.ScrollHint.EnsureVisible
|
|
673
|
+
)
|
|
650
674
|
|
|
651
675
|
# show the completer for the rect
|
|
652
676
|
rect = self.cursorRect()
|
|
@@ -663,7 +687,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
663
687
|
if completer.wasCompleting and not completer.popup().isVisible():
|
|
664
688
|
wasCompletingCounterMax = completer.wasCompletingCounterMax
|
|
665
689
|
if completer.wasCompletingCounter <= wasCompletingCounterMax:
|
|
666
|
-
if event.key() not in (Qt.Key_Backspace, Qt.Key_Left):
|
|
690
|
+
if event.key() not in (Qt.Key.Key_Backspace, Qt.Key.Key_Left):
|
|
667
691
|
completer.wasCompletingCounter += 1
|
|
668
692
|
else:
|
|
669
693
|
completer.wasCompletingCounter = 0
|
|
@@ -671,20 +695,26 @@ class ConsolePrEdit(QTextEdit):
|
|
|
671
695
|
|
|
672
696
|
def moveToHome(self):
|
|
673
697
|
"""moves the cursor to the home location"""
|
|
674
|
-
mode = QTextCursor.MoveAnchor
|
|
698
|
+
mode = QTextCursor.MoveMode.MoveAnchor
|
|
675
699
|
# select the home
|
|
676
|
-
if
|
|
677
|
-
|
|
700
|
+
if (
|
|
701
|
+
QApplication.instance().keyboardModifiers()
|
|
702
|
+
== Qt.KeyboardModifier.ShiftModifier
|
|
703
|
+
):
|
|
704
|
+
mode = QTextCursor.MoveMode.KeepAnchor
|
|
678
705
|
# grab the cursor
|
|
679
706
|
cursor = self.textCursor()
|
|
680
|
-
if
|
|
707
|
+
if (
|
|
708
|
+
QApplication.instance().keyboardModifiers()
|
|
709
|
+
== Qt.KeyboardModifier.ControlModifier
|
|
710
|
+
):
|
|
681
711
|
# move to the top of the document if control is pressed
|
|
682
|
-
cursor.movePosition(QTextCursor.Start)
|
|
712
|
+
cursor.movePosition(QTextCursor.MoveOperation.Start)
|
|
683
713
|
else:
|
|
684
714
|
# Otherwise just move it to the start of the line
|
|
685
|
-
cursor.movePosition(QTextCursor.StartOfBlock, mode)
|
|
715
|
+
cursor.movePosition(QTextCursor.MoveOperation.StartOfBlock, mode)
|
|
686
716
|
# move the cursor to the end of the prompt.
|
|
687
|
-
cursor.movePosition(QTextCursor.Right, mode, len(self.prompt()))
|
|
717
|
+
cursor.movePosition(QTextCursor.MoveOperation.Right, mode, len(self.prompt()))
|
|
688
718
|
self.setTextCursor(cursor)
|
|
689
719
|
|
|
690
720
|
def outputPrompt(self):
|
|
@@ -721,7 +751,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
721
751
|
prompt(str): The prompt to start the line with. If this prompt
|
|
722
752
|
is already the only text on the last line this function does nothing.
|
|
723
753
|
"""
|
|
724
|
-
self.moveCursor(QTextCursor.End)
|
|
754
|
+
self.moveCursor(QTextCursor.MoveOperation.End)
|
|
725
755
|
|
|
726
756
|
# if this is not already a new line
|
|
727
757
|
if self.textCursor().block().text() != prompt:
|
|
@@ -744,9 +774,11 @@ class ConsolePrEdit(QTextEdit):
|
|
|
744
774
|
self.startPrompt(self._outputPrompt)
|
|
745
775
|
|
|
746
776
|
def removeCurrentLine(self):
|
|
747
|
-
self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
|
|
748
|
-
self.moveCursor(
|
|
749
|
-
|
|
777
|
+
self.moveCursor(QTextCursor.MoveOperation.End, QTextCursor.MoveMode.MoveAnchor)
|
|
778
|
+
self.moveCursor(
|
|
779
|
+
QTextCursor.MoveOperation.StartOfLine, QTextCursor.MoveMode.MoveAnchor
|
|
780
|
+
)
|
|
781
|
+
self.moveCursor(QTextCursor.MoveOperation.End, QTextCursor.MoveMode.KeepAnchor)
|
|
750
782
|
self.textCursor().removeSelectedText()
|
|
751
783
|
self.textCursor().deletePreviousChar()
|
|
752
784
|
self.insertPlainText("\n")
|
|
@@ -787,7 +819,11 @@ class ConsolePrEdit(QTextEdit):
|
|
|
787
819
|
hasattr(window, 'uiErrorHyperlinksACT')
|
|
788
820
|
and window.uiErrorHyperlinksACT.isChecked()
|
|
789
821
|
)
|
|
790
|
-
|
|
822
|
+
sepPreditorTrace = (
|
|
823
|
+
hasattr(window, 'uiSeparateTracebackACT')
|
|
824
|
+
and window.uiSeparateTracebackACT.isChecked()
|
|
825
|
+
)
|
|
826
|
+
self.moveCursor(QTextCursor.MoveOperation.End)
|
|
791
827
|
|
|
792
828
|
charFormat = QTextCharFormat()
|
|
793
829
|
if not error:
|
|
@@ -806,7 +842,7 @@ class ConsolePrEdit(QTextEdit):
|
|
|
806
842
|
info = None
|
|
807
843
|
|
|
808
844
|
if doHyperlink and msg == '\n':
|
|
809
|
-
cursor.select(QTextCursor.BlockUnderCursor)
|
|
845
|
+
cursor.select(QTextCursor.SelectionType.BlockUnderCursor)
|
|
810
846
|
line = cursor.selectedText()
|
|
811
847
|
|
|
812
848
|
# Remove possible leading unicode paragraph separator, which really
|
|
@@ -825,6 +861,17 @@ class ConsolePrEdit(QTextEdit):
|
|
|
825
861
|
filename = info.get("filename", "") if info else ""
|
|
826
862
|
isConsolePrEdit = '<ConsolePrEdit>' in filename
|
|
827
863
|
|
|
864
|
+
# To make it easier to see relevant lines of a traceback, optionally insert
|
|
865
|
+
# a newline separating internal PrEditor code from the code run by user.
|
|
866
|
+
if self.addSepNewline:
|
|
867
|
+
if sepPreditorTrace:
|
|
868
|
+
msg += "\n"
|
|
869
|
+
self.addSepNewline = False
|
|
870
|
+
|
|
871
|
+
preditorCalls = ("cmdresult = e", "exec(compiled,")
|
|
872
|
+
if msg.strip().startswith(preditorCalls):
|
|
873
|
+
self.addSepNewline = True
|
|
874
|
+
|
|
828
875
|
if info and doHyperlink and not isConsolePrEdit:
|
|
829
876
|
fileStart = info.get("fileStart")
|
|
830
877
|
fileEnd = info.get("fileEnd")
|
preditor/gui/dialog.py
CHANGED
|
@@ -24,11 +24,14 @@ class Dialog(QDialog):
|
|
|
24
24
|
if not cls._instance:
|
|
25
25
|
cls._instance = cls(parent=parent)
|
|
26
26
|
# protect the memory
|
|
27
|
-
cls._instance.setAttribute(Qt.WA_DeleteOnClose, False)
|
|
27
|
+
cls._instance.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, False)
|
|
28
28
|
return cls._instance
|
|
29
29
|
|
|
30
30
|
def __init__(
|
|
31
|
-
self,
|
|
31
|
+
self,
|
|
32
|
+
parent=None,
|
|
33
|
+
flags=Qt.WindowType.WindowMinMaxButtonsHint
|
|
34
|
+
| Qt.WindowType.WindowCloseButtonHint,
|
|
32
35
|
):
|
|
33
36
|
# if there is no root, create
|
|
34
37
|
if not parent:
|
|
@@ -68,7 +71,7 @@ class Dialog(QDialog):
|
|
|
68
71
|
# dead dialogs
|
|
69
72
|
|
|
70
73
|
# set the delete attribute to clean up the window once it is closed
|
|
71
|
-
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
74
|
+
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, True)
|
|
72
75
|
|
|
73
76
|
# set this property to true to properly handle tracking events to control
|
|
74
77
|
# keyboard overrides
|
|
@@ -109,7 +112,7 @@ class Dialog(QDialog):
|
|
|
109
112
|
def closeEvent(self, event):
|
|
110
113
|
# ensure this object gets deleted
|
|
111
114
|
wwidget = None
|
|
112
|
-
if self.testAttribute(Qt.WA_DeleteOnClose):
|
|
115
|
+
if self.testAttribute(Qt.WidgetAttribute.WA_DeleteOnClose):
|
|
113
116
|
# collect the win widget to uncache it
|
|
114
117
|
if self.parent() and self.parent().inherits('QWinWidget'):
|
|
115
118
|
wwidget = self.parent()
|
|
@@ -128,10 +131,10 @@ class Dialog(QDialog):
|
|
|
128
131
|
# This function properly transfers ownership of the dialog instance back to
|
|
129
132
|
# Python anyway
|
|
130
133
|
|
|
131
|
-
self.setAttribute(Qt.WA_DeleteOnClose, False)
|
|
134
|
+
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, False)
|
|
132
135
|
|
|
133
136
|
# execute the dialog
|
|
134
|
-
return
|
|
137
|
+
return super().exec()
|
|
135
138
|
|
|
136
139
|
def setGeometry(self, *args):
|
|
137
140
|
"""
|
|
@@ -158,7 +161,7 @@ class Dialog(QDialog):
|
|
|
158
161
|
# allow the global instance to be cleared
|
|
159
162
|
if this == cls._instance:
|
|
160
163
|
cls._instance = None
|
|
161
|
-
this.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
164
|
+
this.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, True)
|
|
162
165
|
try:
|
|
163
166
|
this.close()
|
|
164
167
|
except RuntimeError:
|
preditor/gui/drag_tab_bar.py
CHANGED
|
@@ -52,12 +52,12 @@ class DragTabBar(QTabBar):
|
|
|
52
52
|
drag.setMimeData(self._mime_data)
|
|
53
53
|
drag.setPixmap(self._mime_data.imageData())
|
|
54
54
|
drag.setHotSpot(event_pos - pos_in_tab)
|
|
55
|
-
cursor = QCursor(Qt.OpenHandCursor)
|
|
56
|
-
drag.setDragCursor(cursor.pixmap(), Qt.MoveAction)
|
|
57
|
-
action = drag.
|
|
55
|
+
cursor = QCursor(Qt.CursorShape.OpenHandCursor)
|
|
56
|
+
drag.setDragCursor(cursor.pixmap(), Qt.DropAction.MoveAction)
|
|
57
|
+
action = drag.exec(Qt.DropAction.MoveAction)
|
|
58
58
|
# If the user didn't successfully add this to a new tab widget, restore
|
|
59
59
|
# the tab to the original location.
|
|
60
|
-
if action == Qt.IgnoreAction:
|
|
60
|
+
if action == Qt.DropAction.IgnoreAction:
|
|
61
61
|
original_tab_index = self._mime_data.property('original_tab_index')
|
|
62
62
|
self.parentWidget().insertTab(
|
|
63
63
|
original_tab_index, widget, self._mime_data.text()
|
|
@@ -66,7 +66,7 @@ class DragTabBar(QTabBar):
|
|
|
66
66
|
self._mime_data = None
|
|
67
67
|
|
|
68
68
|
def mousePressEvent(self, event): # noqa: N802
|
|
69
|
-
if event.button() == Qt.LeftButton and not self._mime_data:
|
|
69
|
+
if event.button() == Qt.MouseButton.LeftButton and not self._mime_data:
|
|
70
70
|
tab_index = self.tabAt(event.pos())
|
|
71
71
|
|
|
72
72
|
# While we don't remove the tab on mouse press, capture its tab image
|
|
@@ -123,7 +123,7 @@ class DragTabBar(QTabBar):
|
|
|
123
123
|
if event.source().parentWidget() == self:
|
|
124
124
|
return
|
|
125
125
|
|
|
126
|
-
event.setDropAction(Qt.MoveAction)
|
|
126
|
+
event.setDropAction(Qt.DropAction.MoveAction)
|
|
127
127
|
event.accept()
|
|
128
128
|
counter = self.count()
|
|
129
129
|
|
|
@@ -184,7 +184,7 @@ class DragTabBar(QTabBar):
|
|
|
184
184
|
tab_widget.setDocumentMode(True)
|
|
185
185
|
|
|
186
186
|
if menu:
|
|
187
|
-
bar.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
187
|
+
bar.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
|
188
188
|
bar.customContextMenuRequested.connect(bar.tab_menu)
|
|
189
189
|
|
|
190
190
|
return bar
|
preditor/gui/errordialog.py
CHANGED
|
@@ -21,7 +21,7 @@ class ErrorDialog(Dialog):
|
|
|
21
21
|
|
|
22
22
|
self.parent_ = parent
|
|
23
23
|
self.setWindowTitle('Error Occurred')
|
|
24
|
-
self.uiErrorLBL.setTextFormat(Qt.RichText)
|
|
24
|
+
self.uiErrorLBL.setTextFormat(Qt.TextFormat.RichText)
|
|
25
25
|
self.uiIconLBL.setPixmap(
|
|
26
26
|
QPixmap(
|
|
27
27
|
os.path.join(
|
|
@@ -30,7 +30,7 @@ class ErrorDialog(Dialog):
|
|
|
30
30
|
'img',
|
|
31
31
|
'warning-big.png',
|
|
32
32
|
)
|
|
33
|
-
).scaledToHeight(64, Qt.SmoothTransformation)
|
|
33
|
+
).scaledToHeight(64, Qt.TransformationMode.SmoothTransformation)
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
self.uiLoggerBTN.clicked.connect(self.show_logger)
|
preditor/gui/find_files.py
CHANGED
|
@@ -30,22 +30,24 @@ class FindFiles(QWidget):
|
|
|
30
30
|
|
|
31
31
|
# Create shortcuts
|
|
32
32
|
self.uiCloseSCT = QShortcut(
|
|
33
|
-
QKeySequence(Qt.Key_Escape),
|
|
33
|
+
QKeySequence(Qt.Key.Key_Escape),
|
|
34
|
+
self,
|
|
35
|
+
context=Qt.ShortcutContext.WidgetWithChildrenShortcut,
|
|
34
36
|
)
|
|
35
37
|
|
|
36
38
|
self.uiCloseSCT.activated.connect(self.hide)
|
|
37
39
|
|
|
38
40
|
self.uiCaseSensitiveSCT = QShortcut(
|
|
39
|
-
QKeySequence(Qt.AltModifier | Qt.Key_C),
|
|
41
|
+
QKeySequence(Qt.KeyboardModifier.AltModifier | Qt.Key.Key_C),
|
|
40
42
|
self,
|
|
41
|
-
context=Qt.WidgetWithChildrenShortcut,
|
|
43
|
+
context=Qt.ShortcutContext.WidgetWithChildrenShortcut,
|
|
42
44
|
)
|
|
43
45
|
self.uiCaseSensitiveSCT.activated.connect(self.uiCaseSensitiveBTN.toggle)
|
|
44
46
|
|
|
45
47
|
self.uiRegexSCT = QShortcut(
|
|
46
|
-
QKeySequence(Qt.AltModifier | Qt.Key_R),
|
|
48
|
+
QKeySequence(Qt.KeyboardModifier.AltModifier | Qt.Key.Key_R),
|
|
47
49
|
self,
|
|
48
|
-
context=Qt.WidgetWithChildrenShortcut,
|
|
50
|
+
context=Qt.ShortcutContext.WidgetWithChildrenShortcut,
|
|
49
51
|
)
|
|
50
52
|
self.uiRegexSCT.activated.connect(self.uiRegexBTN.toggle)
|
|
51
53
|
|
|
@@ -22,14 +22,18 @@ class FuzzySearch(QFrame):
|
|
|
22
22
|
self.y_offset = 100
|
|
23
23
|
self.setMinimumSize(400, 200)
|
|
24
24
|
self.uiCloseSCT = QShortcut(
|
|
25
|
-
Qt.Key_Escape,
|
|
25
|
+
Qt.Key.Key_Escape,
|
|
26
|
+
self,
|
|
27
|
+
context=Qt.ShortcutContext.WidgetWithChildrenShortcut,
|
|
26
28
|
)
|
|
27
29
|
self.uiCloseSCT.activated.connect(self._canceled)
|
|
28
30
|
|
|
29
|
-
self.uiUpSCT = QShortcut(
|
|
31
|
+
self.uiUpSCT = QShortcut(
|
|
32
|
+
Qt.Key.Key_Up, self, context=Qt.ShortcutContext.WidgetWithChildrenShortcut
|
|
33
|
+
)
|
|
30
34
|
self.uiUpSCT.activated.connect(partial(self.increment_selection, -1))
|
|
31
35
|
self.uiDownSCT = QShortcut(
|
|
32
|
-
Qt.Key_Down, self, context=Qt.WidgetWithChildrenShortcut
|
|
36
|
+
Qt.Key.Key_Down, self, context=Qt.ShortcutContext.WidgetWithChildrenShortcut
|
|
33
37
|
)
|
|
34
38
|
self.uiDownSCT.activated.connect(partial(self.increment_selection, 1))
|
|
35
39
|
|
|
@@ -90,4 +94,4 @@ class FuzzySearch(QFrame):
|
|
|
90
94
|
def popup(self):
|
|
91
95
|
self.show()
|
|
92
96
|
self.reposition()
|
|
93
|
-
self.uiLineEDIT.setFocus(Qt.PopupFocusReason)
|
|
97
|
+
self.uiLineEDIT.setFocus(Qt.FocusReason.PopupFocusReason)
|
|
@@ -61,13 +61,13 @@ class GroupTabWidget(OneTabWidget):
|
|
|
61
61
|
corner.uiMenuBTN = QToolButton(corner)
|
|
62
62
|
corner.uiMenuBTN.setIcon(QIcon(resourcePath('img/chevron-down.png')))
|
|
63
63
|
corner.uiMenuBTN.setObjectName('group_tab_widget_menu_btn')
|
|
64
|
-
corner.uiMenuBTN.setPopupMode(QToolButton.InstantPopup)
|
|
64
|
+
corner.uiMenuBTN.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
|
|
65
65
|
corner.uiCornerMENU = GroupTabMenu(self, parent=corner.uiMenuBTN)
|
|
66
66
|
corner.uiMenuBTN.setMenu(corner.uiCornerMENU)
|
|
67
67
|
lyt.addWidget(corner.uiMenuBTN)
|
|
68
68
|
|
|
69
69
|
self.uiCornerBTN = corner
|
|
70
|
-
self.setCornerWidget(self.uiCornerBTN, Qt.TopRightCorner)
|
|
70
|
+
self.setCornerWidget(self.uiCornerBTN, Qt.Corner.TopRightCorner)
|
|
71
71
|
|
|
72
72
|
def add_new_tab(self, group, title="Workbox", group_fmt=None):
|
|
73
73
|
"""Adds a new tab to the requested group, creating the group if the group
|
|
@@ -148,9 +148,9 @@ class GroupTabWidget(OneTabWidget):
|
|
|
148
148
|
'Are you sure you want to close all tabs under the "{}" tab?'.format(
|
|
149
149
|
self.tabText(self.currentIndex())
|
|
150
150
|
),
|
|
151
|
-
QMessageBox.Yes | QMessageBox.Cancel,
|
|
151
|
+
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.Cancel,
|
|
152
152
|
)
|
|
153
|
-
if ret == QMessageBox.Yes:
|
|
153
|
+
if ret == QMessageBox.StandardButton.Yes:
|
|
154
154
|
# Clean up all temp files created by this group's editors if they
|
|
155
155
|
# are not using actual saved files.
|
|
156
156
|
tab_widget = self.widget(self.currentIndex())
|
|
@@ -323,3 +323,31 @@ class GroupTabWidget(OneTabWidget):
|
|
|
323
323
|
tab_widget = self.currentWidget()
|
|
324
324
|
tab_widget.setCurrentIndex(editor)
|
|
325
325
|
return tab_widget.currentWidget()
|
|
326
|
+
|
|
327
|
+
def set_current_groups_from_workbox(self, workbox):
|
|
328
|
+
"""Make the specified workbox the current widget. If the workbox is not
|
|
329
|
+
found, the current widget is not changed.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
workbox (WorkboxMixin): The workbox to make current.
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
success (bool): Whether the workbox was found and made the current
|
|
336
|
+
widget
|
|
337
|
+
"""
|
|
338
|
+
workbox_infos = self.all_widgets()
|
|
339
|
+
found_info = None
|
|
340
|
+
for workbox_info in workbox_infos:
|
|
341
|
+
if workbox_info[0] == workbox:
|
|
342
|
+
found_info = workbox_info
|
|
343
|
+
break
|
|
344
|
+
if found_info:
|
|
345
|
+
workbox = workbox_info[0]
|
|
346
|
+
group_idx = workbox_info[-2]
|
|
347
|
+
editor_idx = workbox_info[-1]
|
|
348
|
+
|
|
349
|
+
self.setCurrentIndex(group_idx)
|
|
350
|
+
tab_widget = self.currentWidget()
|
|
351
|
+
tab_widget.setCurrentIndex(editor_idx)
|
|
352
|
+
|
|
353
|
+
return bool(found_info)
|
|
@@ -7,7 +7,7 @@ from Qt.QtGui import QStandardItem, QStandardItemModel
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class GroupTabItemModel(QStandardItemModel):
|
|
10
|
-
GroupIndexRole = Qt.UserRole + 1
|
|
10
|
+
GroupIndexRole = Qt.ItemDataRole.UserRole + 1
|
|
11
11
|
TabIndexRole = GroupIndexRole + 1
|
|
12
12
|
|
|
13
13
|
def __init__(self, manager, *args, **kwargs):
|
|
@@ -24,7 +24,7 @@ class GroupTabItemModel(QStandardItemModel):
|
|
|
24
24
|
def pathFromIndex(self, index):
|
|
25
25
|
parts = [""]
|
|
26
26
|
while index.isValid():
|
|
27
|
-
parts.append(self.data(index, Qt.DisplayRole))
|
|
27
|
+
parts.append(self.data(index, Qt.ItemDataRole.DisplayRole))
|
|
28
28
|
index = index.parent()
|
|
29
29
|
if len(parts) == 1:
|
|
30
30
|
return ""
|
|
@@ -56,7 +56,7 @@ class GroupTabTreeItemModel(GroupTabItemModel):
|
|
|
56
56
|
|
|
57
57
|
class GroupTabListItemModel(GroupTabItemModel):
|
|
58
58
|
def flags(self, index):
|
|
59
|
-
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
|
|
59
|
+
return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable
|
|
60
60
|
|
|
61
61
|
def process(self):
|
|
62
62
|
root = self.invisibleRootItem()
|
|
@@ -101,7 +101,7 @@ class GroupTabFuzzyFilterProxyModel(QSortFilterProxyModel):
|
|
|
101
101
|
def pathFromIndex(self, index):
|
|
102
102
|
parts = [""]
|
|
103
103
|
while index.isValid():
|
|
104
|
-
parts.append(self.data(index, Qt.DisplayRole))
|
|
104
|
+
parts.append(self.data(index, Qt.ItemDataRole.DisplayRole))
|
|
105
105
|
index = index.parent()
|
|
106
106
|
if len(parts) == 1:
|
|
107
107
|
return ""
|
|
@@ -25,7 +25,7 @@ class GroupedTabWidget(OneTabWidget):
|
|
|
25
25
|
self.uiCornerBTN.setText('+')
|
|
26
26
|
self.uiCornerBTN.setIcon(QIcon(resourcePath('img/file-plus.png')))
|
|
27
27
|
self.uiCornerBTN.released.connect(lambda: self.add_new_editor())
|
|
28
|
-
self.setCornerWidget(self.uiCornerBTN, Qt.TopRightCorner)
|
|
28
|
+
self.setCornerWidget(self.uiCornerBTN, Qt.Corner.TopRightCorner)
|
|
29
29
|
|
|
30
30
|
def add_new_editor(self, title="Workbox"):
|
|
31
31
|
editor, title = self.default_tab(title)
|
|
@@ -41,16 +41,18 @@ class GroupedTabWidget(OneTabWidget):
|
|
|
41
41
|
def close_tab(self, index):
|
|
42
42
|
if self.count() == 1:
|
|
43
43
|
msg = "You have to leave at least one tab open."
|
|
44
|
-
QMessageBox.critical(
|
|
44
|
+
QMessageBox.critical(
|
|
45
|
+
self, 'Tab can not be closed.', msg, QMessageBox.StandardButton.Ok
|
|
46
|
+
)
|
|
45
47
|
return
|
|
46
48
|
ret = QMessageBox.question(
|
|
47
49
|
self,
|
|
48
50
|
'Donate to the cause?',
|
|
49
51
|
"Would you like to donate this tabs contents to the /dev/null fund "
|
|
50
52
|
"for wayward code?",
|
|
51
|
-
QMessageBox.Yes | QMessageBox.Cancel,
|
|
53
|
+
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.Cancel,
|
|
52
54
|
)
|
|
53
|
-
if ret == QMessageBox.Yes:
|
|
55
|
+
if ret == QMessageBox.StandardButton.Yes:
|
|
54
56
|
# If the tab was saved to a temp file, remove it from disk
|
|
55
57
|
editor = self.widget(index)
|
|
56
58
|
editor.__remove_tempfile__()
|