PrEditor 1.3.0__tar.gz → 1.4.0__tar.gz
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-1.3.0 → preditor-1.4.0}/PKG-INFO +1 -1
- {preditor-1.3.0 → preditor-1.4.0}/PrEditor.egg-info/PKG-INFO +1 -1
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/drag_tab_bar.py +4 -1
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/group_tab_widget/__init__.py +14 -19
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/group_tab_widget/grouped_tab_widget.py +26 -4
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/group_tab_widget/one_tab_widget.py +42 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/logger_window_plugin.py +3 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/loggerwindow.py +27 -40
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/workbox_mixin.py +99 -1
- {preditor-1.3.0 → preditor-1.4.0}/preditor/version.py +3 -3
- {preditor-1.3.0 → preditor-1.4.0}/.coveragerc +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/.github/ISSUE_TEMPLATE/BUG_REPORT.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/.github/workflows/release.yml +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/.github/workflows/static-analysis-and-test.yml +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/.gitignore +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/.pre-commit-config.yaml +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/CODE_OF_CONDUCT.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/CONTRIBUTING.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/LICENSE +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/MANIFEST.in +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/PrEditor.egg-info/SOURCES.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/PrEditor.egg-info/dependency_links.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/PrEditor.egg-info/entry_points.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/PrEditor.egg-info/requires.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/PrEditor.egg-info/top_level.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/README.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/examples/add_to_app.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/examples/output_capture_and_show.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/__main__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/about_module.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/cli.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/config.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/contexts.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/cores/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/cores/core.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/.hab.json +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/maya/PrEditor_maya.mod +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/maya/README.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/maya/plug-ins/PrEditor_maya.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/studiomax/PackageContents.xml +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/studiomax/PrEditor-PrEditor_Show.mcr +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/studiomax/README.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/studiomax/preditor.ms +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/dccs/studiomax/preditor_menu.mnx +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/debug.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/delayable_engine/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/delayable_engine/delayables.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/enum.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/excepthooks.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/app.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/codehighlighter.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/completer.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/console.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/dialog.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/editor_chooser.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/errordialog.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/find_files.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/fuzzy_search/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/fuzzy_search/fuzzy_search.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/group_tab_widget/grouped_tab_menu.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/group_tab_widget/grouped_tab_models.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/level_buttons.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/logger_window_handler.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/newtabwidget.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/set_text_editor_path_dialog.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/status_label.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/suggest_path_quotes_dialog.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/ui/editor_chooser.ui +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/ui/errordialog.ui +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/ui/find_files.ui +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/ui/loggerwindow.ui +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/ui/set_text_editor_path_dialog.ui +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/ui/suggest_path_quotes_dialog.ui +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/window.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/workbox_text_edit.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/gui/workboxwidget.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/logging_config.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/osystem.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/plugins.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/prefs.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/environment_variables.html +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/error_mail.html +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/error_mail_inline.html +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/README.md +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/arrow_forward.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/check-bold.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/chevron-down.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/chevron-up.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/close-thick.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/comment-edit.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/content-copy.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/content-cut.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/content-duplicate.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/content-paste.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/content-save.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/debug_disabled.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/eye-check.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/file-plus.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/file-remove.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/format-align-left.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/format-letter-case-lower.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/format-letter-case-upper.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/format-letter-case.svg +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/information.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/logging_critical.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/logging_custom.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/logging_debug.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/logging_error.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/logging_info.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/logging_not_set.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/logging_warning.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/marker.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/play.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/playlist-play.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/plus-minus-variant.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/preditor.ico +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/preditor.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/preditor.psd +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/preditor.svg +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/regex.svg +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/restart.svg +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/skip-forward-outline.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/skip-next-outline.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/skip-next.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/skip-previous.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/subdirectory-arrow-right.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/text-search-variant.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/img/warning-big.png +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/lang/python.json +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/settings.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/stylesheet/Bright.css +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/resource/stylesheet/Dark.css +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/delayables/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/delayables/smart_highlight.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/delayables/spell_check.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/documenteditor.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/finddialog.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/bash.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/batch.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/cpp.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/css.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/eyeonscript.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/html.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/javascript.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/lua.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/maxscript.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/mel.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/mu.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/nsi.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/perl.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/puppet.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/python.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/ruby.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/sql.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/xml.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/config/yaml.ini +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lang/language.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lexers/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lexers/cpplexer.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lexers/javascriptlexer.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lexers/maxscriptlexer.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lexers/mellexer.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lexers/mulexer.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/lexers/pythonlexer.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/scintilla/ui/finddialog.ui +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/settings.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/stream/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/stream/director.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/stream/manager.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/streamhandler_helper.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/utils/__init__.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/utils/cute.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/utils/stylesheets.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/utils/text_search.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/preditor/weakref.py +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/pyproject.toml +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/requirements-cli.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/requirements-dev.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/requirements-qsci5.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/requirements-qsci6.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/requirements-shortcut.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/requirements.txt +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/setup.cfg +0 -0
- {preditor-1.3.0 → preditor-1.4.0}/tox.ini +0 -0
|
@@ -139,8 +139,11 @@ class DragTabBar(QTabBar):
|
|
|
139
139
|
"""Used by the tab_menu to rename the tab at index `_context_menu_tab`."""
|
|
140
140
|
if self._context_menu_tab != -1:
|
|
141
141
|
current = self.tabText(self._context_menu_tab)
|
|
142
|
-
msg = 'Rename the {} tab to:'.format(current)
|
|
142
|
+
msg = 'Rename the {} tab to (new name must be unique):'.format(current)
|
|
143
|
+
|
|
143
144
|
name, success = QInputDialog.getText(self, 'Rename Tab', msg, text=current)
|
|
145
|
+
name = self.parent().get_next_available_tab_name(name)
|
|
146
|
+
|
|
144
147
|
if success:
|
|
145
148
|
self.setTabText(self._context_menu_tab, name)
|
|
146
149
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import absolute_import
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
-
import re
|
|
5
4
|
|
|
6
5
|
from Qt.QtCore import Qt
|
|
7
6
|
from Qt.QtGui import QIcon
|
|
@@ -46,6 +45,9 @@ class GroupTabWidget(OneTabWidget):
|
|
|
46
45
|
self.editor_cls = WorkboxTextEdit
|
|
47
46
|
self.core_name = core_name
|
|
48
47
|
self.setStyleSheet(DEFAULT_STYLE_SHEET)
|
|
48
|
+
|
|
49
|
+
self.default_title = 'Group01'
|
|
50
|
+
|
|
49
51
|
corner = QWidget(self)
|
|
50
52
|
lyt = QHBoxLayout(corner)
|
|
51
53
|
lyt.setSpacing(0)
|
|
@@ -69,7 +71,7 @@ class GroupTabWidget(OneTabWidget):
|
|
|
69
71
|
self.uiCornerBTN = corner
|
|
70
72
|
self.setCornerWidget(self.uiCornerBTN, Qt.Corner.TopRightCorner)
|
|
71
73
|
|
|
72
|
-
def add_new_tab(self, group, title=
|
|
74
|
+
def add_new_tab(self, group, title=None, prefs=None):
|
|
73
75
|
"""Adds a new tab to the requested group, creating the group if the group
|
|
74
76
|
doesn't exist.
|
|
75
77
|
|
|
@@ -80,9 +82,6 @@ class GroupTabWidget(OneTabWidget):
|
|
|
80
82
|
If True is passed, then the current group tab is used.
|
|
81
83
|
title (str, optional): The name to give the newly created tab inside
|
|
82
84
|
the group.
|
|
83
|
-
group_fmt(str, optional): If None is passed to group, this string is
|
|
84
|
-
used to search for existing tabs to calculate the last number
|
|
85
|
-
and generate the new group tab name.
|
|
86
85
|
|
|
87
86
|
Returns:
|
|
88
87
|
GroupedTabWidget: The tab group for this group.
|
|
@@ -90,21 +89,14 @@ class GroupTabWidget(OneTabWidget):
|
|
|
90
89
|
"""
|
|
91
90
|
parent = None
|
|
92
91
|
if not group:
|
|
93
|
-
|
|
94
|
-
group_fmt = r'Group {}'
|
|
95
|
-
last = 0
|
|
96
|
-
for i in range(self.count()):
|
|
97
|
-
match = re.match(group_fmt.format(r'(\d+)'), self.tabText(i))
|
|
98
|
-
if match:
|
|
99
|
-
last = max(last, int(match.group(1)))
|
|
100
|
-
group = group_fmt.format(last + 1)
|
|
92
|
+
group = self.get_next_available_tab_name(self.default_title)
|
|
101
93
|
elif group is True:
|
|
102
94
|
group = self.currentIndex()
|
|
103
95
|
if isinstance(group, int):
|
|
104
96
|
group_title = self.tabText(group)
|
|
105
97
|
parent = self.widget(group)
|
|
106
98
|
elif isinstance(group, str):
|
|
107
|
-
group_title = group
|
|
99
|
+
group_title = group.replace(" ", "_")
|
|
108
100
|
index = self.index_for_text(group)
|
|
109
101
|
if index != -1:
|
|
110
102
|
parent = self.widget(index)
|
|
@@ -146,7 +138,7 @@ class GroupTabWidget(OneTabWidget):
|
|
|
146
138
|
self,
|
|
147
139
|
'Close all editors under this tab?',
|
|
148
140
|
'Are you sure you want to close all tabs under the "{}" tab?'.format(
|
|
149
|
-
self.tabText(
|
|
141
|
+
self.tabText(index)
|
|
150
142
|
),
|
|
151
143
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.Cancel,
|
|
152
144
|
)
|
|
@@ -154,11 +146,11 @@ class GroupTabWidget(OneTabWidget):
|
|
|
154
146
|
# Clean up all temp files created by this group's editors if they
|
|
155
147
|
# are not using actual saved files.
|
|
156
148
|
tab_widget = self.widget(self.currentIndex())
|
|
157
|
-
for
|
|
158
|
-
editor = tab_widget.widget(
|
|
149
|
+
for editor_index in range(tab_widget.count()):
|
|
150
|
+
editor = tab_widget.widget(editor_index)
|
|
159
151
|
editor.__remove_tempfile__()
|
|
160
152
|
|
|
161
|
-
super(GroupTabWidget, self).close_tab(
|
|
153
|
+
super(GroupTabWidget, self).close_tab(index)
|
|
162
154
|
|
|
163
155
|
def current_groups_widget(self):
|
|
164
156
|
"""Returns the current widget of the currently selected group or None."""
|
|
@@ -166,7 +158,8 @@ class GroupTabWidget(OneTabWidget):
|
|
|
166
158
|
if editor_tab:
|
|
167
159
|
return editor_tab.currentWidget()
|
|
168
160
|
|
|
169
|
-
def default_tab(self, title=
|
|
161
|
+
def default_tab(self, title=None, prefs=None):
|
|
162
|
+
title = title or self.default_title
|
|
170
163
|
widget = GroupedTabWidget(
|
|
171
164
|
parent=self,
|
|
172
165
|
editor_kwargs=self.editor_kwargs,
|
|
@@ -223,6 +216,8 @@ class GroupTabWidget(OneTabWidget):
|
|
|
223
216
|
group_name = group['name']
|
|
224
217
|
tab_widget = None
|
|
225
218
|
|
|
219
|
+
group_name = self.get_next_available_tab_name(group_name)
|
|
220
|
+
|
|
226
221
|
for tab in group.get('tabs', []):
|
|
227
222
|
# Only add this tab if, there is data on disk to load. The user can
|
|
228
223
|
# open multiple instances of PrEditor using the same prefs. The
|
|
@@ -27,7 +27,12 @@ class GroupedTabWidget(OneTabWidget):
|
|
|
27
27
|
self.uiCornerBTN.released.connect(lambda: self.add_new_editor())
|
|
28
28
|
self.setCornerWidget(self.uiCornerBTN, Qt.Corner.TopRightCorner)
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
self.default_title = "Workbox01"
|
|
31
|
+
|
|
32
|
+
def add_new_editor(self, title=None, prefs=None):
|
|
33
|
+
title = title or self.default_title
|
|
34
|
+
|
|
35
|
+
title = self.get_next_available_tab_name(title)
|
|
31
36
|
editor, title = self.default_tab(title)
|
|
32
37
|
index = self.addTab(editor, title)
|
|
33
38
|
self.setCurrentIndex(index)
|
|
@@ -45,11 +50,18 @@ class GroupedTabWidget(OneTabWidget):
|
|
|
45
50
|
self, 'Tab can not be closed.', msg, QMessageBox.StandardButton.Ok
|
|
46
51
|
)
|
|
47
52
|
return
|
|
53
|
+
|
|
54
|
+
workbox = self.widget(index)
|
|
55
|
+
name = workbox.__workbox_name__()
|
|
56
|
+
msg = (
|
|
57
|
+
f"Would you like to donate the contents of tab\n{name}\nto the "
|
|
58
|
+
"/dev/null fund for wayward code?"
|
|
59
|
+
)
|
|
60
|
+
|
|
48
61
|
ret = QMessageBox.question(
|
|
49
62
|
self,
|
|
50
63
|
'Donate to the cause?',
|
|
51
|
-
|
|
52
|
-
"for wayward code?",
|
|
64
|
+
msg,
|
|
53
65
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.Cancel,
|
|
54
66
|
)
|
|
55
67
|
if ret == QMessageBox.StandardButton.Yes:
|
|
@@ -59,7 +71,8 @@ class GroupedTabWidget(OneTabWidget):
|
|
|
59
71
|
|
|
60
72
|
super(GroupedTabWidget, self).close_tab(index)
|
|
61
73
|
|
|
62
|
-
def default_tab(self, title=
|
|
74
|
+
def default_tab(self, title=None, prefs=None):
|
|
75
|
+
title = title or self.default_title
|
|
63
76
|
kwargs = self.editor_kwargs if self.editor_kwargs else {}
|
|
64
77
|
editor = self.editor_cls(parent=self, core_name=self.core_name, **kwargs)
|
|
65
78
|
return editor, title
|
|
@@ -76,5 +89,14 @@ class GroupedTabWidget(OneTabWidget):
|
|
|
76
89
|
if hasattr(self.window(), "setWorkboxFontBasedOnConsole"):
|
|
77
90
|
self.window().setWorkboxFontBasedOnConsole()
|
|
78
91
|
|
|
92
|
+
def tab_widget(self):
|
|
93
|
+
"""Return the tab widget which contains this group tab
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
self._tab_widget (GroupTabWidget): The tab widget which contains
|
|
97
|
+
this workbox
|
|
98
|
+
"""
|
|
99
|
+
return self.parent().parent()
|
|
100
|
+
|
|
79
101
|
def update_closable_tabs(self):
|
|
80
102
|
self.setTabsClosable(self.count() != 1)
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
from __future__ import absolute_import
|
|
2
2
|
|
|
3
|
+
import re
|
|
4
|
+
|
|
3
5
|
from Qt.QtWidgets import QTabWidget
|
|
4
6
|
|
|
7
|
+
TAB_ITERATION_PATTERN = re.compile(r"(\d+)(?!.*\d)")
|
|
8
|
+
|
|
5
9
|
|
|
6
10
|
class OneTabWidget(QTabWidget):
|
|
7
11
|
"""A QTabWidget that shows the close button only if there is more than one
|
|
@@ -17,6 +21,44 @@ class OneTabWidget(QTabWidget):
|
|
|
17
21
|
super(OneTabWidget, self).__init__(*args, **kwargs)
|
|
18
22
|
self.tabCloseRequested.connect(self.close_tab)
|
|
19
23
|
|
|
24
|
+
def get_next_available_tab_name(self, name):
|
|
25
|
+
"""Get the next available tab name, incrementing an iteration if needed.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
name (str): The desired name
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
name (str): The name, or updated name if needed
|
|
32
|
+
"""
|
|
33
|
+
name = name.replace(" ", "_")
|
|
34
|
+
|
|
35
|
+
existing_names = [self.tabText(i) for i in range(self.count())]
|
|
36
|
+
|
|
37
|
+
# Use regex to find the last set of digits. If found, the base name is
|
|
38
|
+
# a slice of name minus the digits string. Otherwise, the base name is
|
|
39
|
+
# the full name and iteration is zero.
|
|
40
|
+
match = TAB_ITERATION_PATTERN.search(name)
|
|
41
|
+
if match:
|
|
42
|
+
# We found trailing digits, so slice to get base name, and convert
|
|
43
|
+
# iteration to int
|
|
44
|
+
iter_str = match.group()
|
|
45
|
+
base = name[: -len(iter_str)]
|
|
46
|
+
iteration = int(iter_str)
|
|
47
|
+
else:
|
|
48
|
+
# No trailing digits found, so base name is full name and iteration
|
|
49
|
+
# is zero.
|
|
50
|
+
base = name
|
|
51
|
+
iteration = 0
|
|
52
|
+
|
|
53
|
+
if name in existing_names:
|
|
54
|
+
for _ in range(99):
|
|
55
|
+
iteration += 1
|
|
56
|
+
new_iter_str = str(iteration).zfill(2)
|
|
57
|
+
name = base + new_iter_str
|
|
58
|
+
if name not in existing_names:
|
|
59
|
+
break
|
|
60
|
+
return name
|
|
61
|
+
|
|
20
62
|
def addTab(self, *args, **kwargs): # noqa: N802
|
|
21
63
|
ret = super(OneTabWidget, self).addTab(*args, **kwargs)
|
|
22
64
|
self.update_closable_tabs()
|
|
@@ -48,6 +48,7 @@ from .completer import CompleterMode
|
|
|
48
48
|
from .level_buttons import LoggingLevelButton
|
|
49
49
|
from .set_text_editor_path_dialog import SetTextEditorPathDialog
|
|
50
50
|
from .status_label import StatusLabel
|
|
51
|
+
from .workbox_mixin import WorkboxName
|
|
51
52
|
|
|
52
53
|
logger = logging.getLogger(__name__)
|
|
53
54
|
|
|
@@ -59,31 +60,6 @@ class WorkboxPages:
|
|
|
59
60
|
Workboxes = 1
|
|
60
61
|
|
|
61
62
|
|
|
62
|
-
class WorkboxName(str):
|
|
63
|
-
"""The joined name of a workbox `group/workbox` with access to its parts.
|
|
64
|
-
|
|
65
|
-
This subclass provides properties for the group and workbox values separately.
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
def __new__(cls, group, workbox):
|
|
69
|
-
txt = "/".join((group, workbox))
|
|
70
|
-
ret = super().__new__(cls, txt)
|
|
71
|
-
# Preserve the imitable nature of str's by using properties without setters.
|
|
72
|
-
ret._group = group
|
|
73
|
-
ret._workbox = workbox
|
|
74
|
-
return ret
|
|
75
|
-
|
|
76
|
-
@property
|
|
77
|
-
def group(self):
|
|
78
|
-
"""The tab name of the group tab that contains the workbox."""
|
|
79
|
-
return self._group
|
|
80
|
-
|
|
81
|
-
@property
|
|
82
|
-
def workbox(self):
|
|
83
|
-
"""The workbox of the tab for this workbox inside of the group."""
|
|
84
|
-
return self._workbox
|
|
85
|
-
|
|
86
|
-
|
|
87
63
|
class LoggerWindow(Window):
|
|
88
64
|
_instance = None
|
|
89
65
|
styleSheetChanged = Signal(str)
|
|
@@ -290,10 +266,9 @@ class LoggerWindow(Window):
|
|
|
290
266
|
|
|
291
267
|
self.dont_ask_again = []
|
|
292
268
|
|
|
293
|
-
# Load any plugins
|
|
294
|
-
self.
|
|
295
|
-
|
|
296
|
-
self.plugins[name] = plugin(self)
|
|
269
|
+
# Load any plugins, and set window title
|
|
270
|
+
self.loadPlugins()
|
|
271
|
+
self.setWindowTitle(self.defineWindowTitle())
|
|
297
272
|
|
|
298
273
|
self.restorePrefs()
|
|
299
274
|
|
|
@@ -306,17 +281,6 @@ class LoggerWindow(Window):
|
|
|
306
281
|
action.triggered.connect(partial(self.setStyleSheet, style_name))
|
|
307
282
|
|
|
308
283
|
self.uiConsoleTOOLBAR.show()
|
|
309
|
-
loggerName = QApplication.instance().translate(
|
|
310
|
-
'PrEditorWindow', DEFAULT_CORE_NAME
|
|
311
|
-
)
|
|
312
|
-
self.setWindowTitle(
|
|
313
|
-
'{} - {} - {} {}-bit'.format(
|
|
314
|
-
loggerName,
|
|
315
|
-
self.name,
|
|
316
|
-
'{}.{}.{}'.format(*sys.version_info[:3]),
|
|
317
|
-
osystem.getPointerSize(),
|
|
318
|
-
)
|
|
319
|
-
)
|
|
320
284
|
|
|
321
285
|
self.setWorkboxFontBasedOnConsole()
|
|
322
286
|
self.setEditorChooserFontBasedOnConsole()
|
|
@@ -357,6 +321,29 @@ class LoggerWindow(Window):
|
|
|
357
321
|
|
|
358
322
|
self.update_workbox_stack()
|
|
359
323
|
|
|
324
|
+
def loadPlugins(self):
|
|
325
|
+
"""Load any plugins that modify the LoggerWindow."""
|
|
326
|
+
self.plugins = {}
|
|
327
|
+
for name, plugin in plugins.loggerwindow():
|
|
328
|
+
if name not in self.plugins:
|
|
329
|
+
self.plugins[name] = plugin(self)
|
|
330
|
+
|
|
331
|
+
def defineWindowTitle(self):
|
|
332
|
+
"""Define the window title, including and info plugins may add."""
|
|
333
|
+
|
|
334
|
+
# Define the title
|
|
335
|
+
loggerName = QApplication.instance().translate(
|
|
336
|
+
'PrEditorWindow', DEFAULT_CORE_NAME
|
|
337
|
+
)
|
|
338
|
+
pyVersion = '{}.{}.{}'.format(*sys.version_info[:3])
|
|
339
|
+
size = osystem.getPointerSize()
|
|
340
|
+
title = f"{loggerName} - {self.name} - {pyVersion} {size}-bit"
|
|
341
|
+
|
|
342
|
+
# Add any info plugins may add to title
|
|
343
|
+
for _name, plugin in self.plugins.items():
|
|
344
|
+
title = plugin.updateWindowTitle(title)
|
|
345
|
+
return title
|
|
346
|
+
|
|
360
347
|
def comment_toggle(self):
|
|
361
348
|
self.current_workbox().__comment_toggle__()
|
|
362
349
|
|
|
@@ -12,6 +12,44 @@ from Qt.QtWidgets import QStackedWidget
|
|
|
12
12
|
from ..prefs import prefs_path
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
class WorkboxName(str):
|
|
16
|
+
"""The joined name of a workbox `group/workbox` with access to its parts.
|
|
17
|
+
|
|
18
|
+
You may pass the group, workbox, or the fully formed workbox name:
|
|
19
|
+
examples:
|
|
20
|
+
workboxName = WorkboxName("Group01", "Workbox05")
|
|
21
|
+
workboxName = WorkboxName("Group01/Workbox05")
|
|
22
|
+
This subclass provides properties for the group and workbox values separately.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __new__(cls, name, sub_name=None):
|
|
26
|
+
if sub_name is not None:
|
|
27
|
+
txt = "/".join((name, sub_name))
|
|
28
|
+
else:
|
|
29
|
+
txt = name
|
|
30
|
+
try:
|
|
31
|
+
name, sub_name = txt.split("/")
|
|
32
|
+
except ValueError:
|
|
33
|
+
msg = "A fully formed name, or a group and name, must be passed in."
|
|
34
|
+
raise ValueError(msg) from None
|
|
35
|
+
|
|
36
|
+
ret = super().__new__(cls, txt)
|
|
37
|
+
# Preserve the imitable nature of str's by using properties without setters.
|
|
38
|
+
ret._group = name
|
|
39
|
+
ret._workbox = sub_name
|
|
40
|
+
return ret
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def group(self):
|
|
44
|
+
"""The tab name of the group tab that contains the workbox."""
|
|
45
|
+
return self._group
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def workbox(self):
|
|
49
|
+
"""The workbox of the tab for this workbox inside of the group."""
|
|
50
|
+
return self._workbox
|
|
51
|
+
|
|
52
|
+
|
|
15
53
|
class WorkboxMixin(object):
|
|
16
54
|
_warning_text = None
|
|
17
55
|
"""When a user is picking this Workbox class, show a warning with this text."""
|
|
@@ -26,6 +64,16 @@ class WorkboxMixin(object):
|
|
|
26
64
|
self._tempfile = tempfile
|
|
27
65
|
self.core_name = core_name
|
|
28
66
|
|
|
67
|
+
self._tab_widget = parent
|
|
68
|
+
|
|
69
|
+
def __tab_widget__(self):
|
|
70
|
+
"""Return the tab widget which contains this workbox
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
GroupedTabWidget: The tab widget which contains this workbox
|
|
74
|
+
"""
|
|
75
|
+
return self._tab_widget
|
|
76
|
+
|
|
29
77
|
def __auto_complete_enabled__(self):
|
|
30
78
|
raise NotImplementedError("Mixin method not overridden.")
|
|
31
79
|
|
|
@@ -151,7 +199,57 @@ class WorkboxMixin(object):
|
|
|
151
199
|
if group == -1 or editor == -1:
|
|
152
200
|
return '<{}>'.format(title)
|
|
153
201
|
else:
|
|
154
|
-
|
|
202
|
+
name = self.__workbox_name__()
|
|
203
|
+
return '<{}>:{}'.format(title, name)
|
|
204
|
+
|
|
205
|
+
def __workbox_name__(self, workbox=None):
|
|
206
|
+
"""Returns the name for this workbox or a given workbox.
|
|
207
|
+
The name is the group tab text and the workbox tab text joined by a `/`"""
|
|
208
|
+
workboxTAB = self.window().uiWorkboxTAB
|
|
209
|
+
group_name = None
|
|
210
|
+
workbox_name = None
|
|
211
|
+
|
|
212
|
+
if workbox:
|
|
213
|
+
grouped_tab_widget = workbox.__tab_widget__()
|
|
214
|
+
for group_idx in range(workboxTAB.count()):
|
|
215
|
+
# If a previous iteration determine workbox_name, bust out
|
|
216
|
+
if workbox_name:
|
|
217
|
+
break
|
|
218
|
+
# Check if current group is the workboxes parent group
|
|
219
|
+
cur_group_widget = workboxTAB.widget(group_idx)
|
|
220
|
+
if cur_group_widget == grouped_tab_widget:
|
|
221
|
+
group_name = workboxTAB.tabText(group_idx)
|
|
222
|
+
|
|
223
|
+
# Found the group, now find workbox
|
|
224
|
+
for workbox_idx in range(cur_group_widget.count()):
|
|
225
|
+
cur_workbox_widget = cur_group_widget.widget(workbox_idx)
|
|
226
|
+
if cur_workbox_widget == workbox:
|
|
227
|
+
workbox_name = cur_group_widget.tabText(workbox_idx)
|
|
228
|
+
break
|
|
229
|
+
else:
|
|
230
|
+
grouped = self.__tab_widget__()
|
|
231
|
+
groupedTabBar = grouped.tabBar()
|
|
232
|
+
|
|
233
|
+
idx = -1
|
|
234
|
+
for idx in range(grouped.count()):
|
|
235
|
+
if grouped.widget(idx) == self:
|
|
236
|
+
break
|
|
237
|
+
workbox_name = groupedTabBar.tabText(idx)
|
|
238
|
+
|
|
239
|
+
group = grouped.tab_widget()
|
|
240
|
+
groupTabBar = group.tabBar()
|
|
241
|
+
idx = -1
|
|
242
|
+
for idx in range(group.count()):
|
|
243
|
+
if group.widget(idx) == grouped:
|
|
244
|
+
break
|
|
245
|
+
group_name = groupTabBar.tabText(idx)
|
|
246
|
+
|
|
247
|
+
# If both found, construct workbox name
|
|
248
|
+
if group_name and workbox_name:
|
|
249
|
+
name = WorkboxName(group_name, workbox_name)
|
|
250
|
+
else:
|
|
251
|
+
name = WorkboxName("", "")
|
|
252
|
+
return name
|
|
155
253
|
|
|
156
254
|
def __goto_line__(self, line):
|
|
157
255
|
raise NotImplementedError("Mixin method not overridden.")
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.4.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g79cb36c80'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|