pyqttoolkit 0.8.0.dev0__tar.gz → 0.8.0.post1__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.
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/PKG-INFO +5 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/_version.py +3 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/application/application.py +2 -11
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/application/garbage_collector.py +14 -14
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/environment.py +8 -1
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/with_signal.py +1 -1
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/with_value_changed.py +3 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/data/__init__.py +1 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/data/interval.py +8 -11
- pyqttoolkit-0.8.0.post1/pyqttoolkit/data/message.py +29 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/datetime/qdatetime.py +2 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/dependencies/__init__.py +7 -5
- pyqttoolkit-0.8.0.post1/pyqttoolkit/exceptions/__init__.py +18 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/logs/__init__.py +29 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/code_text.py +8 -5
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/dataframetable.py +1 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/dictpropertytree.py +1 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/dicttable.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/json_text.py +1 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/list_model.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/span.py +36 -32
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/modules/events/rejectable.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/modules/launcher_config.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/modules/module.py +3 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/scripting/script_runner.py +14 -11
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/event_registry.py +1 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/file_dialog.py +24 -7
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/hotkey_manager.py +1 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/link_manager.py +2 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/message_board.py +22 -21
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/module_service.py +26 -17
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/project_updater.py +5 -6
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/task_runner.py +11 -14
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/tool_window_service.py +1 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/__init__.py +1 -1
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/bulk_value_selector.py +15 -6
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/check_box.py +2 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/code/code_edit.py +25 -15
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/combo_box.py +1 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/count_selector.py +2 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/datetime.py +9 -8
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/datetime_range_selector.py +56 -14
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/delegates.py +3 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/dtype_edit.py +3 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/file_selector.py +2 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/icon.py +12 -11
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/icon_button.py +3 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/labelled.py +1 -1
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/layout/__init__.py +1 -1
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/layout/collabsible.py +2 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/layout/group_box.py +2 -2
- pyqttoolkit-0.8.0.post1/pyqttoolkit/views/layout/group_panel.py +188 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/layout/lines.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/layout/link.py +1 -1
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/line_edit.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/linkable.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/list_view.py +2 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/main_window.py +10 -8
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/metadata_selector.py +2 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/modulewindow.py +12 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/legend_control.py +10 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/matplotlib/__init__.py +23 -23
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/matplotlib/base.py +175 -64
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/plot_options.py +8 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/plot_toolbar_options.py +4 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/toolbar.py +2 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/popout.py +2 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/popup.py +5 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/property_tree.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/shrunk_push_button.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/steppable_combo_box.py +2 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/styleable.py +18 -17
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/table.py +3 -3
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/text_edit.py +3 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/tool_window.py +1 -2
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit.egg-info/PKG-INFO +5 -4
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit.egg-info/SOURCES.txt +2 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit.egg-info/requires.txt +3 -1
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/setup.py +5 -5
- pyqttoolkit-0.8.0.dev0/pyqttoolkit/views/layout/group_panel.py +0 -114
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/MANIFEST.in +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/README.md +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/application/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/colors/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/base.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/composite.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/default.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/config/multi_json_file.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/data/bits.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/data/cache.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/data/names.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/datetime/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/datetime/datetime.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/errors/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/filesystem/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/metadata/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/metadata/dataframe_metadata_manager.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/metadata/dict_metadata_manager.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/metadata/id_generator.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/metadata/metadata_manager_base.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/module.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/roles.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/series_data.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/models/validation.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/modules/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/modules/events/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/modules/events/add_signal.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/modules/events/module_opening.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/properties/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/properties/auto.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/properties/throttled.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/scripting/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/scripting/script_context.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/scripting/script_template.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/autosave.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/email.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/object_converter.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/services/theme_manager.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/viewmanagers/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/viewmanagers/tool.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/code/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/code/python_syntax.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/default_text_line_edit.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/editable_combo_box.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/json_edit.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/__init__.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/matplotlib/colorbar.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/matplotlib/colormap.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/matplotlib/font.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/size.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/views/plot/tool_type.py +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit.egg-info/dependency_links.txt +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit.egg-info/top_level.txt +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/setup.cfg +0 -0
- {pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/versioneer.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyqttoolkit
|
|
3
|
-
Version: 0.8.0.
|
|
3
|
+
Version: 0.8.0.post1
|
|
4
4
|
Summary: A toolkit for PyQt 5
|
|
5
|
-
Home-page: https://github.com/
|
|
6
|
-
Author:
|
|
7
|
-
Author-email: info@
|
|
5
|
+
Home-page: https://github.com/BitBloomTech/pyqttoolkit
|
|
6
|
+
Author: Bitbloom Ltd
|
|
7
|
+
Author-email: info@bitbloom.tech
|
|
8
8
|
License: GPLv3
|
|
9
9
|
Description: # PyQtToolkit
|
|
10
10
|
|
|
@@ -13,4 +13,5 @@ Platform: any
|
|
|
13
13
|
Requires-Python: >=3.6
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
Provides-Extra: publish
|
|
16
|
+
Provides-Extra: ui
|
|
16
17
|
Provides-Extra: test
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "
|
|
11
|
+
"date": "2025-02-10T10:45:17-0600",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "0.8.0
|
|
14
|
+
"full-revisionid": "c01a30f0721570aa53de3b069854c5c25e9ebdb6",
|
|
15
|
+
"version": "0.8.0-1"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -17,9 +17,8 @@
|
|
|
17
17
|
import sys
|
|
18
18
|
import logging
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
from PyQt5.
|
|
22
|
-
#pyline: enable=no-name-in-module
|
|
20
|
+
from PyQt5.QtCore import pyqtSignal
|
|
21
|
+
from PyQt5.QtWidgets import QApplication, QWidget
|
|
23
22
|
|
|
24
23
|
from pyqttoolkit.services import MessageBoard, TaskRunner, ToolWindowService, EventRegistry, ObjectConverter
|
|
25
24
|
from pyqttoolkit.dependencies import DependencyContainer
|
|
@@ -54,14 +53,6 @@ class Application(QApplication):
|
|
|
54
53
|
self.mainWindowLoaded.emit(self._module_service.openModule('Base'))
|
|
55
54
|
return self.exec_()
|
|
56
55
|
|
|
57
|
-
def notify(self, receiver, event):
|
|
58
|
-
try:
|
|
59
|
-
return QApplication.notify(self, receiver, event)
|
|
60
|
-
#pylint: disable=broad-except
|
|
61
|
-
except Exception as e:
|
|
62
|
-
self._handle_exception(type(e), e, e.__traceback__)
|
|
63
|
-
return True
|
|
64
|
-
|
|
65
56
|
def _handle_exception(self, ex_type, ex_value, traceback_obj):
|
|
66
57
|
LOGGER.error('Application Exception: %s, %s', ex_type, ex_value)
|
|
67
58
|
if self._handling_exception:
|
{pyqttoolkit-0.8.0.dev0 → pyqttoolkit-0.8.0.post1}/pyqttoolkit/application/garbage_collector.py
RENAMED
|
@@ -17,9 +17,7 @@
|
|
|
17
17
|
import gc
|
|
18
18
|
import logging
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
from PyQt5.Qt import QObject, QTimer
|
|
22
|
-
#pyline: enable=no-name-in-module
|
|
20
|
+
from PyQt5.QtCore import QObject, QTimer
|
|
23
21
|
|
|
24
22
|
from pyqttoolkit.logs import TRACE
|
|
25
23
|
|
|
@@ -34,27 +32,29 @@ class GarbageCollector(QObject):
|
|
|
34
32
|
thread, as otherwise Qt can crash.
|
|
35
33
|
'''
|
|
36
34
|
|
|
37
|
-
def __init__(self, parent, interval=
|
|
38
|
-
|
|
35
|
+
def __init__(self, parent, interval=60000):
|
|
36
|
+
super().__init__(parent)
|
|
39
37
|
self._interval = interval
|
|
40
|
-
|
|
41
|
-
self._timer = QTimer(self)
|
|
42
|
-
self._timer.timeout.connect(self.check)
|
|
43
|
-
|
|
44
38
|
self._threshold = gc.get_threshold()
|
|
45
39
|
gc.disable()
|
|
46
|
-
self._timer.start(self._interval)
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
if self._interval:
|
|
42
|
+
self._timer = QTimer(self)
|
|
43
|
+
self._timer.timeout.connect(self.check)
|
|
44
|
+
self._timer.start(self._interval)
|
|
45
|
+
else:
|
|
46
|
+
self._timer = None
|
|
47
|
+
|
|
48
|
+
def check(self, full=False):
|
|
49
49
|
l0, l1, l2 = gc.get_count()
|
|
50
50
|
LOGGER.log(TRACE, 'gc_check called: l0=%d, l1=%d, l2=%d', l0, l1, l2)
|
|
51
|
-
if l0 > self._threshold[0]:
|
|
51
|
+
if full or l0 > self._threshold[0]:
|
|
52
52
|
num = gc.collect(0)
|
|
53
53
|
LOGGER.log(TRACE, 'Collecting gen 0, found: %d unreachable', num)
|
|
54
|
-
if l1 > self._threshold[1]:
|
|
54
|
+
if full or l1 > self._threshold[1]:
|
|
55
55
|
num = gc.collect(1)
|
|
56
56
|
LOGGER.log(TRACE, 'Collecting gen 1, found: %d unreachable', num)
|
|
57
|
-
if l2 > self._threshold[2]:
|
|
57
|
+
if full or l2 > self._threshold[2]:
|
|
58
58
|
num = gc.collect(2)
|
|
59
59
|
LOGGER.log(TRACE, 'Collecting gen 2, found: %d unreachable', num)
|
|
60
60
|
|
|
@@ -15,11 +15,18 @@
|
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
import os
|
|
18
|
+
import json
|
|
18
19
|
from .base import BaseApplicationConfiguration
|
|
19
20
|
|
|
20
21
|
class EnvironmentApplicationConfiguration(BaseApplicationConfiguration):
|
|
21
22
|
def get_value(self, key):
|
|
22
|
-
|
|
23
|
+
value = os.getenv(self._format_key(key))
|
|
24
|
+
if value is None:
|
|
25
|
+
return value
|
|
26
|
+
try:
|
|
27
|
+
return json.loads(value)
|
|
28
|
+
except json.decoder.JSONDecodeError:
|
|
29
|
+
return value
|
|
23
30
|
|
|
24
31
|
def set_value(self, key, value):
|
|
25
32
|
os.environ[self._format_key(key)] = str(value)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
17
|
+
from PyQt5.QtCore import pyqtSignal, QObject
|
|
18
18
|
|
|
19
19
|
class WithValueChangedConfiguration(QObject):
|
|
20
20
|
def __init__(self, inner):
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
17
|
+
from PyQt5.QtCore import pyqtSignal, QObject
|
|
18
18
|
|
|
19
19
|
class WithValueChangedConfiguration(QObject):
|
|
20
|
-
def __init__(self, inner):
|
|
21
|
-
super().__init__()
|
|
20
|
+
def __init__(self, parent, inner):
|
|
21
|
+
super().__init__(parent)
|
|
22
22
|
self._inner = inner
|
|
23
23
|
|
|
24
24
|
onValueChanged = pyqtSignal(str, object)
|
|
@@ -14,16 +14,13 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
+
import pandas as pd
|
|
18
|
+
|
|
17
19
|
def calculate_interval(values, sort=True):
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
if len(values) < 2:
|
|
21
|
+
return None
|
|
22
|
+
values_series = pd.Series(values)
|
|
20
23
|
if sort:
|
|
21
|
-
|
|
22
|
-
for
|
|
23
|
-
|
|
24
|
-
next_interval = value - last_value
|
|
25
|
-
if next_interval == interval:
|
|
26
|
-
return interval
|
|
27
|
-
interval = next_interval
|
|
28
|
-
last_value = value
|
|
29
|
-
return interval
|
|
24
|
+
values_series = values_series.sort_values()
|
|
25
|
+
# We want to ensure that the calculated interval is accurate for 90% of values to avoid mistakenly losing values
|
|
26
|
+
return (values_series - values_series.shift(1)).quantile(0.1)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# pyqttoolkit
|
|
2
|
+
# Copyright (C) 2018-2019, Simmovation Ltd.
|
|
3
|
+
#
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the Free Software Foundation,
|
|
16
|
+
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
+
from enum import Enum, IntEnum
|
|
18
|
+
|
|
19
|
+
class MessageType(Enum):
|
|
20
|
+
validation_error = 0
|
|
21
|
+
confirmation = 1
|
|
22
|
+
application_exception = 2
|
|
23
|
+
|
|
24
|
+
class MessageResponse(IntEnum):
|
|
25
|
+
ok = 1
|
|
26
|
+
cancel = 2
|
|
27
|
+
save = 4
|
|
28
|
+
discard = 8
|
|
29
|
+
ignore = 16
|
|
@@ -19,9 +19,7 @@ from .datetime import round_timedelta
|
|
|
19
19
|
|
|
20
20
|
import pandas as pd
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
from PyQt5.Qt import QDateTime, QDate, QTime
|
|
24
|
-
#pylint: enable=no-name-in-module
|
|
22
|
+
from PyQt5.QtCore import QDateTime, QDate, QTime
|
|
25
23
|
|
|
26
24
|
def q_datetime_to_datetime(q_datetime: QDateTime):
|
|
27
25
|
if q_datetime is None or not q_datetime.isValid():
|
|
@@ -39,7 +37,7 @@ def pd_timestamp_to_q_datetime(pd_timestamp: datetime):
|
|
|
39
37
|
return QDateTime()
|
|
40
38
|
return QDateTime(
|
|
41
39
|
QDate(pd_timestamp.year, pd_timestamp.month, pd_timestamp.day),
|
|
42
|
-
QTime(pd_timestamp.hour, pd_timestamp.minute, pd_timestamp.second, pd_timestamp.microsecond
|
|
40
|
+
QTime(pd_timestamp.hour, pd_timestamp.minute, pd_timestamp.second, pd_timestamp.microsecond // 1000)
|
|
43
41
|
)
|
|
44
42
|
|
|
45
43
|
def step_qdatetime(control, fraction, interval, range_start, range_end):
|
|
@@ -37,12 +37,14 @@ class DependencyContainer:
|
|
|
37
37
|
def resolve(self, type_, extras=None, none_for_missing=False):
|
|
38
38
|
args = self._get_args(type_)
|
|
39
39
|
all_dependencies = {**self._instances, **(extras or {})}
|
|
40
|
-
for
|
|
41
|
-
if
|
|
42
|
-
if
|
|
43
|
-
all_dependencies[
|
|
40
|
+
for arg_name, arg in args.items():
|
|
41
|
+
if arg_name not in all_dependencies:
|
|
42
|
+
if arg.default != inspect.Parameter.empty:
|
|
43
|
+
all_dependencies[arg_name] = arg.default
|
|
44
|
+
elif none_for_missing:
|
|
45
|
+
all_dependencies[arg_name] = None
|
|
44
46
|
else:
|
|
45
|
-
raise MissingDependency(type_,
|
|
47
|
+
raise MissingDependency(type_, arg_name)
|
|
46
48
|
return type_(**{a: all_dependencies[a] for a in args})
|
|
47
49
|
|
|
48
50
|
def resolve_for(self, type_for, base_type, extras=None):
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# pyqttoolkit
|
|
2
|
+
# Copyright (C) 2018-2019, Simmovation Ltd.
|
|
3
|
+
#
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the Free Software Foundation,
|
|
16
|
+
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
+
class TaskCancelled(Exception):
|
|
18
|
+
pass
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
+
from typing import Callable
|
|
18
|
+
from io import StringIO
|
|
17
19
|
import logging
|
|
18
20
|
from logging import handlers
|
|
19
21
|
from functools import wraps
|
|
@@ -109,3 +111,30 @@ def logf(level, log_args=True):
|
|
|
109
111
|
return result
|
|
110
112
|
return _
|
|
111
113
|
return logf_decorator
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class LogStream:
|
|
117
|
+
def __init__(self, notify_update: Callable = None):
|
|
118
|
+
self._buffer = StringIO()
|
|
119
|
+
self._notify_update = notify_update
|
|
120
|
+
|
|
121
|
+
def __iadd__(self, other):
|
|
122
|
+
self.write(other)
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
def write(self, message):
|
|
126
|
+
self._buffer.write(message)
|
|
127
|
+
if self._notify_update:
|
|
128
|
+
self._notify_update()
|
|
129
|
+
|
|
130
|
+
def flush(self):
|
|
131
|
+
self._buffer.flush()
|
|
132
|
+
|
|
133
|
+
def getvalue(self):
|
|
134
|
+
return self._buffer.getvalue()
|
|
135
|
+
|
|
136
|
+
def clear(self):
|
|
137
|
+
self._buffer.close()
|
|
138
|
+
self._buffer = StringIO()
|
|
139
|
+
if self._notify_update:
|
|
140
|
+
self._notify_update()
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
18
|
-
#pylint: enable=no-name-in-module
|
|
17
|
+
from PyQt5.QtCore import QObject, pyqtSignal
|
|
19
18
|
|
|
20
19
|
from pyqttoolkit.properties import AutoProperty
|
|
20
|
+
from pyqttoolkit.logs import LogStream
|
|
21
21
|
|
|
22
22
|
class CodeTextModel(QObject):
|
|
23
23
|
def __init__(self, parent, validator):
|
|
@@ -25,16 +25,19 @@ class CodeTextModel(QObject):
|
|
|
25
25
|
self.textChanged.connect(self._validate)
|
|
26
26
|
self._validator = validator
|
|
27
27
|
self.text = ''
|
|
28
|
-
self.output =
|
|
28
|
+
self.output = LogStream(self._handle_output_buffer_changed)
|
|
29
29
|
|
|
30
30
|
textChanged = pyqtSignal(str)
|
|
31
|
-
outputChanged = pyqtSignal(
|
|
31
|
+
outputChanged = pyqtSignal(LogStream)
|
|
32
32
|
validationMessageChanged = pyqtSignal(str)
|
|
33
33
|
|
|
34
34
|
text = AutoProperty(str)
|
|
35
|
-
output = AutoProperty(
|
|
35
|
+
output = AutoProperty(LogStream)
|
|
36
36
|
validationMessage = AutoProperty(str)
|
|
37
37
|
|
|
38
38
|
def _validate(self, value):
|
|
39
39
|
validation_model = self._validator(value)
|
|
40
40
|
self.validationMessage = validation_model.error if validation_model else ''
|
|
41
|
+
|
|
42
|
+
def _handle_output_buffer_changed(self):
|
|
43
|
+
self.outputChanged.emit(self.output)
|
|
@@ -14,9 +14,7 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.QtCore import pyqtSignal
|
|
18
|
-
from PyQt5.Qt import QAbstractTableModel, Qt, QVariant, QModelIndex, QItemSelectionModel
|
|
19
|
-
#pylint: enable=no-name-in-module
|
|
17
|
+
from PyQt5.QtCore import pyqtSignal, QAbstractTableModel, Qt, QVariant, QModelIndex, QItemSelectionModel
|
|
20
18
|
|
|
21
19
|
class DataFrameTableModel(QAbstractTableModel):
|
|
22
20
|
def __init__(self, parent, data, display_column=None, editable=False, row_headers=False):
|
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
from enum import Enum
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
from PyQt5.Qt import Qt, QAbstractItemModel, pyqtSignal, QModelIndex, QVariant
|
|
21
|
-
#pylint: enable=no-name-in-module
|
|
19
|
+
from PyQt5.QtCore import Qt, QAbstractItemModel, pyqtSignal, QModelIndex, QVariant
|
|
22
20
|
|
|
23
21
|
class DictPropertyTreeModel(QAbstractItemModel):
|
|
24
22
|
def __init__(self, parent, data):
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
18
|
-
#pylint: enable=no-name-in-module
|
|
17
|
+
from PyQt5.QtCore import Qt, QAbstractTableModel, pyqtSignal, QModelIndex
|
|
19
18
|
|
|
20
19
|
from pyqttoolkit.models.roles import DataRole
|
|
21
20
|
|
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
from json import loads, dumps, JSONDecodeError
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
from PyQt5.Qt import QObject, pyqtSignal
|
|
21
|
-
#pylint: enable=no-name-in-module
|
|
19
|
+
from PyQt5.QtCore import QObject, pyqtSignal
|
|
22
20
|
|
|
23
21
|
from pyqttoolkit.properties import AutoProperty
|
|
24
22
|
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
18
|
-
#pylint: enable=no-name-in-module
|
|
17
|
+
from PyQt5.QtCore import Qt, QAbstractListModel, QStringListModel
|
|
19
18
|
|
|
20
19
|
from pyqttoolkit.models.roles import DataRole
|
|
21
20
|
|
|
@@ -1,32 +1,36 @@
|
|
|
1
|
-
# pyqttoolkit
|
|
2
|
-
# Copyright (C) 2018-2019, Simmovation Ltd.
|
|
3
|
-
#
|
|
4
|
-
# This program is free software; you can redistribute it and/or modify
|
|
5
|
-
# it under the terms of the GNU General Public License as published by
|
|
6
|
-
# the Free Software Foundation; either version 3 of the License, or
|
|
7
|
-
# (at your option) any later version.
|
|
8
|
-
#
|
|
9
|
-
# This program is distributed in the hope that it will be useful,
|
|
10
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
-
# GNU General Public License for more details.
|
|
13
|
-
#
|
|
14
|
-
# You should have received a copy of the GNU General Public License
|
|
15
|
-
# along with this program; if not, write to the Free Software Foundation,
|
|
16
|
-
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
self.
|
|
24
|
-
self.
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def left(self):
|
|
28
|
-
return self._left
|
|
29
|
-
|
|
30
|
-
@property
|
|
31
|
-
def right(self):
|
|
32
|
-
return self._right
|
|
1
|
+
# pyqttoolkit
|
|
2
|
+
# Copyright (C) 2018-2019, Simmovation Ltd.
|
|
3
|
+
#
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the Free Software Foundation,
|
|
16
|
+
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
+
from PyQt5.QtCore import QObject
|
|
18
|
+
|
|
19
|
+
class SpanModel(QObject):
|
|
20
|
+
def __init__(self, parent, left, right, radians=False):
|
|
21
|
+
QObject.__init__(self, parent)
|
|
22
|
+
self._left = left
|
|
23
|
+
self._right = right
|
|
24
|
+
self._radians = radians
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def left(self):
|
|
28
|
+
return self._left
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def right(self):
|
|
32
|
+
return self._right
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def radians(self):
|
|
36
|
+
return self._radians
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
18
|
-
#pylint: enable=no-name-in-module
|
|
17
|
+
from PyQt5.QtCore import QObject
|
|
19
18
|
|
|
20
19
|
class RejectableEvent(QObject):
|
|
21
20
|
def __init__(self):
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
18
|
-
#pylint: enable=no-name-in-module
|
|
17
|
+
from PyQt5.QtCore import QObject, pyqtSignal
|
|
19
18
|
|
|
20
19
|
from pyqttoolkit.properties import AutoProperty
|
|
21
20
|
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program; if not, write to the Free Software Foundation,
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
-
from PyQt5.
|
|
18
|
-
#pylint: enable=no-name-in-module
|
|
17
|
+
from PyQt5.QtCore import QObject, pyqtSignal
|
|
19
18
|
|
|
20
19
|
from .events import ModuleOpeningEvent
|
|
21
20
|
|
|
@@ -24,6 +23,8 @@ class ModuleBase(QObject):
|
|
|
24
23
|
QObject.__init__(self)
|
|
25
24
|
self._id = id_
|
|
26
25
|
self._launcher_config = launcher_config
|
|
26
|
+
if self._launcher_config:
|
|
27
|
+
self._launcher_config.setParent(self)
|
|
27
28
|
|
|
28
29
|
opening = pyqtSignal(ModuleOpeningEvent)
|
|
29
30
|
opened = pyqtSignal()
|
|
@@ -80,21 +80,24 @@ class ScriptRunner:
|
|
|
80
80
|
self._context = None
|
|
81
81
|
|
|
82
82
|
def _globals(self, context):
|
|
83
|
-
return {'__builtins__': {**__builtins__, '__import__': self._import, 'exit': self._exit, **{g: self._not_implemented for g in self._disallowed_globals}}}
|
|
83
|
+
return {'__builtins__': {**__builtins__, '__import__': self._import(builtins.__import__), 'exit': self._exit, **{g: self._not_implemented for g in self._disallowed_globals}}}
|
|
84
84
|
|
|
85
85
|
def compile(self, script):
|
|
86
86
|
return compile(script, 'code', 'exec')
|
|
87
87
|
|
|
88
|
-
def _import(self,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
88
|
+
def _import(self, import_function):
|
|
89
|
+
def _(module_name, *args, **kwargs):
|
|
90
|
+
if any(re.match(m, module_name) for m in self._disallowed_modules):
|
|
91
|
+
raise ImportError('Module not found')
|
|
92
|
+
try:
|
|
93
|
+
with add_paths(self._additional_paths):
|
|
94
|
+
module = import_function(module_name, *args, **kwargs)
|
|
95
|
+
if module_name in 'importlib':
|
|
96
|
+
module.import_module = self._import(importlib.import_module)
|
|
97
|
+
return module
|
|
98
|
+
except KeyError:
|
|
99
|
+
raise ImportError('Module not found')
|
|
100
|
+
return _
|
|
98
101
|
|
|
99
102
|
def _additional_paths(self):
|
|
100
103
|
return self._additional_paths
|
|
@@ -16,17 +16,32 @@
|
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
from os import path
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
from PyQt5.
|
|
21
|
-
|
|
19
|
+
from PyQt5.QtCore import QStandardPaths, QTimer
|
|
20
|
+
from PyQt5.QtWidgets import QFileDialog
|
|
21
|
+
|
|
22
|
+
from .event_registry import EventTypes
|
|
22
23
|
|
|
23
24
|
class FileDialogService:
|
|
24
|
-
def __init__(self, project_manager, application_configuration):
|
|
25
|
+
def __init__(self, project_manager, application_configuration, event_registry):
|
|
25
26
|
self._project_manager = project_manager
|
|
26
27
|
self._application_configuration = application_configuration
|
|
27
|
-
|
|
28
|
+
self._event_registry = event_registry
|
|
29
|
+
|
|
30
|
+
def _get_dialog(self, parent, filter_, default_directory=None):
|
|
31
|
+
dialog = QFileDialog(
|
|
32
|
+
parent,
|
|
33
|
+
directory=default_directory or self._get_default_directory(),
|
|
34
|
+
filter=filter_
|
|
35
|
+
)
|
|
36
|
+
def _notify_save_dialog_finished(result):
|
|
37
|
+
self._event_registry.event(EventTypes.save_dialog_finished).emit(result)
|
|
38
|
+
dialog.finished.connect(_notify_save_dialog_finished)
|
|
39
|
+
return dialog
|
|
40
|
+
|
|
28
41
|
def get_save_filename(self, parent, filter_, default_name=None):
|
|
29
|
-
|
|
42
|
+
default_directory = path.dirname(default_name) if default_name else None
|
|
43
|
+
dialog = self._get_dialog(parent, filter_, default_directory)
|
|
44
|
+
|
|
30
45
|
if default_name:
|
|
31
46
|
dialog.selectFile(default_name)
|
|
32
47
|
dialog.setModal(True)
|
|
@@ -36,7 +51,7 @@ class FileDialogService:
|
|
|
36
51
|
return dialog.selectedFiles()[0]
|
|
37
52
|
|
|
38
53
|
def get_open_filename(self, parent, filter_, file_mode=None):
|
|
39
|
-
dialog =
|
|
54
|
+
dialog = self._get_dialog(parent, filter_)
|
|
40
55
|
if file_mode:
|
|
41
56
|
dialog.setFileMode(file_mode)
|
|
42
57
|
if dialog.exec_():
|
|
@@ -50,5 +65,7 @@ class FileDialogService:
|
|
|
50
65
|
if default_location and path.isdir(default_location):
|
|
51
66
|
return default_location
|
|
52
67
|
return QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation)
|
|
68
|
+
elif self._project_manager.filename and not path.isdir(path.dirname(self._project_manager.filename)):
|
|
69
|
+
return QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation)
|
|
53
70
|
else:
|
|
54
71
|
return path.dirname(self._project_manager.filename)
|
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
from enum import Enum
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
from PyQt5.Qt import Qt
|
|
21
|
-
#pylint: enable=no-name-in-module
|
|
19
|
+
from PyQt5.QtCore import Qt
|
|
22
20
|
|
|
23
21
|
class HotkeyEvents(Enum):
|
|
24
22
|
next_instance_y = 0
|