oqtopus 0.1.14__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.
@@ -0,0 +1,350 @@
1
+ from qgis.PyQt.QtCore import Qt, QUrl, pyqtSignal
2
+ from qgis.PyQt.QtGui import QDesktopServices
3
+ from qgis.PyQt.QtWidgets import QApplication, QFileDialog, QMessageBox, QWidget
4
+
5
+ from ..core.module import Module
6
+ from ..core.module_package import ModulePackage
7
+ from ..core.package_prepare_task import PackagePrepareTask, PackagePrepareTaskCanceled
8
+ from ..utils.plugin_utils import PluginUtils, logger
9
+ from ..utils.qt_utils import CriticalMessageBox, OverrideCursor, QtUtils
10
+
11
+ DIALOG_UI = PluginUtils.get_ui_class("module_selection_widget.ui")
12
+
13
+
14
+ class ModuleSelectionWidget(QWidget, DIALOG_UI):
15
+
16
+ module_package_SPECIAL_LOAD_DEVELOPMENT = "Load development versions"
17
+
18
+ signal_loadingStarted = pyqtSignal()
19
+ signal_loadingFinished = pyqtSignal()
20
+
21
+ def __init__(self, modules_config, parent=None):
22
+ QWidget.__init__(self, parent)
23
+ self.setupUi(self)
24
+
25
+ self.__current_module = None
26
+ self.__current_module_package = None
27
+ self.__modules_config = modules_config
28
+
29
+ self.module_progressBar.setVisible(False)
30
+
31
+ self.module_module_comboBox.clear()
32
+ self.module_module_comboBox.addItem(self.tr("Please select a module"), None)
33
+ for config_module in self.__modules_config.modules:
34
+ module = Module(
35
+ name=config_module.name,
36
+ organisation=config_module.organisation,
37
+ repository=config_module.repository,
38
+ parent=self,
39
+ )
40
+ self.module_module_comboBox.addItem(module.name, module)
41
+ module.signal_versionsLoaded.connect(self.__loadVersionsFinished)
42
+ module.signal_developmentVersionsLoaded.connect(self.__loadDevelopmentVersionsFinished)
43
+
44
+ self.module_latestVersion_label.setText("")
45
+ QtUtils.setForegroundColor(self.module_latestVersion_label, PluginUtils.COLOR_GREEN)
46
+
47
+ self.module_package_comboBox.clear()
48
+ self.module_package_comboBox.addItem(self.tr("Please select a version"), None)
49
+
50
+ self.module_zipPackage_groupBox.setVisible(False)
51
+
52
+ self.module_module_comboBox.currentIndexChanged.connect(self.__moduleChanged)
53
+ self.module_package_comboBox.currentIndexChanged.connect(self.__moduleVersionChanged)
54
+ self.module_seeChangeLog_pushButton.clicked.connect(self.__seeChangeLogClicked)
55
+ self.module_browseZip_toolButton.clicked.connect(self.__moduleBrowseZipClicked)
56
+
57
+ self.__packagePrepareTask = PackagePrepareTask(self)
58
+ self.__packagePrepareTask.finished.connect(self.__packagePrepareTaskFinished)
59
+ self.__packagePrepareTask.signalPackagingProgress.connect(
60
+ self.__packagePrepareTaskProgress
61
+ )
62
+
63
+ def close(self):
64
+ if self.__packagePrepareTask.isRunning():
65
+ self.__packagePrepareTask.cancel()
66
+ self.__packagePrepareTask.wait()
67
+
68
+ def getSelectedModulePackage(self):
69
+ return self.__current_module_package
70
+
71
+ def lastError(self):
72
+ """
73
+ Returns the last error occurred during the loading process.
74
+ If no error occurred, returns None.
75
+ """
76
+ return self.__packagePrepareTask.lastError
77
+
78
+ def __moduleChanged(self, index):
79
+ if self.module_module_comboBox.currentData() == self.__current_module:
80
+ return
81
+
82
+ self.__current_module = self.module_module_comboBox.currentData()
83
+
84
+ self.module_latestVersion_label.setText("")
85
+ self.module_package_comboBox.clear()
86
+ self.module_package_comboBox.addItem(self.tr("Please select a version"), None)
87
+
88
+ if self.__current_module is None:
89
+ return
90
+
91
+ if self.__current_module.versions == list():
92
+ QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
93
+ self.__current_module.start_load_versions()
94
+
95
+ def __moduleVersionChanged(self, index):
96
+
97
+ if (
98
+ self.module_package_comboBox.currentData()
99
+ == self.module_package_SPECIAL_LOAD_DEVELOPMENT
100
+ ):
101
+ self.__loadDevelopmentVersions()
102
+ return
103
+
104
+ if self.__packagePrepareTask.isRunning():
105
+ logger.info("Package prepare task is running, canceling it.")
106
+ self.__packagePrepareTask.cancel()
107
+ self.__packagePrepareTask.wait()
108
+
109
+ self.__current_module_package = self.module_package_comboBox.currentData()
110
+ if self.__current_module_package is None:
111
+ return
112
+
113
+ if self.__current_module_package.type == self.__current_module_package.Type.FROM_ZIP:
114
+ self.module_zippackage_groupBox.setVisible(True)
115
+ return
116
+ else:
117
+ self.module_zipPackage_groupBox.setVisible(False)
118
+
119
+ loading_text = self.tr(
120
+ f"Loading packages for module '{self.module_module_comboBox.currentText()}' version '{self.__current_module_package.display_name()}'..."
121
+ )
122
+ self.module_information_label.setText(loading_text)
123
+ QtUtils.resetForegroundColor(self.module_information_label)
124
+ logger.info(loading_text)
125
+
126
+ self.module_informationProject_label.setText("-")
127
+ self.module_informationPlugin_label.setText("-")
128
+
129
+ self.__packagePrepareTask.startFromModulePackage(self.__current_module_package)
130
+
131
+ self.signal_loadingStarted.emit()
132
+ self.module_progressBar.setVisible(True)
133
+
134
+ def __loadDevelopmentVersions(self):
135
+ if self.__current_module is None:
136
+ return
137
+
138
+ if self.__current_module.development_versions == list():
139
+ QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
140
+ self.__current_module.start_load_development_versions()
141
+
142
+ def __moduleBrowseZipClicked(self):
143
+ filename, format = QFileDialog.getOpenFileName(
144
+ self, self.tr("Open from zip"), None, self.tr("Zip package (*.zip)")
145
+ )
146
+
147
+ if filename == "":
148
+ return
149
+
150
+ self.module_fromZip_lineEdit.setText(filename)
151
+
152
+ try:
153
+ with OverrideCursor(Qt.CursorShape.WaitCursor):
154
+ self.__loadModuleFromZip(filename)
155
+ except Exception as exception:
156
+ CriticalMessageBox(
157
+ self.tr("Error"), self.tr("Can't load module from zip file:"), exception, self
158
+ ).exec()
159
+ return
160
+
161
+ def __loadModuleFromZip(self, filename):
162
+
163
+ if self.__packagePrepareTask.isRunning():
164
+ self.__packagePrepareTask.cancel()
165
+ self.__packagePrepareTask.wait()
166
+
167
+ self.__packagePrepareTask.startFromZip(filename)
168
+
169
+ self.signal_loadingStarted.emit()
170
+ self.module_progressBar.setVisible(True)
171
+
172
+ def __packagePrepareTaskFinished(self):
173
+ logger.info("Load package task finished")
174
+
175
+ self.signal_loadingFinished.emit()
176
+ self.module_progressBar.setVisible(False)
177
+
178
+ if isinstance(self.__packagePrepareTask.lastError, PackagePrepareTaskCanceled):
179
+ logger.info("Load package task was canceled by user.")
180
+ self.module_information_label.setText(self.tr("Package loading canceled."))
181
+ QtUtils.setForegroundColor(self.module_information_label, PluginUtils.COLOR_WARNING)
182
+ return
183
+
184
+ if self.__packagePrepareTask.lastError is not None:
185
+ error_text = self.tr("Can't load module package:")
186
+ CriticalMessageBox(
187
+ self.tr("Error"), error_text, self.__packagePrepareTask.lastError, self
188
+ ).exec()
189
+ self.module_information_label.setText(error_text)
190
+ QtUtils.setForegroundColor(self.module_information_label, PluginUtils.COLOR_WARNING)
191
+ return
192
+
193
+ package_dir = self.module_package_comboBox.currentData().package_dir
194
+ logger.info(f"Package loaded into '{package_dir}'")
195
+ self.module_information_label.setText(package_dir)
196
+ QtUtils.resetForegroundColor(self.module_information_label)
197
+
198
+ asset_project = self.module_package_comboBox.currentData().asset_project
199
+ if asset_project:
200
+ self.module_informationProject_label.setText(asset_project.package_dir)
201
+ else:
202
+ self.module_informationProject_label.setText("No asset available")
203
+
204
+ asset_plugin = self.module_package_comboBox.currentData().asset_plugin
205
+ if asset_plugin:
206
+ self.module_informationPlugin_label.setText(asset_plugin.package_dir)
207
+ else:
208
+ self.module_informationPlugin_label.setText("No asset available")
209
+
210
+ def __packagePrepareTaskProgress(self, progress):
211
+ loading_text = self.tr("Load package task running...")
212
+ logger.info(loading_text)
213
+ self.module_information_label.setText(loading_text)
214
+
215
+ def __seeChangeLogClicked(self):
216
+ if self.__current_module_package.type == ModulePackage.Type.FROM_ZIP:
217
+ QMessageBox.warning(
218
+ self,
219
+ self.tr("Can't open changelog"),
220
+ self.tr("Changelog is not available for Zip packages."),
221
+ )
222
+ return
223
+
224
+ if self.__current_module_package is None:
225
+ QMessageBox.warning(
226
+ self,
227
+ self.tr("Can't open changelog"),
228
+ self.tr("Please select a module and version first."),
229
+ )
230
+ return
231
+
232
+ if self.__current_module_package.html_url is None:
233
+ QMessageBox.warning(
234
+ self,
235
+ self.tr("Can't open changelog"),
236
+ self.tr(
237
+ f"Changelog not available for version '{self.__current_module_package.display_name()}'."
238
+ ),
239
+ )
240
+ return
241
+
242
+ changelog_url = self.__current_module_package.html_url
243
+ logger.info(f"Opening changelog URL: {changelog_url}")
244
+ QDesktopServices.openUrl(QUrl(changelog_url))
245
+
246
+ def __loadVersionsFinished(self, error):
247
+ logger.info("Loading versions finished")
248
+
249
+ QApplication.restoreOverrideCursor()
250
+ self.signal_loadingFinished.emit()
251
+ self.module_progressBar.setVisible(False)
252
+
253
+ if error:
254
+ if "rate limit exceeded for url" in error.lower():
255
+ QMessageBox.critical(
256
+ self,
257
+ self.tr("GitHub API Rate Limit Exceeded"),
258
+ self.tr(
259
+ "Oqtopus needs to download release data from GitHub to work properly.<br><br>"
260
+ "GitHub limits the number of requests that can be made without authentication. "
261
+ "You have reached the maximum number of requests allowed for unauthenticated users.<br><br>"
262
+ "To continue using this feature, please create a free GitHub personal access token and enter it in the Settings dialog.<br><br>"
263
+ "This will increase your request limit.<br><br>"
264
+ "<b>How to get a token:</b><br>"
265
+ "1. Go to <a href='https://github.com/settings/tokens'>GitHub Personal Access Tokens</a>.<br>"
266
+ "2. Click <b>Generate new token</b> and select the <code>repo</code> scope.<br>"
267
+ "3. Copy the generated token and paste it in the Settings dialog of this application."
268
+ ),
269
+ )
270
+ return
271
+
272
+ error_text = self.tr(f"Can't load module versions: {error}")
273
+ QMessageBox.critical(self, self.tr("Error"), error_text)
274
+ self.module_information_label.setText(error_text)
275
+ QtUtils.setForegroundColor(self.module_information_label, PluginUtils.COLOR_WARNING)
276
+ return
277
+
278
+ for module_package in self.__current_module.versions:
279
+ self.module_package_comboBox.addItem(module_package.display_name(), module_package)
280
+
281
+ if self.__current_module.latest_version is not None:
282
+ self.module_latestVersion_label.setText(
283
+ f"Latest: {self.__current_module.latest_version.name}"
284
+ )
285
+
286
+ self.module_package_comboBox.insertSeparator(self.module_package_comboBox.count())
287
+ self.module_package_comboBox.addItem(
288
+ self.tr("Load from ZIP file"),
289
+ ModulePackage(
290
+ module=self.__current_module,
291
+ organisation=self.__current_module.organisation,
292
+ repository=self.__current_module.repository,
293
+ json_payload=None,
294
+ type=ModulePackage.Type.FROM_ZIP,
295
+ ),
296
+ )
297
+
298
+ self.module_package_comboBox.insertSeparator(self.module_package_comboBox.count())
299
+ self.module_package_comboBox.addItem(
300
+ self.tr("Load development branches"), self.module_package_SPECIAL_LOAD_DEVELOPMENT
301
+ )
302
+
303
+ self.module_progressBar.setVisible(False)
304
+ logger.info(f"Versions loaded for module '{self.__current_module.name}'.")
305
+
306
+ def __loadDevelopmentVersionsFinished(self, error):
307
+ logger.info("Loading development versions finished")
308
+
309
+ QApplication.restoreOverrideCursor()
310
+ self.signal_loadingFinished.emit()
311
+ self.module_progressBar.setVisible(False)
312
+
313
+ if error:
314
+ if "rate limit exceeded for url" in error.lower():
315
+ QMessageBox.critical(
316
+ self,
317
+ self.tr("GitHub API Rate Limit Exceeded"),
318
+ self.tr(
319
+ "Oqtopus needs to download release data from GitHub to work properly.<br><br>"
320
+ "GitHub limits the number of requests that can be made without authentication. "
321
+ "You have reached the maximum number of requests allowed for unauthenticated users.<br><br>"
322
+ "To continue using this feature, please create a free GitHub personal access token and enter it in the Settings dialog.<br><br>"
323
+ "This will increase your request limit.<br><br>"
324
+ "<b>How to get a token:</b><br>"
325
+ "1. Go to <a href='https://github.com/settings/tokens'>GitHub Personal Access Tokens</a>.<br>"
326
+ "2. Click <b>Generate new token</b> and select the <code>repo</code> scope.<br>"
327
+ "3. Copy the generated token and paste it in the Settings dialog of this application."
328
+ ),
329
+ )
330
+ return
331
+
332
+ error_text = self.tr(f"Can't load module versions: {error}")
333
+ QMessageBox.critical(self, self.tr("Error"), error_text)
334
+ self.module_information_label.setText(error_text)
335
+ QtUtils.setForegroundColor(self.module_information_label, PluginUtils.COLOR_WARNING)
336
+ return
337
+
338
+ if self.__current_module.development_versions == list():
339
+ QMessageBox.warning(
340
+ self,
341
+ self.tr("No development versions found"),
342
+ self.tr("No development versions found for this module."),
343
+ )
344
+ return
345
+
346
+ self.module_package_comboBox.removeItem(self.module_package_comboBox.count() - 1)
347
+ self.module_package_comboBox.setCurrentIndex(0)
348
+
349
+ for module_package in self.__current_module.development_versions:
350
+ self.module_package_comboBox.addItem(module_package.display_name(), module_package)
@@ -0,0 +1,199 @@
1
+ import os
2
+
3
+ import psycopg
4
+ from pum.pum_config import PumConfig
5
+ from pum.schema_migrations import SchemaMigrations
6
+ from pum.upgrader import Upgrader
7
+ from qgis.PyQt.QtCore import Qt
8
+ from qgis.PyQt.QtWidgets import QMessageBox, QWidget
9
+
10
+ from ..core.module import Module
11
+ from ..utils.plugin_utils import PluginUtils, logger
12
+ from ..utils.qt_utils import CriticalMessageBox, OverrideCursor, QtUtils
13
+
14
+ DIALOG_UI = PluginUtils.get_ui_class("module_widget.ui")
15
+
16
+
17
+ class ModuleWidget(QWidget, DIALOG_UI):
18
+
19
+ def __init__(self, parent=None):
20
+ QWidget.__init__(self, parent)
21
+ self.setupUi(self)
22
+
23
+ self.moduleInfo_stackedWidget.setCurrentWidget(self.moduleInfo_stackedWidget_pageInstall)
24
+
25
+ self.db_demoData_checkBox.clicked.connect(
26
+ lambda checked: self.db_demoData_comboBox.setEnabled(checked)
27
+ )
28
+
29
+ self.moduleInfo_install_pushButton.clicked.connect(self.__installModuleClicked)
30
+ self.moduleInfo_upgrade_pushButton.clicked.connect(self.__upgradeModuleClicked)
31
+
32
+ self.__current_module_package = None
33
+ self.__database_connection = None
34
+
35
+ def setModulePackage(self, module_package: Module):
36
+ self.__current_module_package = module_package
37
+ self.__packagePrepareGetPUMConfig()
38
+ self.__updateModuleInfo()
39
+
40
+ def setDatabaseConnection(self, connection: psycopg.Connection):
41
+ self.__database_connection = connection
42
+ self.__updateModuleInfo()
43
+
44
+ def __packagePrepareGetPUMConfig(self):
45
+ package_dir = self.__current_module_package.package_dir
46
+
47
+ if package_dir is None:
48
+ CriticalMessageBox(
49
+ self.tr("Error"),
50
+ self.tr(
51
+ f"The selected file '{self.__current_module_package.zip_file}' does not contain a valid package directory."
52
+ ),
53
+ None,
54
+ self,
55
+ ).exec()
56
+ return
57
+
58
+ self.__data_model_dir = os.path.join(package_dir, "datamodel")
59
+ pumConfigFilename = os.path.join(self.__data_model_dir, ".pum.yaml")
60
+ if not os.path.exists(pumConfigFilename):
61
+ CriticalMessageBox(
62
+ self.tr("Error"),
63
+ self.tr(
64
+ f"The selected file '{self.__current_module_package.zip_file}' does not contain a valid .pum.yaml file."
65
+ ),
66
+ None,
67
+ self,
68
+ ).exec()
69
+ return
70
+
71
+ try:
72
+ self.__pum_config = PumConfig.from_yaml(pumConfigFilename, install_dependencies=True)
73
+ except Exception as exception:
74
+ CriticalMessageBox(
75
+ self.tr("Error"),
76
+ self.tr(f"Can't load PUM config from '{pumConfigFilename}':"),
77
+ exception,
78
+ self,
79
+ ).exec()
80
+ return
81
+
82
+ logger.info(f"PUM config loaded from '{pumConfigFilename}'")
83
+
84
+ self.parameters_groupbox.setParameters(self.__pum_config.parameters())
85
+
86
+ self.db_demoData_comboBox.clear()
87
+ for demo_data_name, demo_data_file in self.__pum_config.demo_data().items():
88
+ self.db_demoData_comboBox.addItem(demo_data_name, demo_data_file)
89
+
90
+ def __installModuleClicked(self):
91
+
92
+ if self.__current_module_package is None:
93
+ CriticalMessageBox(
94
+ self.tr("Error"), self.tr("Please select a module package first."), None, self
95
+ ).exec()
96
+ return
97
+
98
+ if self.__database_connection is None:
99
+ CriticalMessageBox(
100
+ self.tr("Error"), self.tr("Please select a database service first."), None, self
101
+ ).exec()
102
+ return
103
+
104
+ if self.__pum_config is None:
105
+ CriticalMessageBox(
106
+ self.tr("Error"), self.tr("No valid module available."), None, self
107
+ ).exec()
108
+ return
109
+
110
+ parameters = self.parameters_groupbox.parameters_values()
111
+
112
+ try:
113
+ upgrader = Upgrader(
114
+ config=self.__pum_config,
115
+ )
116
+ with OverrideCursor(Qt.CursorShape.WaitCursor):
117
+ upgrader.install(
118
+ parameters=parameters,
119
+ connection=self.__database_connection,
120
+ roles=self.db_parameters_CreateAndGrantRoles_checkBox.isChecked(),
121
+ grant=self.db_parameters_CreateAndGrantRoles_checkBox.isChecked(),
122
+ )
123
+
124
+ if self.db_demoData_checkBox.isChecked():
125
+ demo_data_name = self.db_demoData_comboBox.currentText()
126
+ upgrader.install_demo_data(
127
+ connection=self.__database_connection,
128
+ name=demo_data_name,
129
+ parameters=parameters,
130
+ )
131
+ except Exception as exception:
132
+ CriticalMessageBox(
133
+ self.tr("Error"), self.tr("Can't install the module:"), exception, self
134
+ ).exec()
135
+ return
136
+
137
+ QMessageBox.information(
138
+ self,
139
+ self.tr("Module installed"),
140
+ self.tr(
141
+ f"Module '{self.__current_module_package.module.name}' version '{self.__current_module_package.name}' has been successfully installed."
142
+ ),
143
+ )
144
+ logger.info(
145
+ f"Module '{self.__current_module_package.module.name}' version '{self.__current_module_package.name}' has been successfully installed."
146
+ )
147
+
148
+ self.__updateModuleInfo()
149
+
150
+ def __upgradeModuleClicked(self):
151
+ QMessageBox.critical(
152
+ self,
153
+ self.tr("Not implemented"),
154
+ self.tr("Upgrade module is not implemented yet."),
155
+ )
156
+ return
157
+
158
+ def __updateModuleInfo(self):
159
+ if self.__current_module_package is None:
160
+ self.moduleInfo_label.setText(self.tr("No module package selected"))
161
+ QtUtils.setForegroundColor(self.moduleInfo_label, PluginUtils.COLOR_WARNING)
162
+ return
163
+
164
+ if self.__database_connection is None:
165
+ self.moduleInfo_label.setText(self.tr("No database connection available"))
166
+ QtUtils.setForegroundColor(self.moduleInfo_label, PluginUtils.COLOR_WARNING)
167
+ return
168
+
169
+ if self.__pum_config is None:
170
+ self.moduleInfo_label.setText(self.tr("No PUM config available"))
171
+ QtUtils.setForegroundColor(self.moduleInfo_label, PluginUtils.COLOR_WARNING)
172
+ return
173
+
174
+ migrationVersion = self.__pum_config.last_version()
175
+ sm = SchemaMigrations(self.__pum_config)
176
+
177
+ if sm.exists(self.__database_connection):
178
+ # Case upgrade
179
+ baseline_version = sm.baseline(self.__database_connection)
180
+ self.moduleInfo_label.setText(self.tr(f"Version {baseline_version} found"))
181
+ QtUtils.resetForegroundColor(self.moduleInfo_label)
182
+ self.moduleInfo_upgrade_pushButton.setText(self.tr(f"Upgrade to {migrationVersion}"))
183
+
184
+ self.moduleInfo_stackedWidget.setCurrentWidget(
185
+ self.moduleInfo_stackedWidget_pageUpgrade
186
+ )
187
+
188
+ logger.info(
189
+ f"Migration table details: {sm.migration_details(self.__database_connection)}"
190
+ )
191
+
192
+ else:
193
+ # Case install
194
+ self.moduleInfo_label.setText(self.tr("No module found"))
195
+ QtUtils.resetForegroundColor(self.moduleInfo_label)
196
+ self.moduleInfo_install_pushButton.setText(self.tr(f"Install {migrationVersion}"))
197
+ self.moduleInfo_stackedWidget.setCurrentWidget(
198
+ self.moduleInfo_stackedWidget_pageInstall
199
+ )
@@ -0,0 +1,75 @@
1
+ import logging
2
+
3
+ from pum import ParameterDefinition, ParameterType
4
+ from qgis.PyQt.QtWidgets import (
5
+ QCheckBox,
6
+ QGroupBox,
7
+ QHBoxLayout,
8
+ QLabel,
9
+ QLineEdit,
10
+ QWidget,
11
+ )
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class ParameterWidget(QWidget):
17
+ def __init__(self, parameter_definition: ParameterDefinition, parent):
18
+ QWidget.__init__(self, parent)
19
+ self.layout = QHBoxLayout(self)
20
+ self.layout.setContentsMargins(0, 0, 0, 0)
21
+ self.setLayout(self.layout)
22
+ self.value = None
23
+ self.__valueChanged = False
24
+
25
+ if parameter_definition.type != ParameterType.BOOLEAN:
26
+ self.layout.addWidget(QLabel(parameter_definition.name, self))
27
+
28
+ if parameter_definition.type == ParameterType.BOOLEAN:
29
+ self.widget = QCheckBox(parameter_definition.name, self)
30
+ self.widget.setChecked(parameter_definition.default)
31
+ self.widget.checked.connect(self.__valueChanged)
32
+ self.layout.addWidget(self.widget)
33
+ self.value = lambda: self.widget.isChecked()
34
+ elif parameter_definition.type in (
35
+ ParameterType.DECIMAL,
36
+ ParameterType.INTEGER,
37
+ ParameterType.TEXT,
38
+ ):
39
+ self.widget = QLineEdit(self)
40
+ if parameter_definition.default is not None:
41
+ self.widget.setPlaceholderText(str(parameter_definition.default))
42
+ self.layout.addWidget(self.widget)
43
+ if parameter_definition.type == ParameterType.INTEGER:
44
+ self.value = lambda: int(self.widget.text() or self.widget.placeholderText())
45
+ elif parameter_definition.type == ParameterType.DECIMAL:
46
+ self.value = lambda: float(self.widget.text() or self.widget.placeholderText())
47
+ else:
48
+ self.value = lambda: self.widget.text() or self.widget.placeholderText()
49
+
50
+
51
+ class ParametersGroupBox(QGroupBox):
52
+ def __init__(self, parent):
53
+ QGroupBox.__init__(self, parent)
54
+ self.parameter_widgets = {}
55
+
56
+ def setParameters(self, parameters: list[ParameterDefinition]):
57
+ logger.info(f"Setting parameters in ParametersGroupBox ({len(parameters)})")
58
+ self.clean()
59
+ self.parameters = parameters
60
+ # Remove all widgets from the parameters_group_box layout
61
+ for parameter in parameters:
62
+ pw = ParameterWidget(parameter, self)
63
+ self.layout().addWidget(pw)
64
+ self.parameter_widgets[parameter.name] = pw
65
+
66
+ def parameters_values(self):
67
+ values = {}
68
+ for parameter in self.parameters:
69
+ values[parameter.name] = self.parameter_widgets[parameter.name].value()
70
+ return values
71
+
72
+ def clean(self):
73
+ for widget in self.parameter_widgets.values():
74
+ widget.deleteLater()
75
+ self.parameter_widgets = {}