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.

Files changed (57) hide show
  1. preditor/__init__.py +4 -1
  2. preditor/about_module.py +6 -2
  3. preditor/dccs/.hab.json +10 -0
  4. preditor/dccs/maya/PrEditor_maya.mod +0 -1
  5. preditor/dccs/maya/README.md +22 -0
  6. preditor/dccs/maya/plug-ins/PrEditor_maya.py +32 -1
  7. preditor/dccs/studiomax/PackageContents.xml +32 -0
  8. preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr +8 -0
  9. preditor/dccs/studiomax/README.md +17 -0
  10. preditor/dccs/studiomax/preditor.ms +16 -0
  11. preditor/dccs/studiomax/preditor_menu.mnx +7 -0
  12. preditor/debug.py +7 -3
  13. preditor/excepthooks.py +1 -1
  14. preditor/gui/app.py +2 -2
  15. preditor/gui/codehighlighter.py +10 -24
  16. preditor/gui/completer.py +17 -6
  17. preditor/gui/console.py +94 -47
  18. preditor/gui/dialog.py +10 -7
  19. preditor/gui/drag_tab_bar.py +7 -7
  20. preditor/gui/errordialog.py +2 -2
  21. preditor/gui/find_files.py +7 -5
  22. preditor/gui/fuzzy_search/fuzzy_search.py +8 -4
  23. preditor/gui/group_tab_widget/__init__.py +32 -4
  24. preditor/gui/group_tab_widget/grouped_tab_models.py +4 -4
  25. preditor/gui/group_tab_widget/grouped_tab_widget.py +6 -4
  26. preditor/gui/level_buttons.py +16 -1
  27. preditor/gui/loggerwindow.py +48 -27
  28. preditor/gui/set_text_editor_path_dialog.py +3 -1
  29. preditor/gui/ui/loggerwindow.ui +11 -1
  30. preditor/gui/window.py +4 -4
  31. preditor/gui/workbox_mixin.py +43 -14
  32. preditor/gui/workbox_text_edit.py +7 -5
  33. preditor/gui/workboxwidget.py +25 -16
  34. preditor/logging_config.py +5 -2
  35. preditor/scintilla/__init__.py +19 -1
  36. preditor/scintilla/delayables/smart_highlight.py +7 -4
  37. preditor/scintilla/delayables/spell_check.py +5 -4
  38. preditor/scintilla/documenteditor.py +228 -135
  39. preditor/scintilla/finddialog.py +3 -3
  40. preditor/scintilla/lang/language.py +1 -1
  41. preditor/scintilla/lexers/cpplexer.py +3 -2
  42. preditor/scintilla/lexers/javascriptlexer.py +6 -4
  43. preditor/scintilla/lexers/maxscriptlexer.py +8 -7
  44. preditor/scintilla/lexers/mellexer.py +3 -2
  45. preditor/scintilla/lexers/mulexer.py +3 -2
  46. preditor/scintilla/lexers/pythonlexer.py +7 -6
  47. preditor/utils/cute.py +9 -8
  48. preditor/version.py +16 -3
  49. {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/METADATA +69 -32
  50. {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/RECORD +56 -47
  51. preditor-1.3.0.dist-info/top_level.txt +3 -0
  52. tests/find_files/test_find_files.py +74 -0
  53. tests/ide/test_delayable_engine.py +171 -0
  54. preditor-1.1.0.dist-info/top_level.txt +0 -1
  55. {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/WHEEL +0 -0
  56. {preditor-1.1.0.dist-info → preditor-1.3.0.dist-info}/entry_points.txt +0 -0
  57. {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 QColor, QFontMetrics, QTextCharFormat, QTextCursor, QTextDocument
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(Qt.CTRL | Qt.SHIFT | Qt.Key_Backspace)
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).width(" ")
159
- self.setTabStopWidth(fontPixelWidth * tab_width)
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(cursor.End)
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(cursor.EndOfLine)
351
- cursor.movePosition(cursor.End, cursor.KeepAnchor)
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 = event.key() == Qt.Key_Space and modifiers == Qt.ControlModifier
585
- ctrlM = event.key() == Qt.Key_M and modifiers == Qt.ControlModifier
586
- ctrlI = event.key() == Qt.Key_I and modifiers == Qt.ControlModifier
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(index, QAbstractItemView.EnsureVisible)
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 QApplication.instance().keyboardModifiers() == Qt.ShiftModifier:
677
- mode = QTextCursor.KeepAnchor
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 QApplication.instance().keyboardModifiers() == Qt.ControlModifier:
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(QTextCursor.StartOfLine, QTextCursor.MoveAnchor)
749
- self.moveCursor(QTextCursor.End, QTextCursor.KeepAnchor)
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
- self.moveCursor(QTextCursor.End)
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, parent=None, flags=Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
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 QDialog.exec_(self)
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:
@@ -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.exec_(Qt.MoveAction)
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
@@ -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)
@@ -30,22 +30,24 @@ class FindFiles(QWidget):
30
30
 
31
31
  # Create shortcuts
32
32
  self.uiCloseSCT = QShortcut(
33
- QKeySequence(Qt.Key_Escape), self, context=Qt.WidgetWithChildrenShortcut
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, self, context=Qt.WidgetWithChildrenShortcut
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(Qt.Key_Up, self, context=Qt.WidgetWithChildrenShortcut)
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(self, 'Tab can not be closed.', msg, QMessageBox.Ok)
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__()