PrEditor 1.0.0__py3-none-any.whl → 1.2.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/config.py +16 -0
  4. preditor/dccs/.hab.json +10 -0
  5. preditor/dccs/maya/PrEditor_maya.mod +0 -1
  6. preditor/dccs/maya/README.md +22 -0
  7. preditor/dccs/maya/plug-ins/PrEditor_maya.py +32 -1
  8. preditor/dccs/studiomax/PackageContents.xml +32 -0
  9. preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr +8 -0
  10. preditor/dccs/studiomax/README.md +17 -0
  11. preditor/dccs/studiomax/preditor.ms +16 -0
  12. preditor/dccs/studiomax/preditor_menu.mnx +7 -0
  13. preditor/debug.py +7 -3
  14. preditor/excepthooks.py +15 -6
  15. preditor/gui/app.py +2 -2
  16. preditor/gui/codehighlighter.py +10 -24
  17. preditor/gui/completer.py +17 -6
  18. preditor/gui/console.py +77 -47
  19. preditor/gui/dialog.py +10 -7
  20. preditor/gui/drag_tab_bar.py +7 -7
  21. preditor/gui/errordialog.py +2 -2
  22. preditor/gui/find_files.py +7 -5
  23. preditor/gui/fuzzy_search/fuzzy_search.py +8 -4
  24. preditor/gui/group_tab_widget/__init__.py +4 -4
  25. preditor/gui/group_tab_widget/grouped_tab_models.py +4 -4
  26. preditor/gui/group_tab_widget/grouped_tab_widget.py +6 -4
  27. preditor/gui/level_buttons.py +16 -1
  28. preditor/gui/loggerwindow.py +51 -28
  29. preditor/gui/set_text_editor_path_dialog.py +3 -1
  30. preditor/gui/window.py +4 -4
  31. preditor/gui/workbox_mixin.py +40 -11
  32. preditor/gui/workbox_text_edit.py +5 -3
  33. preditor/gui/workboxwidget.py +16 -12
  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 +165 -116
  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.0.0.dist-info → preditor-1.2.0.dist-info}/METADATA +69 -32
  50. {preditor-1.0.0.dist-info → preditor-1.2.0.dist-info}/RECORD +56 -47
  51. preditor-1.2.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.0.0.dist-info/top_level.txt +0 -1
  55. {preditor-1.0.0.dist-info → preditor-1.2.0.dist-info}/WHEEL +0 -0
  56. {preditor-1.0.0.dist-info → preditor-1.2.0.dist-info}/entry_points.txt +0 -0
  57. {preditor-1.0.0.dist-info → preditor-1.2.0.dist-info}/licenses/LICENSE +0 -0
preditor/__init__.py CHANGED
@@ -184,7 +184,10 @@ def launch(run_workbox=False, app_id=None, name=None, standalone=False):
184
184
  # it regain focus.
185
185
  widget.activateWindow()
186
186
  widget.raise_()
187
- widget.setWindowState(widget.windowState() & ~Qt.WindowMinimized | Qt.WindowActive)
187
+ widget.setWindowState(
188
+ widget.windowState() & ~Qt.WindowState.WindowMinimized
189
+ | Qt.WindowState.WindowActive
190
+ )
188
191
  widget.console().setFocus()
189
192
  app.start()
190
193
 
preditor/about_module.py CHANGED
@@ -111,10 +111,14 @@ class AboutQt(AboutModule):
111
111
  pass
112
112
 
113
113
  # Add info for all Qt5 bindings that have been imported
114
- if 'PyQt5.QtCore' in sys.modules:
115
- ret.append('PyQt5: {}'.format(sys.modules['PyQt5.QtCore'].PYQT_VERSION_STR))
114
+ if 'PySide6.QtCore' in sys.modules:
115
+ ret.append('PySide6: {}'.format(sys.modules['PySide6.QtCore'].qVersion()))
116
+ if 'PyQt6.QtCore' in sys.modules:
117
+ ret.append('PyQt6: {}'.format(sys.modules['PyQt6.QtCore'].PYQT_VERSION_STR))
116
118
  if 'PySide2.QtCore' in sys.modules:
117
119
  ret.append('PySide2: {}'.format(sys.modules['PySide2.QtCore'].qVersion()))
120
+ if 'PyQt5.QtCore' in sys.modules:
121
+ ret.append('PyQt5: {}'.format(sys.modules['PyQt5.QtCore'].PYQT_VERSION_STR))
118
122
 
119
123
  # Add qt library paths for plugin debugging
120
124
  for i, path in enumerate(QtCore.QCoreApplication.libraryPaths()):
preditor/config.py CHANGED
@@ -48,6 +48,7 @@ class PreditorConfig:
48
48
  self._name = None
49
49
  self._logging = False
50
50
  self._headless_callback = None
51
+ self._on_create_callback = None
51
52
  self._parent_callback = None
52
53
  self._error_dialog_class = True
53
54
  self._excepthooks = []
@@ -63,6 +64,7 @@ class PreditorConfig:
63
64
  f"{' ' * indent}logging: {self.logging}",
64
65
  f"{' ' * indent}headless_callback: {self.headless_callback!r}",
65
66
  f"{' ' * indent}parent_callback: {self.parent_callback!r}",
67
+ f"{' ' * indent}on_create_callback: {self.on_create_callback!r}",
66
68
  ]
67
69
  return '\n'.join(ret)
68
70
 
@@ -233,6 +235,20 @@ class PreditorConfig:
233
235
  # If the core name was changed attempt to update the logging config.
234
236
  self.update_logging()
235
237
 
238
+ @property
239
+ def on_create_callback(self):
240
+ """A pointer to a method that is called on LoggerWindow instance create.
241
+
242
+ This callback accepts the instance and can be used to customize the
243
+ LoggerWindow instance when it is first created.
244
+ """
245
+ return self._on_create_callback
246
+
247
+ @on_create_callback.setter
248
+ @set_if_unlocked()
249
+ def on_create_callback(self, cb):
250
+ self._on_create_callback = cb
251
+
236
252
  @property
237
253
  def parent_callback(self):
238
254
  """A pointer to a method that is called by `self.root_window`.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "preditor",
3
+ "version": "0.0.dev0",
4
+ "environment": {
5
+ "append": {
6
+ "MAYA_MODULE_PATH": "{relative_root}/maya",
7
+ "ADSK_APPLICATION_PLUGINS": "{relative_root}/studiomax"
8
+ }
9
+ }
10
+ }
@@ -1,2 +1 @@
1
1
  + PrEditor DEVELOPMENT .
2
- PYTHONPATH +:= ../..
@@ -0,0 +1,22 @@
1
+ # Maya Integration
2
+
3
+ This is an example of using an Maya module to add PrEditor into Maya. This adds
4
+ a PrEditor menu with a PrEditor action in Maya's menu bar letting you open PrEditor. It
5
+ adds the excepthook so if a python exception is raised it will prompt the user
6
+ to show PrEditor. PrEditor will show all python stdout/stderr output generated
7
+ after the plugin is loaded.
8
+
9
+ # Setup
10
+
11
+ Make sure to follow these [setup instructions](/preditor/README.md#Setup) first to create the virtualenv.
12
+
13
+ Alternatively you can use [myapy's](https://help.autodesk.com/view/MAYAUL/2026/ENU/?guid=GUID-72A245EC-CDB4-46AB-BEE0-4BBBF9791627) pip to install the requirements, but a
14
+ separate virtualenv is recommended. This method should not require setting the
15
+ `PREDITOR_SITE` environment variable even if you use an editable install.
16
+
17
+ # Use
18
+
19
+ The [preditor/dccs/maya](/preditor/dccs/maya) directory is setup as a Maya Module. To load it in
20
+ maya add the full path to that directory to the `MAYA_MODULE_PATH` environment
21
+ variable. You can use `;` on windows and `:` on linux to join multiple paths together.
22
+ You will need to enable auto load for the `PrEditor_maya.py` plugin.
@@ -1,5 +1,9 @@
1
1
  from __future__ import absolute_import
2
2
 
3
+ import os
4
+ import site
5
+ from pathlib import Path
6
+
3
7
  import maya.mel
4
8
  from maya import OpenMayaUI, cmds
5
9
 
@@ -35,12 +39,39 @@ def launch(ignored):
35
39
  return widget
36
40
 
37
41
 
42
+ def update_site():
43
+ """Adds a site dir to python. This makes its contents importable to python.
44
+
45
+ This includes making any editable installs located in that site-packages folder
46
+ accessible to this python instance. This does not activate the virtualenv.
47
+
48
+ If the env var `PREDITOR_SITE` is set, this path is used. Otherwise the
49
+ parent directory of preditor is used.
50
+
51
+ - `PREDITOR_SITE` is useful if you want to use an editable install of preditor
52
+ for development. This should point to a virtualenv's site-packages folder.
53
+ - Otherwise if the virtualenv has a regular pip install of preditor you can
54
+ skip setting the env var.
55
+ """
56
+ venv_path = os.getenv("PREDITOR_SITE")
57
+ # If the env var is not defined then use the parent dir of this preditor package.
58
+ if venv_path is None:
59
+ venv_path = cmds.moduleInfo(moduleName="PrEditor", path=True)
60
+ venv_path = Path(venv_path).parent.parent.parent
61
+ venv_path = str(venv_path)
62
+
63
+ print(f"Preditor is adding python site: {venv_path}")
64
+ site.addsitedir(venv_path)
65
+
66
+
38
67
  def initializePlugin(mobject): # noqa: N802
39
68
  """Initialize the script plug-in"""
40
69
  global preditor_menu
41
70
 
42
71
  # If running headless, there is no need to build a gui and create the python logger
43
72
  if not headless():
73
+ update_site()
74
+
44
75
  from Qt.QtWidgets import QApplication
45
76
 
46
77
  import preditor
@@ -67,7 +98,7 @@ def initializePlugin(mobject): # noqa: N802
67
98
  gmainwindow = maya.mel.eval("$temp1=$gMainWindow")
68
99
  preditor_menu = cmds.menu(label="PrEditor", parent=gmainwindow, tearOff=True)
69
100
  cmds.menuItem(
70
- label="Show",
101
+ label="PrEditor",
71
102
  command=launch,
72
103
  sourceType="python",
73
104
  image=preditor.resourcePath('img/preditor.png'),
@@ -0,0 +1,32 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <ApplicationPackage
3
+ SchemaVersion="1.0"
4
+ AutodeskProduct="3ds Max"
5
+ ProductType="Application"
6
+ Name="PrEditor"
7
+ Description="Initialize PrEditor inside 3ds Max."
8
+ AppVersion="0.0.1"
9
+ ProductCode="{7b1e4ece-9a30-4afb-99ed-b9fb7c23e2f9}"
10
+ UpgradeCode="{2d245bb4-19cf-4f90-ae19-3ff006ed0f48}">
11
+ <CompanyDetails Name="Blur Studio" Email="opensource@blur.com"/>
12
+ <Components Description="pre-start-up scripts parts">
13
+ <RuntimeRequirements OS="Win64" Platform="3ds Max" SeriesMin="2025" SeriesMax="2026" />
14
+ <ComponentEntry ModuleName="./preditor.ms" />
15
+ </Components>
16
+ <Components Description="macroscripts parts">
17
+ <RuntimeRequirements OS="Win64" Platform="3ds Max" SeriesMin="2025" SeriesMax="2026" />
18
+ <ComponentEntry ModuleName="./PrEditor-PrEditor_Show.mcr" />
19
+ </Components>
20
+ <Components Description="menu parts">
21
+ <RuntimeRequirements OS="Win64" Platform="3ds Max" SeriesMin="2025" SeriesMax="2026" />
22
+ <ComponentEntry ModuleName="./preditor_menu.mnx" />
23
+ </Components>
24
+ <Components Description="light icon paths parts">
25
+ <RuntimeRequirements OS="Win64" Platform="3ds Max" SeriesMin="2025" SeriesMax="2026" />
26
+ <ComponentEntry AppName="lighticons" Version="1.0.0" ModuleName="../../resource/img" />
27
+ </Components>
28
+ <Components Description="dark icon paths parts">
29
+ <RuntimeRequirements OS="Win64" Platform="3ds Max" SeriesMin="2025" SeriesMax="2026" />
30
+ <ComponentEntry AppName="darkicons" Version="1.0.0" ModuleName="../../resource/img" />
31
+ </Components>
32
+ </ApplicationPackage>
@@ -0,0 +1,8 @@
1
+ macroScript PrEditor_Show
2
+ category:"PrEditor"
3
+ tooltip:"PrEditor..."
4
+ IconName:"preditor.ico"
5
+ (
6
+ local preditor = python.import "preditor"
7
+ preditor.launch()
8
+ )
@@ -0,0 +1,17 @@
1
+ # 3ds Max Integration
2
+
3
+ This is an example of using an Autodesk Application Package to load PrEditor into
4
+ 3ds Max. This adds a PrEditor item to the Scripting menu in 3ds Max's menu bar
5
+ to show PrEditor. It adds the excepthook so if a python exception is raised
6
+ it will prompt the user to show PrEditor. PrEditor will show all python stdout/stderr
7
+ output generated after the plugin is loaded.
8
+
9
+ # Setup
10
+
11
+ Make sure to follow these [setup instructions](/preditor/README.md#Setup) first to create the virtualenv.
12
+
13
+ # Use
14
+
15
+ The [preditor/dccs/studiomax](/preditor/dccs/studiomax) directory is setup as a 3ds Max Application Plugin.
16
+ To load it in 3ds Max add the full path to that directory to the `ADSK_APPLICATION_PLUGINS` environment
17
+ variable. You can use `;` on windows and `:` on linux to join multiple paths together.
@@ -0,0 +1,16 @@
1
+
2
+ function configure_preditor = (
3
+ local pysite = python.import "site"
4
+ local WinEnv = dotNetClass "System.Environment"
5
+ -- If the env var PREDITOR_SITE is set, add its packages to python
6
+ local venv_path = WinEnv.GetEnvironmentVariable "PREDITOR_SITE"
7
+ if venv_path != undefined do (
8
+ print("Preditor is adding python site: " + venv_path)
9
+ pysite.addsitedir venv_path
10
+ )
11
+ -- Configure preditor, adding excepthook etc.
12
+ local preditor = python.import "preditor"
13
+ preditor.configure "studiomax"
14
+ )
15
+
16
+ configure_preditor()
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <MaxMenuTransformations>
3
+ <CreateMenuSeparator MenuId="658724ec-de09-47dd-b723-918c59a28ad1" Id="9cdc28de-9e70-471c-ae5c-d86e3b7fefba" BeforeId="4e206a37-f502-4fa8-ba0e-70dd427d507f"/>
4
+ <MoveItem DestinationId="658724ec-de09-47dd-b723-918c59a28ad1" ItemId="4e206a37-f502-4fa8-ba0e-70dd427d507f"/>
5
+ <CreateMenuAction MenuId="658724ec-de09-47dd-b723-918c59a28ad1" Id="f243229b-f0f6-42b4-a94d-bebe9ef9777f" ActionId="647394-PrEditor_Show`PrEditor"/>
6
+ <MoveItem DestinationId="658724ec-de09-47dd-b723-918c59a28ad1" ItemId="9cdc28de-9e70-471c-ae5c-d86e3b7fefba" BeforeId="f243229b-f0f6-42b4-a94d-bebe9ef9777f"/>
7
+ </MaxMenuTransformations>
preditor/debug.py CHANGED
@@ -21,11 +21,15 @@ class FileLogger:
21
21
  """Removes the contents of the log file."""
22
22
  open(self._logfile, 'w').close()
23
23
  if stamp:
24
- msg = '--------- Date: {today} Version: {version} ---------'
25
- print(msg.format(today=datetime.datetime.today(), version=sys.version))
24
+ print(self.stamp())
26
25
 
27
26
  def flush(self):
28
- self._stdhandle.flush()
27
+ if self._stdhandle:
28
+ self._stdhandle.flush()
29
+
30
+ def stamp(self):
31
+ msg = '--------- Date: {today} Version: {version} ---------'
32
+ return msg.format(today=datetime.datetime.today(), version=sys.version)
29
33
 
30
34
  def write(self, msg):
31
35
  f = open(self._logfile, 'a')
preditor/excepthooks.py CHANGED
@@ -15,10 +15,8 @@ class PreditorExceptHook(object):
15
15
  This calls each callable in the `preditor.config.excepthooks` list any time
16
16
  `sys.excepthook` is called due to an raised exception.
17
17
 
18
- If `config.excepthook` is empty when installing this class, it will
19
- automatically add the `call_base_excepthook` and `ask_to_show_logger` methods.
20
- This enables showing the excepthook in parent streams and prompting the user
21
- to show PrEditor when an error happens. You can disable this by adding `None`
18
+ If `config.excepthooks` is empty when installing this class, it will
19
+ automatically add `default_excepthooks`. You can disable this by adding `None`
22
20
  to the list before this class is initialized.
23
21
  """
24
22
 
@@ -27,8 +25,7 @@ class PreditorExceptHook(object):
27
25
 
28
26
  # Add the default excepthooks
29
27
  if not config.excepthooks and config.excepthooks != [None]:
30
- config.excepthooks.append(self.call_base_excepthook)
31
- config.excepthooks.append(self.ask_to_show_logger)
28
+ config.excepthooks.extend(self.default_excepthooks())
32
29
 
33
30
  def __call__(self, *exc_info):
34
31
  """Run when an exception is raised and calls all `config.excepthooks`."""
@@ -40,6 +37,18 @@ class PreditorExceptHook(object):
40
37
  # Clear any ErrorReports that were generated by this exception handling
41
38
  ErrorReport.clearReports()
42
39
 
40
+ def default_excepthooks(self):
41
+ """Returns default excepthooks handlers.
42
+
43
+ This includes the `call_base_excepthook` and `ask_to_show_logger` methods.
44
+ They enables showing the excepthook in parent streams and prompting the user
45
+ to show PrEditor when an error happens.
46
+ """
47
+ return [
48
+ self.call_base_excepthook,
49
+ self.ask_to_show_logger,
50
+ ]
51
+
43
52
  def call_base_excepthook(self, *exc_info):
44
53
  """Process `base_excepthook` supplied during object instantiation.
45
54
 
preditor/gui/app.py CHANGED
@@ -93,7 +93,7 @@ class App(object):
93
93
  Returns:
94
94
  args: Extend the arguments used to intialize the QApplication.
95
95
  """
96
- if settings.OS_TYPE == "Windows" and Qt.IsPyQt5:
96
+ if settings.OS_TYPE == "Windows" and (Qt.IsPyQt6 or Qt.IsPyQt5):
97
97
  # Make Qt automatically scale based on the monitor the window is
98
98
  # currently located.
99
99
  return ["--platform", "windows:dpiawareness=0"]
@@ -157,4 +157,4 @@ class App(object):
157
157
  """Exec's the QApplication if it hasn't already been started."""
158
158
  if self.app_created and self.app and not self.app_has_exec:
159
159
  self.app_has_exec = True
160
- self.app.exec_()
160
+ Qt.QtCompat.QApplication.exec_()
@@ -4,7 +4,6 @@ import json
4
4
  import os
5
5
  import re
6
6
 
7
- from Qt.QtCore import QRegExp
8
7
  from Qt.QtGui import QColor, QSyntaxHighlighter, QTextCharFormat
9
8
 
10
9
  from .. import resourcePath
@@ -68,59 +67,46 @@ class CodeHighlighter(QSyntaxHighlighter):
68
67
  if parent and hasattr(parent, 'outputPrompt'):
69
68
  self.highlightText(
70
69
  text,
71
- QRegExp('%s[^\\n]*' % re.escape(parent.outputPrompt())),
70
+ re.compile('%s[^\\n]*' % re.escape(parent.outputPrompt())),
72
71
  format,
73
72
  )
74
73
 
75
74
  # format the keywords
76
75
  format = self.keywordFormat()
77
76
  for kwd in self._keywords:
78
- self.highlightText(text, QRegExp(r'\b%s\b' % kwd), format)
77
+ self.highlightText(text, re.compile(r'\b%s\b' % kwd), format)
79
78
 
80
79
  # format the strings
81
80
  format = self.stringFormat()
81
+
82
82
  for string in self._strings:
83
83
  self.highlightText(
84
84
  text,
85
- QRegExp('%s[^%s]*' % (string, string)),
85
+ re.compile('{s}[^{s}]*{s}'.format(s=string)),
86
86
  format,
87
- includeLast=True,
88
87
  )
89
88
 
90
89
  # format the comments
91
90
  format = self.commentFormat()
92
91
  for comment in self._comments:
93
- self.highlightText(text, QRegExp(comment), format)
92
+ self.highlightText(text, re.compile(comment), format)
94
93
 
95
94
  def highlightText(self, text, expr, format, offset=0, includeLast=False):
96
95
  """Highlights a text group with an expression and format
97
96
 
98
97
  Args:
99
98
  text (str): text to highlight
100
- expr (QRegExp): search parameter
99
+ expr (QRegularExpression): search parameter
101
100
  format (QTextCharFormat): formatting rule
102
- offset (int): number of characters to offset by when highlighting
103
101
  includeLast (bool): whether or not the last character should be highlighted
104
102
  """
105
- pos = expr.indexIn(text, 0)
106
-
107
103
  # highlight all the given matches to the expression in the text
108
- while pos != -1:
109
- pos = expr.pos(offset)
110
- length = len(expr.cap(offset))
111
-
112
- # use the last character if desired
104
+ for match in expr.finditer(text):
105
+ start, end = match.span()
106
+ length = end - start
113
107
  if includeLast:
114
108
  length += 1
115
-
116
- # set the formatting
117
- self.setFormat(pos, length, format)
118
-
119
- matched = expr.matchedLength()
120
- if includeLast:
121
- matched += 1
122
-
123
- pos = expr.indexIn(text, pos + matched)
109
+ self.setFormat(start, length, format)
124
110
 
125
111
  def keywordColor(self):
126
112
  # pull the color from the parent if possible because this doesn't support
preditor/gui/completer.py CHANGED
@@ -5,6 +5,7 @@ import re
5
5
  import sys
6
6
  from enum import Enum
7
7
 
8
+ import Qt as Qt_py
8
9
  from Qt.QtCore import QRegExp, QSortFilterProxyModel, QStringListModel, Qt
9
10
  from Qt.QtGui import QCursor, QTextCursor
10
11
  from Qt.QtWidgets import QCompleter, QToolTip
@@ -63,12 +64,16 @@ class PythonCompleter(QCompleter):
63
64
 
64
65
  def setCaseSensitive(self, caseSensitive=True):
65
66
  """Set case sensitivity for completions"""
66
- self._sensitivity = Qt.CaseSensitive if caseSensitive else Qt.CaseInsensitive
67
+ self._sensitivity = (
68
+ Qt.CaseSensitivity.CaseSensitive
69
+ if caseSensitive
70
+ else Qt.CaseSensitivity.CaseInsensitive
71
+ )
67
72
  self.buildCompleter()
68
73
 
69
74
  def caseSensitive(self):
70
75
  """Return current case sensitivity state for completions"""
71
- caseSensitive = self._sensitivity == Qt.CaseSensitive
76
+ caseSensitive = self._sensitivity == Qt.CaseSensitivity.CaseSensitive
72
77
  return caseSensitive
73
78
 
74
79
  def setCompleterMode(self, completerMode=CompleterMode.STARTS_WITH):
@@ -89,7 +94,7 @@ class PythonCompleter(QCompleter):
89
94
  self.filterModel.setSourceModel(model)
90
95
  self.filterModel.setFilterCaseSensitivity(self._sensitivity)
91
96
  self.setModel(self.filterModel)
92
- self.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
97
+ self.setCompletionMode(QCompleter.CompletionMode.UnfilteredPopupCompletion)
93
98
 
94
99
  def currentObject(self, scope=None, docMode=False):
95
100
  if self._enabled:
@@ -155,8 +160,14 @@ class PythonCompleter(QCompleter):
155
160
  if self._completerMode == CompleterMode.FULL_FUZZY:
156
161
  regExStr = ".*".join(prefix)
157
162
 
158
- regexp = QRegExp(regExStr, self._sensitivity)
159
- self.filterModel.setFilterRegExp(regexp)
163
+ if Qt_py.IsPyQt6 or Qt_py.IsPySide6:
164
+ regexp = QRegExp(regExStr)
165
+ if self._sensitivity:
166
+ regexp.setPatternOptions(QRegExp.PatternOption.CaseInsensitiveOption)
167
+ self.filterModel.setFilterRegularExpression(regexp)
168
+ else:
169
+ regexp = QRegExp(regExStr, self._sensitivity)
170
+ self.filterModel.setFilterRegExp(regexp)
160
171
 
161
172
  def clear(self):
162
173
  self.popup().hide()
@@ -193,7 +204,7 @@ class PythonCompleter(QCompleter):
193
204
  """pulls out the text underneath the cursor of this items widget"""
194
205
 
195
206
  cursor = self.widget().textCursor()
196
- cursor.select(QTextCursor.WordUnderCursor)
207
+ cursor.select(QTextCursor.SelectionType.WordUnderCursor)
197
208
 
198
209
  # grab the selected word
199
210
  word = cursor.selectedText()