oqtopus 0.2.0__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oqtopus/core/module.py +176 -32
- oqtopus/core/module_operation_task.py +234 -0
- oqtopus/core/module_package.py +27 -10
- oqtopus/core/modules_config.py +2 -0
- oqtopus/core/package_prepare_task.py +240 -25
- oqtopus/gui/database_connection_widget.py +12 -5
- oqtopus/gui/database_create_dialog.py +3 -3
- oqtopus/gui/database_duplicate_dialog.py +4 -4
- oqtopus/gui/logs_widget.py +94 -7
- oqtopus/gui/main_dialog.py +118 -31
- oqtopus/gui/module_selection_widget.py +110 -22
- oqtopus/gui/module_widget.py +647 -61
- oqtopus/gui/parameters_groupbox.py +25 -13
- oqtopus/gui/plugin_widget.py +13 -0
- oqtopus/gui/project_widget.py +5 -0
- oqtopus/gui/settings_dialog.py +2 -0
- oqtopus/oqtopus_plugin.py +10 -1
- oqtopus/ui/module_selection_widget.ui +96 -96
- oqtopus/ui/module_widget.ui +72 -58
- oqtopus/ui/settings_dialog.ui +18 -11
- oqtopus/utils/plugin_utils.py +113 -19
- oqtopus/utils/qt_utils.py +54 -0
- {oqtopus-0.2.0.dist-info → oqtopus-1.0.0.dist-info}/METADATA +1 -1
- oqtopus-1.0.0.dist-info/RECORD +47 -0
- {oqtopus-0.2.0.dist-info → oqtopus-1.0.0.dist-info}/WHEEL +1 -1
- tests/test_imports.py +59 -0
- oqtopus-0.2.0.dist-info/RECORD +0 -45
- {oqtopus-0.2.0.dist-info → oqtopus-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {oqtopus-0.2.0.dist-info → oqtopus-1.0.0.dist-info}/top_level.txt +0 -0
oqtopus/gui/main_dialog.py
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
import os
|
|
27
|
+
import shutil
|
|
27
28
|
import sys
|
|
28
29
|
|
|
29
30
|
from qgis.PyQt.QtCore import QUrl
|
|
@@ -31,8 +32,10 @@ from qgis.PyQt.QtGui import QAction, QDesktopServices
|
|
|
31
32
|
from qgis.PyQt.QtWidgets import (
|
|
32
33
|
QDialog,
|
|
33
34
|
QMenuBar,
|
|
35
|
+
QMessageBox,
|
|
34
36
|
)
|
|
35
37
|
|
|
38
|
+
from ..core.module_package import ModulePackage
|
|
36
39
|
from ..utils.plugin_utils import PluginUtils, logger
|
|
37
40
|
from .about_dialog import AboutDialog
|
|
38
41
|
from .settings_dialog import SettingsDialog
|
|
@@ -93,10 +96,18 @@ class MainDialog(QDialog, DIALOG_UI):
|
|
|
93
96
|
self.menubar.setNativeMenuBar(False)
|
|
94
97
|
self.layout().setMenuBar(self.menubar)
|
|
95
98
|
|
|
96
|
-
# Settings
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
# Settings menu
|
|
100
|
+
settings_menu = self.menubar.addMenu(self.tr("Settings"))
|
|
101
|
+
|
|
102
|
+
# Settings dialog action
|
|
103
|
+
settings_dialog_action = QAction(self.tr("Preferences..."), self)
|
|
104
|
+
settings_dialog_action.triggered.connect(self.__open_settings_dialog)
|
|
105
|
+
settings_menu.addAction(settings_dialog_action)
|
|
106
|
+
|
|
107
|
+
# Cache cleanup action
|
|
108
|
+
cleanup_cache_action = QAction(self.tr("Cleanup Cache"), self)
|
|
109
|
+
cleanup_cache_action.triggered.connect(self.__cleanup_cache)
|
|
110
|
+
settings_menu.addAction(cleanup_cache_action)
|
|
100
111
|
|
|
101
112
|
# Help menu
|
|
102
113
|
help_menu = self.menubar.addMenu(self.tr("Help"))
|
|
@@ -127,13 +138,34 @@ class MainDialog(QDialog, DIALOG_UI):
|
|
|
127
138
|
)
|
|
128
139
|
self.__databaseConnectionWidget_connectionChanged()
|
|
129
140
|
|
|
130
|
-
self.
|
|
131
|
-
self.plugin_tab.setEnabled(False)
|
|
132
|
-
self.project_tab.setEnabled(False)
|
|
141
|
+
self.__disable_module_tabs()
|
|
133
142
|
|
|
134
143
|
logger.info("Ready.")
|
|
135
144
|
|
|
145
|
+
def closeEvent(self, event):
|
|
146
|
+
"""Handle window close event (X button) to properly cleanup threads."""
|
|
147
|
+
if self.__moduleWidget.isOperationRunning():
|
|
148
|
+
QMessageBox.warning(
|
|
149
|
+
self,
|
|
150
|
+
self.tr("Operation in progress"),
|
|
151
|
+
self.tr("Cannot close the dialog while an operation is running."),
|
|
152
|
+
)
|
|
153
|
+
event.ignore()
|
|
154
|
+
return
|
|
155
|
+
self.__moduleWidget.close()
|
|
156
|
+
self.__moduleSelectionWidget.close()
|
|
157
|
+
self.__logsWidget.close()
|
|
158
|
+
event.accept()
|
|
159
|
+
|
|
136
160
|
def __closeDialog(self):
|
|
161
|
+
if self.__moduleWidget.isOperationRunning():
|
|
162
|
+
QMessageBox.warning(
|
|
163
|
+
self,
|
|
164
|
+
self.tr("Operation in progress"),
|
|
165
|
+
self.tr("Cannot close the dialog while an operation is running."),
|
|
166
|
+
)
|
|
167
|
+
return
|
|
168
|
+
self.__moduleWidget.close()
|
|
137
169
|
self.__moduleSelectionWidget.close()
|
|
138
170
|
self.__logsWidget.close()
|
|
139
171
|
self.accept()
|
|
@@ -147,44 +179,99 @@ class MainDialog(QDialog, DIALOG_UI):
|
|
|
147
179
|
dlg = SettingsDialog(self)
|
|
148
180
|
dlg.exec()
|
|
149
181
|
|
|
182
|
+
def __cleanup_cache(self):
|
|
183
|
+
"""Delete all cached data (downloaded packages and GitHub API cache)."""
|
|
184
|
+
cache_paths = PluginUtils.get_all_cache_paths()
|
|
185
|
+
|
|
186
|
+
if not cache_paths:
|
|
187
|
+
QMessageBox.information(
|
|
188
|
+
self,
|
|
189
|
+
self.tr("Cache Cleanup"),
|
|
190
|
+
self.tr("No cache directories found. Nothing to clean up."),
|
|
191
|
+
)
|
|
192
|
+
return
|
|
193
|
+
|
|
194
|
+
# Format paths for display
|
|
195
|
+
paths_display = "\n".join(f" • {p}" for p in cache_paths)
|
|
196
|
+
|
|
197
|
+
# Ask for confirmation
|
|
198
|
+
reply = QMessageBox.question(
|
|
199
|
+
self,
|
|
200
|
+
self.tr("Cleanup Cache"),
|
|
201
|
+
self.tr(
|
|
202
|
+
f"This will delete all cached data from:\n{paths_display}\n\n"
|
|
203
|
+
"Downloaded module packages and API cache will need to be re-fetched.\n\n"
|
|
204
|
+
"Are you sure you want to continue?"
|
|
205
|
+
),
|
|
206
|
+
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
|
207
|
+
QMessageBox.StandardButton.No,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
if reply != QMessageBox.StandardButton.Yes:
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
errors = []
|
|
214
|
+
for cache_dir in cache_paths:
|
|
215
|
+
try:
|
|
216
|
+
shutil.rmtree(cache_dir)
|
|
217
|
+
except Exception as e:
|
|
218
|
+
errors.append(f"{cache_dir}: {e}")
|
|
219
|
+
|
|
220
|
+
if errors:
|
|
221
|
+
QMessageBox.warning(
|
|
222
|
+
self,
|
|
223
|
+
self.tr("Cache Cleanup Warning"),
|
|
224
|
+
self.tr("Some cache directories could not be deleted:\n") + "\n".join(errors),
|
|
225
|
+
)
|
|
226
|
+
else:
|
|
227
|
+
QMessageBox.information(
|
|
228
|
+
self,
|
|
229
|
+
self.tr("Cache Cleanup"),
|
|
230
|
+
self.tr("Cache has been successfully cleaned up."),
|
|
231
|
+
)
|
|
232
|
+
|
|
150
233
|
def __show_about_dialog(self):
|
|
151
234
|
dialog = self.__about_dialog_cls(self)
|
|
152
235
|
dialog.exec()
|
|
153
236
|
|
|
154
|
-
def
|
|
155
|
-
|
|
237
|
+
def __disable_module_tabs(self):
|
|
238
|
+
"""Disable all module-related tabs."""
|
|
156
239
|
self.module_tab.setEnabled(False)
|
|
157
240
|
self.plugin_tab.setEnabled(False)
|
|
158
241
|
self.project_tab.setEnabled(False)
|
|
159
242
|
|
|
160
|
-
def
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return
|
|
243
|
+
def __enable_module_tabs(self, module_package: ModulePackage):
|
|
244
|
+
"""Enable module tabs based on available assets."""
|
|
245
|
+
self.module_tab.setEnabled(True)
|
|
246
|
+
self.plugin_tab.setEnabled(module_package.asset_plugin is not None)
|
|
247
|
+
self.project_tab.setEnabled(module_package.asset_project is not None)
|
|
166
248
|
|
|
167
|
-
|
|
168
|
-
|
|
249
|
+
def __clear_module_packages(self):
|
|
250
|
+
"""Clear module package state from all widgets."""
|
|
251
|
+
self.__moduleWidget.clearModulePackage()
|
|
252
|
+
self.__projectWidget.clearModulePackage()
|
|
253
|
+
self.__pluginWidget.clearModulePackage()
|
|
169
254
|
|
|
170
|
-
|
|
255
|
+
def __set_module_packages(self, module_package: ModulePackage):
|
|
256
|
+
"""Set module package in all widgets."""
|
|
257
|
+
self.__moduleWidget.setModulePackage(module_package)
|
|
258
|
+
self.__projectWidget.setModulePackage(module_package)
|
|
259
|
+
self.__pluginWidget.setModulePackage(module_package)
|
|
171
260
|
|
|
172
|
-
|
|
173
|
-
|
|
261
|
+
def __moduleSelection_loadingStarted(self):
|
|
262
|
+
self.db_groupBox.setEnabled(False)
|
|
263
|
+
self.__disable_module_tabs()
|
|
264
|
+
self.__clear_module_packages()
|
|
174
265
|
|
|
175
|
-
|
|
176
|
-
|
|
266
|
+
def __moduleSelection_loadingFinished(self):
|
|
267
|
+
self.db_groupBox.setEnabled(True)
|
|
177
268
|
|
|
178
|
-
self.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
self.__projectWidget.setModulePackage(
|
|
182
|
-
self.__moduleSelectionWidget.getSelectedModulePackage()
|
|
183
|
-
)
|
|
269
|
+
module_package = self.__moduleSelectionWidget.getSelectedModulePackage()
|
|
270
|
+
if module_package is None or self.__moduleSelectionWidget.lastError() is not None:
|
|
271
|
+
return
|
|
184
272
|
|
|
185
|
-
self.
|
|
186
|
-
|
|
187
|
-
)
|
|
273
|
+
self.__enable_module_tabs(module_package)
|
|
274
|
+
self.__set_module_packages(module_package)
|
|
188
275
|
|
|
189
276
|
def __databaseConnectionWidget_connectionChanged(self):
|
|
190
277
|
self.__moduleWidget.setDatabaseConnection(self.__databaseConnectionWidget.getConnection())
|
|
@@ -15,7 +15,7 @@ DIALOG_UI = PluginUtils.get_ui_class("module_selection_widget.ui")
|
|
|
15
15
|
|
|
16
16
|
class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
17
17
|
|
|
18
|
-
module_package_SPECIAL_LOAD_DEVELOPMENT = "Load development
|
|
18
|
+
module_package_SPECIAL_LOAD_DEVELOPMENT = "Load pre-releases and development branches"
|
|
19
19
|
|
|
20
20
|
signal_loadingStarted = pyqtSignal()
|
|
21
21
|
signal_loadingFinished = pyqtSignal()
|
|
@@ -49,8 +49,10 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
49
49
|
for config_module in self.__modules_config.modules:
|
|
50
50
|
module = Module(
|
|
51
51
|
name=config_module.name,
|
|
52
|
+
id=config_module.id,
|
|
52
53
|
organisation=config_module.organisation,
|
|
53
54
|
repository=config_module.repository,
|
|
55
|
+
exclude_releases=config_module.exclude_releases,
|
|
54
56
|
parent=self,
|
|
55
57
|
)
|
|
56
58
|
self.module_module_comboBox.addItem(module.name, module)
|
|
@@ -62,8 +64,8 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
62
64
|
self.module_latestVersion_label.setText("")
|
|
63
65
|
QtUtils.setForegroundColor(self.module_latestVersion_label, PluginUtils.COLOR_GREEN)
|
|
64
66
|
|
|
65
|
-
self.
|
|
66
|
-
self.
|
|
67
|
+
self.__reset_package_selection()
|
|
68
|
+
self.module_seeChangeLog_pushButton.setEnabled(False)
|
|
67
69
|
|
|
68
70
|
self.module_zipPackage_groupBox.setVisible(False)
|
|
69
71
|
|
|
@@ -80,6 +82,14 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
80
82
|
|
|
81
83
|
def close(self):
|
|
82
84
|
if self.__packagePrepareTask.isRunning():
|
|
85
|
+
# Disconnect signals first to prevent crashes when emitting to destroyed widgets
|
|
86
|
+
try:
|
|
87
|
+
self.__packagePrepareTask.signalPackagingProgress.disconnect()
|
|
88
|
+
self.__packagePrepareTask.finished.disconnect()
|
|
89
|
+
except TypeError:
|
|
90
|
+
# Already disconnected
|
|
91
|
+
pass
|
|
92
|
+
|
|
83
93
|
self.__packagePrepareTask.cancel()
|
|
84
94
|
self.__packagePrepareTask.wait()
|
|
85
95
|
|
|
@@ -93,22 +103,51 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
93
103
|
"""
|
|
94
104
|
return self.__packagePrepareTask.lastError
|
|
95
105
|
|
|
106
|
+
def __reset_package_selection(self):
|
|
107
|
+
"""Reset package selection combo box to initial state."""
|
|
108
|
+
self.module_package_comboBox.clear()
|
|
109
|
+
self.module_package_comboBox.addItem(self.tr("Please select a version"), None)
|
|
110
|
+
self.module_package_comboBox.setEnabled(False)
|
|
111
|
+
# Disable this placeholder item so it can't be selected once a version is chosen
|
|
112
|
+
model = self.module_package_comboBox.model()
|
|
113
|
+
item = model.item(0)
|
|
114
|
+
if item:
|
|
115
|
+
item.setEnabled(False)
|
|
116
|
+
|
|
117
|
+
def __enable_package_selection(self):
|
|
118
|
+
"""Enable package selection combo box."""
|
|
119
|
+
self.module_package_comboBox.setEnabled(True)
|
|
120
|
+
|
|
96
121
|
def __moduleChanged(self, index):
|
|
122
|
+
logger.debug(f"__moduleChanged START, index={index}")
|
|
97
123
|
if self.module_module_comboBox.currentData() == self.__current_module:
|
|
124
|
+
logger.debug("Same module selected, returning")
|
|
98
125
|
return
|
|
99
126
|
|
|
127
|
+
logger.debug(f"Module changed to: {self.module_module_comboBox.currentText()}")
|
|
100
128
|
self.__current_module = self.module_module_comboBox.currentData()
|
|
101
129
|
|
|
130
|
+
logger.debug("Resetting labels and UI")
|
|
102
131
|
self.module_latestVersion_label.setText("")
|
|
103
|
-
self.
|
|
104
|
-
self.
|
|
132
|
+
self.__reset_package_selection()
|
|
133
|
+
self.module_seeChangeLog_pushButton.setEnabled(False)
|
|
105
134
|
|
|
106
135
|
if self.__current_module is None:
|
|
136
|
+
logger.debug("No module selected")
|
|
107
137
|
return
|
|
108
138
|
|
|
139
|
+
logger.debug(f"Module versions list length: {len(self.__current_module.versions)}")
|
|
109
140
|
if self.__current_module.versions == list():
|
|
141
|
+
logger.debug("Versions empty, starting load")
|
|
142
|
+
# Emit signal first to allow UI to update before showing wait cursor
|
|
143
|
+
self.signal_loadingStarted.emit()
|
|
110
144
|
QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
|
|
111
145
|
self.__current_module.start_load_versions()
|
|
146
|
+
else:
|
|
147
|
+
logger.debug("Versions already loaded, populating UI")
|
|
148
|
+
# Versions already loaded (from cache or previous selection) - populate UI
|
|
149
|
+
self.__loadVersionsFinished("")
|
|
150
|
+
logger.debug("__moduleChanged END")
|
|
112
151
|
|
|
113
152
|
def __moduleVersionChanged(self, index):
|
|
114
153
|
|
|
@@ -126,20 +165,35 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
126
165
|
|
|
127
166
|
self.__current_module_package = self.module_package_comboBox.currentData()
|
|
128
167
|
if self.__current_module_package is None:
|
|
168
|
+
self.module_seeChangeLog_pushButton.setEnabled(False)
|
|
169
|
+
# Clear module information when placeholder is selected
|
|
170
|
+
self.module_information_label.setText(self.tr("Please select a version"))
|
|
171
|
+
QtUtils.resetForegroundColor(self.module_information_label)
|
|
172
|
+
self.module_informationProject_label.setText("-")
|
|
173
|
+
self.module_informationPlugin_label.setText("-")
|
|
174
|
+
# Emit signal to clear module widgets
|
|
175
|
+
self.signal_loadingFinished.emit()
|
|
129
176
|
return
|
|
130
177
|
|
|
178
|
+
# Enable changelog button for valid selections
|
|
179
|
+
self.module_seeChangeLog_pushButton.setEnabled(True)
|
|
180
|
+
|
|
131
181
|
if self.__current_module_package.type == self.__current_module_package.Type.FROM_ZIP:
|
|
132
182
|
self.module_zipPackage_groupBox.setVisible(True)
|
|
133
183
|
return
|
|
134
184
|
else:
|
|
135
185
|
self.module_zipPackage_groupBox.setVisible(False)
|
|
136
186
|
|
|
137
|
-
loading_text = self.tr(
|
|
138
|
-
f"Loading packages for module '{self.module_module_comboBox.currentText()}' version '{self.__current_module_package.display_name()}'..."
|
|
139
|
-
)
|
|
187
|
+
loading_text = self.tr("Loading package...")
|
|
140
188
|
self.module_information_label.setText(loading_text)
|
|
189
|
+
self.module_information_label.setToolTip(
|
|
190
|
+
f"{self.module_module_comboBox.currentText()} - {self.__current_module_package.display_name()}"
|
|
191
|
+
)
|
|
141
192
|
QtUtils.resetForegroundColor(self.module_information_label)
|
|
142
|
-
logger.info(
|
|
193
|
+
logger.info(
|
|
194
|
+
f"Loading packages for module '{self.module_module_comboBox.currentText()}' "
|
|
195
|
+
f"version '{self.__current_module_package.display_name()}'..."
|
|
196
|
+
)
|
|
143
197
|
|
|
144
198
|
self.module_informationProject_label.setText("-")
|
|
145
199
|
self.module_informationPlugin_label.setText("-")
|
|
@@ -147,6 +201,8 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
147
201
|
self.__packagePrepareTask.startFromModulePackage(self.__current_module_package)
|
|
148
202
|
|
|
149
203
|
self.signal_loadingStarted.emit()
|
|
204
|
+
self.module_progressBar.setMaximum(100)
|
|
205
|
+
self.module_progressBar.setValue(0)
|
|
150
206
|
self.module_progressBar.setVisible(True)
|
|
151
207
|
|
|
152
208
|
def __loadDevelopmentVersions(self):
|
|
@@ -154,6 +210,8 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
154
210
|
return
|
|
155
211
|
|
|
156
212
|
if self.__current_module.development_versions == list():
|
|
213
|
+
# Emit signal first to allow UI to update before showing wait cursor
|
|
214
|
+
self.signal_loadingStarted.emit()
|
|
157
215
|
QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
|
|
158
216
|
self.__current_module.start_load_development_versions()
|
|
159
217
|
|
|
@@ -185,6 +243,8 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
185
243
|
self.__packagePrepareTask.startFromZip(self.__current_module_package, filename)
|
|
186
244
|
|
|
187
245
|
self.signal_loadingStarted.emit()
|
|
246
|
+
self.module_progressBar.setMaximum(100)
|
|
247
|
+
self.module_progressBar.setValue(0)
|
|
188
248
|
self.module_progressBar.setVisible(True)
|
|
189
249
|
|
|
190
250
|
def __packagePrepareTaskFinished(self):
|
|
@@ -211,29 +271,43 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
211
271
|
package_dir = self.module_package_comboBox.currentData().source_package_dir
|
|
212
272
|
logger.info(f"Package loaded into '{package_dir}'")
|
|
213
273
|
QtUtils.resetForegroundColor(self.module_information_label)
|
|
214
|
-
self.module_information_label
|
|
215
|
-
f"<a href='file://{package_dir}'>{package_dir}</a>",
|
|
216
|
-
)
|
|
274
|
+
QtUtils.setPathLinkWithEllipsis(self.module_information_label, package_dir)
|
|
217
275
|
|
|
218
276
|
asset_project = self.module_package_comboBox.currentData().asset_project
|
|
219
277
|
if asset_project:
|
|
220
|
-
|
|
221
|
-
|
|
278
|
+
QtUtils.setPathLinkWithEllipsis(
|
|
279
|
+
self.module_informationProject_label, asset_project.package_dir
|
|
222
280
|
)
|
|
223
281
|
else:
|
|
224
282
|
self.module_informationProject_label.setText("No asset available")
|
|
283
|
+
self.module_informationProject_label.setToolTip("")
|
|
225
284
|
|
|
226
285
|
asset_plugin = self.module_package_comboBox.currentData().asset_plugin
|
|
227
286
|
if asset_plugin:
|
|
228
|
-
|
|
229
|
-
|
|
287
|
+
QtUtils.setPathLinkWithEllipsis(
|
|
288
|
+
self.module_informationPlugin_label, asset_plugin.package_dir
|
|
230
289
|
)
|
|
231
290
|
else:
|
|
232
291
|
self.module_informationPlugin_label.setText("No asset available")
|
|
292
|
+
self.module_informationPlugin_label.setToolTip("")
|
|
293
|
+
|
|
294
|
+
def __packagePrepareTaskProgress(self, progress, bytes_downloaded):
|
|
295
|
+
if progress < 0:
|
|
296
|
+
# Indeterminate progress (size unknown)
|
|
297
|
+
self.module_progressBar.setMaximum(0)
|
|
298
|
+
self.module_progressBar.setValue(0)
|
|
299
|
+
if bytes_downloaded > 0:
|
|
300
|
+
mb_downloaded = bytes_downloaded / (1024 * 1024)
|
|
301
|
+
loading_text = self.tr(f"Downloading package... {mb_downloaded:.1f} MB")
|
|
302
|
+
else:
|
|
303
|
+
loading_text = self.tr("Downloading package...")
|
|
304
|
+
else:
|
|
305
|
+
# Determinate progress (0-100%)
|
|
306
|
+
self.module_progressBar.setMaximum(100)
|
|
307
|
+
self.module_progressBar.setValue(int(progress))
|
|
308
|
+
mb_downloaded = bytes_downloaded / (1024 * 1024)
|
|
309
|
+
loading_text = self.tr(f"Downloading... {mb_downloaded:.1f} MB ({progress:.0f}%)")
|
|
233
310
|
|
|
234
|
-
def __packagePrepareTaskProgress(self, progress):
|
|
235
|
-
loading_text = self.tr("Load package task running...")
|
|
236
|
-
logger.info(loading_text)
|
|
237
311
|
self.module_information_label.setText(loading_text)
|
|
238
312
|
|
|
239
313
|
def __seeChangeLogClicked(self):
|
|
@@ -300,6 +374,9 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
300
374
|
return
|
|
301
375
|
|
|
302
376
|
for module_package in self.__current_module.versions:
|
|
377
|
+
# Skip pre-releases in the main list (they'll be shown in development versions)
|
|
378
|
+
if module_package.prerelease is True:
|
|
379
|
+
continue
|
|
303
380
|
self.module_package_comboBox.addItem(module_package.display_name(), module_package)
|
|
304
381
|
|
|
305
382
|
if self.__current_module.latest_version is not None:
|
|
@@ -321,10 +398,19 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
321
398
|
)
|
|
322
399
|
|
|
323
400
|
self.module_package_comboBox.insertSeparator(self.module_package_comboBox.count())
|
|
324
|
-
self.module_package_comboBox.addItem(
|
|
325
|
-
self.tr("Load development branches"), self.module_package_SPECIAL_LOAD_DEVELOPMENT
|
|
326
|
-
)
|
|
327
401
|
|
|
402
|
+
# If development versions were already loaded, add them directly
|
|
403
|
+
# Otherwise show the option to load them
|
|
404
|
+
if self.__current_module.development_versions:
|
|
405
|
+
for module_package in self.__current_module.development_versions:
|
|
406
|
+
self.module_package_comboBox.addItem(module_package.display_name(), module_package)
|
|
407
|
+
else:
|
|
408
|
+
self.module_package_comboBox.addItem(
|
|
409
|
+
self.tr("Load pre-releases and development branches"),
|
|
410
|
+
self.module_package_SPECIAL_LOAD_DEVELOPMENT,
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
self.__enable_package_selection()
|
|
328
414
|
self.module_progressBar.setVisible(False)
|
|
329
415
|
logger.info(f"Versions loaded for module '{self.__current_module.name}'.")
|
|
330
416
|
|
|
@@ -373,3 +459,5 @@ class ModuleSelectionWidget(QWidget, DIALOG_UI):
|
|
|
373
459
|
|
|
374
460
|
for module_package in self.__current_module.development_versions:
|
|
375
461
|
self.module_package_comboBox.addItem(module_package.display_name(), module_package)
|
|
462
|
+
|
|
463
|
+
self.__enable_package_selection()
|