PrEditor 0.0.0.dev1__py2.py3-none-any.whl → 0.1.0__py2.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-0.1.0.dist-info/LICENSE +165 -0
- PrEditor-0.1.0.dist-info/METADATA +212 -0
- PrEditor-0.1.0.dist-info/RECORD +149 -0
- {PrEditor-0.0.0.dev1.dist-info → PrEditor-0.1.0.dist-info}/WHEEL +1 -1
- PrEditor-0.1.0.dist-info/entry_points.txt +18 -0
- PrEditor-0.1.0.dist-info/top_level.txt +1 -0
- preditor/__init__.py +301 -0
- {blurdev → preditor}/__main__.py +13 -13
- preditor/about_module.py +166 -0
- preditor/cli.py +192 -0
- {blurdev → preditor}/contexts.py +119 -119
- preditor/cores/core.py +65 -0
- preditor/dccs/maya/PrEditor_maya.mod +2 -0
- preditor/dccs/maya/plug-ins/PrEditor_maya.py +108 -0
- preditor/debug.py +294 -0
- blurdev/scintilla/delayable_engine.py → preditor/delayable_engine/__init__.py +310 -299
- blurdev/scintilla/delayables/base.py → preditor/delayable_engine/delayables.py +85 -85
- {blurdev → preditor}/enum.py +728 -1003
- {blurdev → preditor}/gui/__init__.py +84 -125
- preditor/gui/app.py +159 -0
- {blurdev → preditor}/gui/codehighlighter.py +209 -219
- {blurdev → preditor}/gui/completer.py +226 -236
- {blurdev → preditor}/gui/console.py +801 -858
- {blurdev → preditor}/gui/dialog.py +200 -216
- preditor/gui/drag_tab_bar.py +190 -0
- preditor/gui/editor_chooser.py +57 -0
- {blurdev → preditor}/gui/errordialog.py +100 -97
- preditor/gui/fuzzy_search/fuzzy_search.py +93 -0
- preditor/gui/group_tab_widget/__init__.py +319 -0
- preditor/gui/group_tab_widget/grouped_tab_menu.py +35 -0
- preditor/gui/group_tab_widget/grouped_tab_models.py +108 -0
- preditor/gui/group_tab_widget/grouped_tab_widget.py +75 -0
- preditor/gui/group_tab_widget/one_tab_widget.py +54 -0
- preditor/gui/level_buttons.py +349 -0
- {blurdev → preditor}/gui/logger_window_handler.py +46 -45
- {blurdev → preditor}/gui/loggerwindow.py +1205 -1417
- {blurdev → preditor}/gui/newtabwidget.py +69 -68
- {blurdev → preditor}/gui/redmine_login_dialog.py +63 -61
- {blurdev → preditor}/gui/set_text_editor_path_dialog.py +59 -57
- preditor/gui/ui/editor_chooser.ui +93 -0
- {blurdev → preditor}/gui/ui/errordialog.ui +81 -81
- {blurdev → preditor}/gui/ui/loggerwindow.ui +1030 -864
- {blurdev → preditor}/gui/ui/redmine_login_dialog.ui +124 -124
- {blurdev → preditor}/gui/ui/set_text_editor_path_dialog.ui +149 -149
- {blurdev → preditor}/gui/window.py +183 -199
- preditor/gui/workbox_mixin.py +357 -0
- preditor/gui/workbox_text_edit.py +117 -0
- preditor/gui/workboxwidget.py +276 -0
- preditor/logging_config.py +52 -0
- preditor/osystem.py +401 -0
- preditor/plugins.py +65 -0
- preditor/prefs.py +74 -0
- {blurdev → preditor}/resource/environment_variables.html +26 -38
- {blurdev → preditor}/resource/error_mail.html +85 -85
- {blurdev → preditor}/resource/error_mail_inline.html +41 -41
- preditor/resource/img/README.md +7 -0
- preditor/resource/img/arrow_forward.png +0 -0
- preditor/resource/img/check-bold.png +0 -0
- preditor/resource/img/chevron-down.png +0 -0
- preditor/resource/img/chevron-up.png +0 -0
- preditor/resource/img/close-thick.png +0 -0
- preditor/resource/img/comment-edit.png +0 -0
- preditor/resource/img/content-copy.png +0 -0
- preditor/resource/img/content-cut.png +0 -0
- preditor/resource/img/content-duplicate.png +0 -0
- preditor/resource/img/content-paste.png +0 -0
- preditor/resource/img/content-save.png +0 -0
- preditor/resource/img/debug_disabled.png +0 -0
- preditor/resource/img/eye-check.png +0 -0
- preditor/resource/img/file-plus.png +0 -0
- preditor/resource/img/file-remove.png +0 -0
- preditor/resource/img/format-align-left.png +0 -0
- preditor/resource/img/format-letter-case-lower.png +0 -0
- preditor/resource/img/format-letter-case-upper.png +0 -0
- preditor/resource/img/information.png +0 -0
- preditor/resource/img/logging_critical.png +0 -0
- preditor/resource/img/logging_custom.png +0 -0
- preditor/resource/img/logging_debug.png +0 -0
- preditor/resource/img/logging_error.png +0 -0
- preditor/resource/img/logging_info.png +0 -0
- preditor/resource/img/logging_not_set.png +0 -0
- preditor/resource/img/logging_warning.png +0 -0
- preditor/resource/img/marker.png +0 -0
- preditor/resource/img/play.png +0 -0
- preditor/resource/img/playlist-play.png +0 -0
- preditor/resource/img/plus-minus-variant.png +0 -0
- preditor/resource/img/preditor.ico +0 -0
- preditor/resource/img/preditor.png +0 -0
- preditor/resource/img/preditor.psd +0 -0
- preditor/resource/img/preditor.svg +44 -0
- preditor/resource/img/restart.svg +1 -0
- preditor/resource/img/skip-forward-outline.png +0 -0
- preditor/resource/img/skip-next-outline.png +0 -0
- preditor/resource/img/skip-next.png +0 -0
- preditor/resource/img/skip-previous.png +0 -0
- preditor/resource/img/subdirectory-arrow-right.png +0 -0
- preditor/resource/img/text-search-variant.png +0 -0
- {blurdev → preditor}/resource/lang/python.json +30 -30
- preditor/resource/settings.ini +25 -0
- {blurdev/resource/stylesheet/logger → preditor/resource/stylesheet}/Bright.css +56 -61
- {blurdev → preditor}/resource/stylesheet/Dark.css +190 -132
- {blurdev → preditor}/scintilla/__init__.py +22 -28
- preditor/scintilla/delayables/__init__.py +11 -0
- {blurdev → preditor}/scintilla/delayables/smart_highlight.py +94 -93
- {blurdev → preditor}/scintilla/delayables/spell_check.py +173 -172
- {blurdev → preditor}/scintilla/documenteditor.py +2039 -2115
- {blurdev → preditor}/scintilla/finddialog.py +68 -81
- {blurdev → preditor}/scintilla/lang/__init__.py +80 -93
- {blurdev → preditor}/scintilla/lang/config/bash.ini +15 -15
- {blurdev → preditor}/scintilla/lang/config/batch.ini +14 -14
- {blurdev → preditor}/scintilla/lang/config/cpp.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/css.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/eyeonscript.ini +17 -17
- {blurdev → preditor}/scintilla/lang/config/html.ini +21 -21
- {blurdev → preditor}/scintilla/lang/config/javascript.ini +24 -24
- {blurdev → preditor}/scintilla/lang/config/lua.ini +16 -16
- {blurdev → preditor}/scintilla/lang/config/maxscript.ini +20 -20
- {blurdev → preditor}/scintilla/lang/config/mel.ini +18 -18
- {blurdev → preditor}/scintilla/lang/config/mu.ini +22 -22
- {blurdev → preditor}/scintilla/lang/config/nsi.ini +5 -5
- {blurdev → preditor}/scintilla/lang/config/perl.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/puppet.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/python.ini +28 -28
- {blurdev → preditor}/scintilla/lang/config/ruby.ini +19 -19
- {blurdev → preditor}/scintilla/lang/config/sql.ini +7 -7
- {blurdev → preditor}/scintilla/lang/config/xml.ini +21 -21
- {blurdev → preditor}/scintilla/lang/config/yaml.ini +18 -18
- {blurdev → preditor}/scintilla/lang/language.py +240 -250
- preditor/scintilla/lexers/__init__.py +0 -0
- {blurdev → preditor}/scintilla/lexers/cpplexer.py +21 -30
- {blurdev → preditor}/scintilla/lexers/javascriptlexer.py +25 -34
- {blurdev → preditor}/scintilla/lexers/maxscriptlexer.py +234 -253
- {blurdev → preditor}/scintilla/lexers/mellexer.py +368 -376
- {blurdev → preditor}/scintilla/lexers/mulexer.py +32 -41
- {blurdev → preditor}/scintilla/lexers/pythonlexer.py +41 -50
- {blurdev → preditor}/scintilla/ui/finddialog.ui +160 -160
- preditor/settings.py +71 -0
- preditor/stream/__init__.py +80 -0
- preditor/stream/director.py +56 -0
- preditor/stream/manager.py +74 -0
- preditor/streamhandler_helper.py +46 -0
- preditor/utils/__init__.py +0 -0
- preditor/utils/cute.py +30 -0
- preditor/utils/stylesheets.py +54 -0
- {blurdev → preditor}/version.py +5 -5
- preditor/weakref.py +363 -0
- PrEditor-0.0.0.dev1.dist-info/METADATA +0 -51
- PrEditor-0.0.0.dev1.dist-info/RECORD +0 -279
- PrEditor-0.0.0.dev1.dist-info/top_level.txt +0 -1
- blurdev/__init__.py +0 -356
- blurdev/cores/__init__.py +0 -98
- blurdev/cores/application.py +0 -26
- blurdev/cores/core.py +0 -634
- blurdev/debug.py +0 -593
- blurdev/external.py +0 -391
- blurdev/gui/level_buttons.py +0 -585
- blurdev/gui/workboxwidget.py +0 -205
- blurdev/logger.py +0 -238
- blurdev/osystem.py +0 -813
- blurdev/prefs.py +0 -33
- blurdev/protocols/__init__.py +0 -71
- blurdev/protocols/write_std_output_handler.py +0 -83
- blurdev/resource/designer_plugins.xml +0 -9
- blurdev/resource/error_email_old.html +0 -41
- blurdev/resource/img/add.png +0 -0
- blurdev/resource/img/ajax-loader.gif +0 -0
- blurdev/resource/img/application.png +0 -0
- blurdev/resource/img/applications.png +0 -0
- blurdev/resource/img/assburner.png +0 -0
- blurdev/resource/img/assfreezer.png +0 -0
- blurdev/resource/img/bar.gif +0 -0
- blurdev/resource/img/blank.png +0 -0
- blurdev/resource/img/blurdev.png +0 -0
- blurdev/resource/img/calendar_disabled.png +0 -0
- blurdev/resource/img/calendar_enabled.png +0 -0
- blurdev/resource/img/cancel.png +0 -0
- blurdev/resource/img/custom.png +0 -0
- blurdev/resource/img/debug_high.png +0 -0
- blurdev/resource/img/debug_low.png +0 -0
- blurdev/resource/img/debug_mid.png +0 -0
- blurdev/resource/img/debug_off.png +0 -0
- blurdev/resource/img/django.png +0 -0
- blurdev/resource/img/doc.png +0 -0
- blurdev/resource/img/edit.png +0 -0
- blurdev/resource/img/elemental.png +0 -0
- blurdev/resource/img/explore.png +0 -0
- blurdev/resource/img/favorite.png +0 -0
- blurdev/resource/img/file.png +0 -0
- blurdev/resource/img/folder.png +0 -0
- blurdev/resource/img/ide/add.png +0 -0
- blurdev/resource/img/ide/add_note.png +0 -0
- blurdev/resource/img/ide/arrow_down.png +0 -0
- blurdev/resource/img/ide/arrow_up.png +0 -0
- blurdev/resource/img/ide/check.png +0 -0
- blurdev/resource/img/ide/class.png +0 -0
- blurdev/resource/img/ide/clean.png +0 -0
- blurdev/resource/img/ide/clearlog.png +0 -0
- blurdev/resource/img/ide/close.png +0 -0
- blurdev/resource/img/ide/comment_add.png +0 -0
- blurdev/resource/img/ide/comment_remove.png +0 -0
- blurdev/resource/img/ide/comment_toggle.png +0 -0
- blurdev/resource/img/ide/console.png +0 -0
- blurdev/resource/img/ide/copy.png +0 -0
- blurdev/resource/img/ide/copylstrip.png +0 -0
- blurdev/resource/img/ide/cut.png +0 -0
- blurdev/resource/img/ide/edit.png +0 -0
- blurdev/resource/img/ide/find.png +0 -0
- blurdev/resource/img/ide/find_replace.png +0 -0
- blurdev/resource/img/ide/findnext.png +0 -0
- blurdev/resource/img/ide/findprev.png +0 -0
- blurdev/resource/img/ide/folder_find.png +0 -0
- blurdev/resource/img/ide/function.png +0 -0
- blurdev/resource/img/ide/git-bash.png +0 -0
- blurdev/resource/img/ide/git-gui.png +0 -0
- blurdev/resource/img/ide/gitk.png +0 -0
- blurdev/resource/img/ide/goto.png +0 -0
- blurdev/resource/img/ide/goto_def.png +0 -0
- blurdev/resource/img/ide/help.png +0 -0
- blurdev/resource/img/ide/highlighter.png +0 -0
- blurdev/resource/img/ide/lowercase.png +0 -0
- blurdev/resource/img/ide/newfile.png +0 -0
- blurdev/resource/img/ide/newfolder.png +0 -0
- blurdev/resource/img/ide/newproject.png +0 -0
- blurdev/resource/img/ide/newwizard.png +0 -0
- blurdev/resource/img/ide/open.png +0 -0
- blurdev/resource/img/ide/paste.png +0 -0
- blurdev/resource/img/ide/pdb_continue.png +0 -0
- blurdev/resource/img/ide/pdb_down.png +0 -0
- blurdev/resource/img/ide/pdb_next.png +0 -0
- blurdev/resource/img/ide/pdb_step.png +0 -0
- blurdev/resource/img/ide/pdb_up.png +0 -0
- blurdev/resource/img/ide/plus_minus.png +0 -0
- blurdev/resource/img/ide/preferences.png +0 -0
- blurdev/resource/img/ide/project_find.png +0 -0
- blurdev/resource/img/ide/python.png +0 -0
- blurdev/resource/img/ide/pyular.png +0 -0
- blurdev/resource/img/ide/qt.png +0 -0
- blurdev/resource/img/ide/quit.png +0 -0
- blurdev/resource/img/ide/redo.png +0 -0
- blurdev/resource/img/ide/refresh.png +0 -0
- blurdev/resource/img/ide/remove.png +0 -0
- blurdev/resource/img/ide/ruler.png +0 -0
- blurdev/resource/img/ide/run.png +0 -0
- blurdev/resource/img/ide/runall.png +0 -0
- blurdev/resource/img/ide/runallclear.png +0 -0
- blurdev/resource/img/ide/runselected.png +0 -0
- blurdev/resource/img/ide/runselectedclear.png +0 -0
- blurdev/resource/img/ide/save.png +0 -0
- blurdev/resource/img/ide/saveas.png +0 -0
- blurdev/resource/img/ide/sdk.png +0 -0
- blurdev/resource/img/ide/separator.png +0 -0
- blurdev/resource/img/ide/tabbed.png +0 -0
- blurdev/resource/img/ide/tile.png +0 -0
- blurdev/resource/img/ide/toolbar.png +0 -0
- blurdev/resource/img/ide/undo.png +0 -0
- blurdev/resource/img/ide/uppercase.png +0 -0
- blurdev/resource/img/ide/view_as.png +0 -0
- blurdev/resource/img/ide/windowed.png +0 -0
- blurdev/resource/img/ide.ico +0 -0
- blurdev/resource/img/ide.png +0 -0
- blurdev/resource/img/ide48.png +0 -0
- blurdev/resource/img/info.png +0 -0
- blurdev/resource/img/legacy tool.png +0 -0
- blurdev/resource/img/library.png +0 -0
- blurdev/resource/img/logger/about.png +0 -0
- blurdev/resource/img/logger/arrow_forward.png +0 -0
- blurdev/resource/img/logger/clear.png +0 -0
- blurdev/resource/img/logger/close.png +0 -0
- blurdev/resource/img/logger/debug_disabled.png +0 -0
- blurdev/resource/img/logger/debug_high.png +0 -0
- blurdev/resource/img/logger/debug_low.png +0 -0
- blurdev/resource/img/logger/debug_mid.png +0 -0
- blurdev/resource/img/logger/down.png +0 -0
- blurdev/resource/img/logger/find.png +0 -0
- blurdev/resource/img/logger/logging_critical.png +0 -0
- blurdev/resource/img/logger/logging_debug.png +0 -0
- blurdev/resource/img/logger/logging_error.png +0 -0
- blurdev/resource/img/logger/logging_info.png +0 -0
- blurdev/resource/img/logger/logging_not_set.png +0 -0
- blurdev/resource/img/logger/logging_warning.png +0 -0
- blurdev/resource/img/logger/next.png +0 -0
- blurdev/resource/img/logger/play.png +0 -0
- blurdev/resource/img/logger/playlist_play.png +0 -0
- blurdev/resource/img/logger/previous.png +0 -0
- blurdev/resource/img/logger/return.png +0 -0
- blurdev/resource/img/logger/save.png +0 -0
- blurdev/resource/img/logger/subdirectory_arrow_right.png +0 -0
- blurdev/resource/img/logger/up.png +0 -0
- blurdev/resource/img/lovebar.png +0 -0
- blurdev/resource/img/new.png +0 -0
- blurdev/resource/img/new_selected.png +0 -0
- blurdev/resource/img/node.png +0 -0
- blurdev/resource/img/ok.png +0 -0
- blurdev/resource/img/options.png +0 -0
- blurdev/resource/img/packages.png +0 -0
- blurdev/resource/img/preview/add.png +0 -0
- blurdev/resource/img/preview/brush.png +0 -0
- blurdev/resource/img/preview/delete.png +0 -0
- blurdev/resource/img/preview/delte.png +0 -0
- blurdev/resource/img/preview/fill.png +0 -0
- blurdev/resource/img/preview/layers.png +0 -0
- blurdev/resource/img/preview/media.png +0 -0
- blurdev/resource/img/preview/navigate.png +0 -0
- blurdev/resource/img/preview/pencil.png +0 -0
- blurdev/resource/img/preview/select.png +0 -0
- blurdev/resource/img/preview/type.png +0 -0
- blurdev/resource/img/preview/visible.png +0 -0
- blurdev/resource/img/project.png +0 -0
- blurdev/resource/img/python_logger.ico +0 -0
- blurdev/resource/img/python_logger.png +0 -0
- blurdev/resource/img/refresh.png +0 -0
- blurdev/resource/img/remove.png +0 -0
- blurdev/resource/img/reset.png +0 -0
- blurdev/resource/img/richtext/font_bold.png +0 -0
- blurdev/resource/img/richtext/font_italic.png +0 -0
- blurdev/resource/img/richtext/link_image.png +0 -0
- blurdev/resource/img/richtext/spell_check.png +0 -0
- blurdev/resource/img/richtext/unordered_list.png +0 -0
- blurdev/resource/img/save.png +0 -0
- blurdev/resource/img/savesettings.png +0 -0
- blurdev/resource/img/settings.png +0 -0
- blurdev/resource/img/tool.png +0 -0
- blurdev/resource/img/toolbarHandleHorizontal.png +0 -0
- blurdev/resource/img/toolbarHandleVertical.png +0 -0
- blurdev/resource/img/trash.png +0 -0
- blurdev/resource/img/trax.png +0 -0
- blurdev/resource/img/tree.png +0 -0
- blurdev/resource/img/treegrunt.ico +0 -0
- blurdev/resource/img/treegrunt.png +0 -0
- blurdev/resource/img/treegruntedit.png +0 -0
- blurdev/resource/img/user interface.png +0 -0
- blurdev/resource/img/warning.png +0 -0
- blurdev/resource/img/watermark.png +0 -0
- blurdev/resource/sdk/blurdev.sdk +0 -3
- blurdev/resource/settings.ini +0 -82
- blurdev/resource/softimage/BlurApplication.dll +0 -0
- blurdev/resource/softimage/BlurApplication64.dll +0 -0
- blurdev/resource/stylesheet/Carbon.css +0 -35
- blurdev/resource/stylesheet/logger/Dark.css +0 -62
- blurdev/resource/templ/py_comment.templ +0 -1
- blurdev/resource/templ/py_debug_raise_error.templ +0 -7
- blurdev/resource/templ/py_doc_string.templ +0 -10
- blurdev/resource/templ/py_header.templ +0 -9
- blurdev/resource/templ/py_line_comment.templ +0 -1
- blurdev/resource/templ/py_log_to_file.templ +0 -22
- blurdev/resource/templ/py_module_path.templ +0 -1
- blurdev/resource/templ/py_pyqt_core.templ +0 -1
- blurdev/resource/templ/py_pyqt_gui.templ +0 -1
- blurdev/resource/templ/py_splashscreen.templ +0 -6
- blurdev/resource/templ/py_testing_note.templ +0 -1
- blurdev/resource/templ/py_testing_note_end.templ +0 -1
- blurdev/resource/tools_environments.json +0 -72
- blurdev/resource/tools_environments.xml +0 -11
- blurdev/resource/tools_environments_linux.xml +0 -11
- blurdev/resource/tools_environments_offline.xml +0 -7
- blurdev/runtimes/__init__.py +0 -2
- blurdev/runtimes/logger.py +0 -44
- blurdev/scintilla/delayables/__init__.py +0 -9
- blurdev/settings.py +0 -312
- blurdev/utils/error.py +0 -389
- {blurdev/scintilla/lexers → preditor/cores}/__init__.py +0 -0
- {blurdev/utils → preditor/gui/fuzzy_search}/__init__.py +0 -0
- {blurdev → preditor}/resource/img/warning-big.png +0 -0
|
@@ -1,216 +1,200 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
#
|
|
85
|
-
self.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
#
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
self.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
def
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
def
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
"""
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
this.close()
|
|
202
|
-
except RuntimeError:
|
|
203
|
-
pass
|
|
204
|
-
|
|
205
|
-
@classmethod
|
|
206
|
-
def instanceShutdown(cls):
|
|
207
|
-
"""Call shutdown on this class instance only if the class was instantiated.
|
|
208
|
-
|
|
209
|
-
Returns:
|
|
210
|
-
bool: if cls.instance().shutdown() needed to be called.
|
|
211
|
-
"""
|
|
212
|
-
instance = cls._instance
|
|
213
|
-
if instance:
|
|
214
|
-
instance.shutdown()
|
|
215
|
-
return True
|
|
216
|
-
return False
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
|
|
3
|
+
from Qt.QtCore import Qt
|
|
4
|
+
from Qt.QtWidgets import QDialog
|
|
5
|
+
|
|
6
|
+
from .. import core, relativePath, root_window
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Dialog(QDialog):
|
|
10
|
+
_instance = None
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def instance(cls, parent=None):
|
|
14
|
+
"""If you only want to have one instance of a dialog, use this method instead
|
|
15
|
+
of creating a new dialog. It will only create a new instance of the class if
|
|
16
|
+
the class variable _instance is none.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
parent (QWidget, optional):The parent widget
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Dialog:
|
|
23
|
+
"""
|
|
24
|
+
if not cls._instance:
|
|
25
|
+
cls._instance = cls(parent=parent)
|
|
26
|
+
# protect the memory
|
|
27
|
+
cls._instance.setAttribute(Qt.WA_DeleteOnClose, False)
|
|
28
|
+
# but make sure that if we reload the environment, everything gets deleted
|
|
29
|
+
# properly
|
|
30
|
+
core.aboutToClearPaths.connect(cls._instance.shutdown)
|
|
31
|
+
return cls._instance
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self, parent=None, flags=Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
|
|
35
|
+
):
|
|
36
|
+
# if there is no root, create
|
|
37
|
+
if not parent:
|
|
38
|
+
parent = root_window()
|
|
39
|
+
|
|
40
|
+
# create a QDialog
|
|
41
|
+
if flags:
|
|
42
|
+
QDialog.__init__(self, parent, flags)
|
|
43
|
+
else:
|
|
44
|
+
QDialog.__init__(self, parent)
|
|
45
|
+
|
|
46
|
+
# INFO
|
|
47
|
+
#
|
|
48
|
+
# As far as we can tell, the purpose for this class is keeping live
|
|
49
|
+
# references to the subclasses so they don't get garbage collected, all while
|
|
50
|
+
# getting around having to actively maintain a list of running dialogs.
|
|
51
|
+
#
|
|
52
|
+
# Generally, setting WA_DeleteOnClose to False, and keeping the _instance
|
|
53
|
+
# variable around will do the trick for pseudo-singleton dialogs. (created with
|
|
54
|
+
# instance=True)
|
|
55
|
+
#
|
|
56
|
+
# However, for non-instanced dialogs where multiples are allowed, deleteOnClose
|
|
57
|
+
# is set to True and no _instance variable is set. Because there are no live
|
|
58
|
+
# references to the dialog, it is closed and garbage collected almost
|
|
59
|
+
# immediately in certain programs (xsi, maya).
|
|
60
|
+
#
|
|
61
|
+
# The current workaround is to manually set WA_DeleteOnClose to False, however
|
|
62
|
+
# this causes any subclasses to stick around in memory even when the
|
|
63
|
+
# window/dialog is closed. So you also have to manually set WA_DeleteOnClose to
|
|
64
|
+
# True in the sub-classed .closeEvent() method before you call super()
|
|
65
|
+
#
|
|
66
|
+
# It is completely possible to write some code that would automatically handle
|
|
67
|
+
# this, and it is CERTAINLY something we can/will be doing in the future, but
|
|
68
|
+
# for now we're not quite sure how that would affect the production tools.
|
|
69
|
+
# Technically this is a problem, but there are currently no consequences from an
|
|
70
|
+
# artist standpoint because we have more than enough memory to hold all those
|
|
71
|
+
# dead dialogs
|
|
72
|
+
|
|
73
|
+
# set the delete attribute to clean up the window once it is closed
|
|
74
|
+
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
75
|
+
|
|
76
|
+
# set this property to true to properly handle tracking events to control
|
|
77
|
+
# keyboard overrides
|
|
78
|
+
self.setMouseTracking(True)
|
|
79
|
+
|
|
80
|
+
# If this value is set to False calling setGeometry on this dialog will not
|
|
81
|
+
# adjust the geometry to ensure the dialog is on a valid screen.
|
|
82
|
+
self.checkScreenGeo = True
|
|
83
|
+
# If this value is set to True the dialog will listen for
|
|
84
|
+
# core.aboutToClearPaths and call shutdown on the dialog.
|
|
85
|
+
self.aboutToClearPathsEnabled = True
|
|
86
|
+
# attempt to set the dialog icon
|
|
87
|
+
import os
|
|
88
|
+
import sys
|
|
89
|
+
|
|
90
|
+
from Qt.QtGui import QIcon
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
path = relativePath(
|
|
94
|
+
os.path.abspath(sys.modules[self.__class__.__module__].__file__),
|
|
95
|
+
'img/icon.png',
|
|
96
|
+
)
|
|
97
|
+
if os.path.exists(path):
|
|
98
|
+
self.setWindowIcon(QIcon(path))
|
|
99
|
+
except (AttributeError, KeyError):
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
def _shouldDisableAccelerators(self, old, now):
|
|
103
|
+
"""Used to enable typing in DCC's that require it(Max 2018).
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
old (QWidget or None): The QWidget that lost focus.
|
|
107
|
+
new (QWidget or None): The QWidget that gained focus.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
bool: If accelerators should be disabled.
|
|
111
|
+
"""
|
|
112
|
+
# By default we always want to disable accelerators.
|
|
113
|
+
return True
|
|
114
|
+
|
|
115
|
+
def closeEvent(self, event):
|
|
116
|
+
# ensure this object gets deleted
|
|
117
|
+
wwidget = None
|
|
118
|
+
if self.testAttribute(Qt.WA_DeleteOnClose):
|
|
119
|
+
# collect the win widget to uncache it
|
|
120
|
+
if self.parent() and self.parent().inherits('QWinWidget'):
|
|
121
|
+
wwidget = self.parent()
|
|
122
|
+
|
|
123
|
+
QDialog.closeEvent(self, event)
|
|
124
|
+
|
|
125
|
+
# uncache the win widget if necessary
|
|
126
|
+
if wwidget:
|
|
127
|
+
from .winwidget import WinWidget
|
|
128
|
+
|
|
129
|
+
WinWidget.uncache(wwidget)
|
|
130
|
+
|
|
131
|
+
# only disconnect here if deleting on close
|
|
132
|
+
if self.aboutToClearPathsEnabled and self.testAttribute(Qt.WA_DeleteOnClose):
|
|
133
|
+
try:
|
|
134
|
+
core.aboutToClearPaths.disconnect(self.shutdown)
|
|
135
|
+
except TypeError:
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
def exec_(self):
|
|
139
|
+
# do not use the DeleteOnClose attribute when executing a dialog as often times
|
|
140
|
+
# a user will be accessing information from the dialog instance after it closes.
|
|
141
|
+
# This function properly transfers ownership of the dialog instance back to
|
|
142
|
+
# Python anyway
|
|
143
|
+
|
|
144
|
+
self.setAttribute(Qt.WA_DeleteOnClose, False)
|
|
145
|
+
|
|
146
|
+
# execute the dialog
|
|
147
|
+
return QDialog.exec_(self)
|
|
148
|
+
|
|
149
|
+
def setGeometry(self, *args):
|
|
150
|
+
"""
|
|
151
|
+
Sets the dialog's geometry, It will also check if the geometry is visible on any
|
|
152
|
+
monitors. If it is not it will move the dialog so it is visible. This can be
|
|
153
|
+
disabled by setting self.checkScreenGeo to False
|
|
154
|
+
"""
|
|
155
|
+
super(Dialog, self).setGeometry(*args)
|
|
156
|
+
if self.checkScreenGeo:
|
|
157
|
+
from ..utils.cute import ensureWindowIsVisible
|
|
158
|
+
|
|
159
|
+
ensureWindowIsVisible(self)
|
|
160
|
+
|
|
161
|
+
def showEvent(self, event):
|
|
162
|
+
# listen for aboutToClearPaths signal if requested
|
|
163
|
+
# but only connect here if deleting on close
|
|
164
|
+
if self.aboutToClearPathsEnabled and self.testAttribute(Qt.WA_DeleteOnClose):
|
|
165
|
+
core.aboutToClearPaths.connect(self.shutdown)
|
|
166
|
+
super(Dialog, self).showEvent(event)
|
|
167
|
+
|
|
168
|
+
def shutdown(self):
|
|
169
|
+
# use a @classmethod to make inheritance magically work
|
|
170
|
+
self._shutdown(self)
|
|
171
|
+
|
|
172
|
+
@classmethod
|
|
173
|
+
def _shutdown(cls, this):
|
|
174
|
+
"""
|
|
175
|
+
If this item is the class instance properly close it and remove it from memory
|
|
176
|
+
so it can be recreated.
|
|
177
|
+
"""
|
|
178
|
+
# allow the global instance to be cleared
|
|
179
|
+
if this == cls._instance:
|
|
180
|
+
cls._instance = None
|
|
181
|
+
if this.aboutToClearPathsEnabled:
|
|
182
|
+
core.aboutToClearPaths.disconnect(this.shutdown)
|
|
183
|
+
this.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
184
|
+
try:
|
|
185
|
+
this.close()
|
|
186
|
+
except RuntimeError:
|
|
187
|
+
pass
|
|
188
|
+
|
|
189
|
+
@classmethod
|
|
190
|
+
def instance_shutdown(cls):
|
|
191
|
+
"""Call shutdown on this class instance only if the class was instantiated.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
bool: if cls.instance().shutdown() needed to be called.
|
|
195
|
+
"""
|
|
196
|
+
instance = cls._instance
|
|
197
|
+
if instance:
|
|
198
|
+
instance.shutdown()
|
|
199
|
+
return True
|
|
200
|
+
return False
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
|
|
3
|
+
from Qt.QtCore import QByteArray, QMimeData, QPoint, QRect, Qt
|
|
4
|
+
from Qt.QtGui import QCursor, QDrag, QPixmap, QRegion
|
|
5
|
+
from Qt.QtWidgets import QInputDialog, QMenu, QTabBar
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DragTabBar(QTabBar):
|
|
9
|
+
"""A QTabBar that allows you to drag and drop its tabs to other DragTabBar's
|
|
10
|
+
while still allowing you to move tabs normally.
|
|
11
|
+
|
|
12
|
+
In most cases you should use `install_tab_widget` to create and add this TabBar
|
|
13
|
+
to a QTabWidget. It takes care of enabling usability features of QTabWidget's.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
mime_type (str, optional): Only accepts dropped tabs that implement this
|
|
17
|
+
Mime Type. Tabs dragged off of this TabBar will have this Mime Type
|
|
18
|
+
implemented.
|
|
19
|
+
|
|
20
|
+
Based on code by ARussel: https://forum.qt.io/post/420469
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, parent=None, mime_type='DragTabBar'):
|
|
24
|
+
super(DragTabBar, self).__init__(parent=parent)
|
|
25
|
+
self.setAcceptDrops(True)
|
|
26
|
+
self.setMouseTracking(True)
|
|
27
|
+
self._mime_data = None
|
|
28
|
+
self._context_menu_tab = -1
|
|
29
|
+
self.mime_type = mime_type
|
|
30
|
+
|
|
31
|
+
def mouseMoveEvent(self, event): # noqa: N802
|
|
32
|
+
|
|
33
|
+
if not self._mime_data:
|
|
34
|
+
return super(DragTabBar, self).mouseMoveEvent(event)
|
|
35
|
+
|
|
36
|
+
# Check if the mouse has moved outside of the widget, if not, let
|
|
37
|
+
# the QTabBar handle the internal tab movement.
|
|
38
|
+
event_pos = event.pos()
|
|
39
|
+
global_pos = self.mapToGlobal(event_pos)
|
|
40
|
+
bar_geo = QRect(self.mapToGlobal(self.pos()), self.size())
|
|
41
|
+
inside = bar_geo.contains(global_pos)
|
|
42
|
+
if inside:
|
|
43
|
+
return super(DragTabBar, self).mouseMoveEvent(event)
|
|
44
|
+
|
|
45
|
+
# The user has moved the tab outside of the QTabBar, remove the tab from
|
|
46
|
+
# this tab bar and store it in the MimeData, initiating a drag event.
|
|
47
|
+
widget = self._mime_data.property('widget')
|
|
48
|
+
tab_index = self.parentWidget().indexOf(widget)
|
|
49
|
+
self.parentWidget().removeTab(tab_index)
|
|
50
|
+
pos_in_tab = self.mapFromGlobal(global_pos)
|
|
51
|
+
drag = QDrag(self)
|
|
52
|
+
drag.setMimeData(self._mime_data)
|
|
53
|
+
drag.setPixmap(self._mime_data.imageData())
|
|
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)
|
|
58
|
+
# If the user didn't successfully add this to a new tab widget, restore
|
|
59
|
+
# the tab to the original location.
|
|
60
|
+
if action == Qt.IgnoreAction:
|
|
61
|
+
original_tab_index = self._mime_data.property('original_tab_index')
|
|
62
|
+
self.parentWidget().insertTab(
|
|
63
|
+
original_tab_index, widget, self._mime_data.text()
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
self._mime_data = None
|
|
67
|
+
|
|
68
|
+
def mousePressEvent(self, event): # noqa: N802
|
|
69
|
+
if event.button() == Qt.LeftButton and not self._mime_data:
|
|
70
|
+
tab_index = self.tabAt(event.pos())
|
|
71
|
+
|
|
72
|
+
# While we don't remove the tab on mouse press, capture its tab image
|
|
73
|
+
# and attach it to the mouse. This also stores info needed to handle
|
|
74
|
+
# moving the tab to a new QTabWidget, and undoing the move if the
|
|
75
|
+
# user cancels the drop.
|
|
76
|
+
tab_rect = self.tabRect(tab_index)
|
|
77
|
+
pixmap = QPixmap(tab_rect.size())
|
|
78
|
+
self.render(pixmap, QPoint(), QRegion(tab_rect))
|
|
79
|
+
|
|
80
|
+
self._mime_data = QMimeData()
|
|
81
|
+
self._mime_data.setData(self.mime_type, QByteArray())
|
|
82
|
+
self._mime_data.setText(self.tabText(tab_index))
|
|
83
|
+
self._mime_data.setProperty('original_tab_index', tab_index)
|
|
84
|
+
self._mime_data.setImageData(pixmap)
|
|
85
|
+
widget = self.parentWidget().widget(tab_index)
|
|
86
|
+
self._mime_data.setProperty('widget', widget)
|
|
87
|
+
|
|
88
|
+
# By default if there are no tabs, the tab bar is hidden. This
|
|
89
|
+
# prevents users from re-adding tabs to the tab bar as only it
|
|
90
|
+
# accepts the tab drops. This preserves the tab bar height
|
|
91
|
+
# after it was drawn with a tab so it should automatically stay
|
|
92
|
+
# the same visual height.
|
|
93
|
+
if not self.minimumHeight():
|
|
94
|
+
self.setMinimumHeight(self.height())
|
|
95
|
+
|
|
96
|
+
super(DragTabBar, self).mousePressEvent(event)
|
|
97
|
+
|
|
98
|
+
def mouseReleaseEvent(self, event): # noqa: N802
|
|
99
|
+
self._mime_data = None
|
|
100
|
+
super(DragTabBar, self).mouseReleaseEvent(event)
|
|
101
|
+
|
|
102
|
+
def dragEnterEvent(self, event): # noqa: N802
|
|
103
|
+
# if event.mimeData().hasFormat(self.mime_type):
|
|
104
|
+
event.accept()
|
|
105
|
+
|
|
106
|
+
def dragLeaveEvent(self, event): # noqa: N802
|
|
107
|
+
event.accept()
|
|
108
|
+
|
|
109
|
+
def dragMoveEvent(self, event): # noqa: N802
|
|
110
|
+
# If this is not a tab of the same mime type, make the tab under the mouse
|
|
111
|
+
# the current tab so users can easily drop inside that tab.
|
|
112
|
+
if not event.mimeData().hasFormat(self.mime_type):
|
|
113
|
+
event.accept()
|
|
114
|
+
tab_index = self.tabAt(event.pos())
|
|
115
|
+
if tab_index == -1:
|
|
116
|
+
tab_index = self.count() - 1
|
|
117
|
+
if self.currentIndex() != tab_index:
|
|
118
|
+
self.setCurrentIndex(tab_index)
|
|
119
|
+
|
|
120
|
+
def dropEvent(self, event): # noqa: N802
|
|
121
|
+
if not event.mimeData().hasFormat(self.mime_type):
|
|
122
|
+
return
|
|
123
|
+
if event.source().parentWidget() == self:
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
event.setDropAction(Qt.MoveAction)
|
|
127
|
+
event.accept()
|
|
128
|
+
counter = self.count()
|
|
129
|
+
|
|
130
|
+
mime_data = event.mimeData()
|
|
131
|
+
if counter == 0:
|
|
132
|
+
self.parent().addTab(mime_data.property('widget'), mime_data.text())
|
|
133
|
+
else:
|
|
134
|
+
self.parent().insertTab(
|
|
135
|
+
counter + 1, mime_data.property('widget'), mime_data.text()
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
def rename_tab(self):
|
|
139
|
+
"""Used by the tab_menu to rename the tab at index `_context_menu_tab`."""
|
|
140
|
+
if self._context_menu_tab != -1:
|
|
141
|
+
current = self.tabText(self._context_menu_tab)
|
|
142
|
+
msg = 'Rename the {} tab to:'.format(current)
|
|
143
|
+
name, success = QInputDialog.getText(self, 'Rename Tab', msg, text=current)
|
|
144
|
+
if success:
|
|
145
|
+
self.setTabText(self._context_menu_tab, name)
|
|
146
|
+
|
|
147
|
+
def tab_menu(self, pos, popup=True):
|
|
148
|
+
"""Creates the custom context menu for the tab bar. To customize the menu
|
|
149
|
+
call super setting `popup=False`. This will return the menu for
|
|
150
|
+
customization and you will then need to call popup on the menu.
|
|
151
|
+
|
|
152
|
+
This method sets the tab index the user right clicked on in the variable
|
|
153
|
+
`_context_menu_tab`. This can be used in the triggered QAction methods."""
|
|
154
|
+
|
|
155
|
+
self._context_menu_tab = self.tabAt(pos)
|
|
156
|
+
if self._context_menu_tab == -1:
|
|
157
|
+
return
|
|
158
|
+
menu = QMenu(self)
|
|
159
|
+
act = menu.addAction('Rename')
|
|
160
|
+
act.triggered.connect(self.rename_tab)
|
|
161
|
+
|
|
162
|
+
if popup:
|
|
163
|
+
menu.popup(self.mapToGlobal(pos))
|
|
164
|
+
|
|
165
|
+
return menu
|
|
166
|
+
|
|
167
|
+
@classmethod
|
|
168
|
+
def install_tab_widget(cls, tab_widget, mime_type='DragTabBar', menu=True):
|
|
169
|
+
"""Creates and returns a instance of DragTabBar and installs it on the
|
|
170
|
+
QTabWidget. This enables movable tabs, and enables document mode.
|
|
171
|
+
Document mode makes the tab bar expand to the size of the QTabWidget so
|
|
172
|
+
drag drop operations are more intuitive.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
tab_widget (QTabWidget): The QTabWidget to install the tab bar on.
|
|
176
|
+
mime_data (str, optional): This TabBar will only accept tab drop
|
|
177
|
+
operations with this mime type.
|
|
178
|
+
menu (bool, optional): Install a custom context menu on the bar bar.
|
|
179
|
+
Override `tab_menu` to customize the menu.
|
|
180
|
+
"""
|
|
181
|
+
bar = cls(tab_widget, mime_type=mime_type)
|
|
182
|
+
tab_widget.setTabBar(bar)
|
|
183
|
+
tab_widget.setMovable(True)
|
|
184
|
+
tab_widget.setDocumentMode(True)
|
|
185
|
+
|
|
186
|
+
if menu:
|
|
187
|
+
bar.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
188
|
+
bar.customContextMenuRequested.connect(bar.tab_menu)
|
|
189
|
+
|
|
190
|
+
return bar
|