From fd0823f2bba5467a3e8f9b90076b052395737a40 Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 14:20:03 +0100
Subject: [PATCH 1/9] recognize if we find a metaconfig-id in the corrent
database - if so, we provide it to the gui. we can disable the metaconfig
from the database and select another project topping from the usabilityhub or
from the local system. when a topping is selected we disable the optimize
strategy.
---
.../workflow_wizard/project_creation_page.py | 460 ++++++++++++++----
.../ui/workflow_wizard/project_creation.ui | 207 +++++---
2 files changed, 497 insertions(+), 170 deletions(-)
diff --git a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
index dd4a7039a..cea3b14af 100644
--- a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
@@ -17,28 +17,43 @@
***************************************************************************/
"""
+import configparser
import os
+import re
import yaml
-from qgis.core import QgsProject
+from qgis.core import Qgis, QgsProject
from qgis.PyQt.QtCore import Qt
-from qgis.PyQt.QtWidgets import QWizardPage
+from qgis.PyQt.QtWidgets import QCompleter, QWizardPage
+import QgisModelBaker.libs.modelbaker.utils.db_utils as db_utils
from QgisModelBaker.libs.modelbaker.dataobjects.project import Project
from QgisModelBaker.libs.modelbaker.db_factory.db_simple_factory import DbSimpleFactory
from QgisModelBaker.libs.modelbaker.dbconnector.db_connector import DBConnectorError
from QgisModelBaker.libs.modelbaker.generator.generator import Generator
from QgisModelBaker.libs.modelbaker.iliwrapper.globals import DbIliMode
-from QgisModelBaker.libs.modelbaker.iliwrapper.ilicache import IliToppingFileItemModel
+from QgisModelBaker.libs.modelbaker.iliwrapper.ilicache import (
+ IliDataCache,
+ IliDataFileCompleterDelegate,
+ IliDataItemModel,
+ IliToppingFileItemModel,
+)
from QgisModelBaker.libs.modelbaker.utils.globals import OptimizeStrategy
+from QgisModelBaker.libs.modelbaker.utils.qt_utils import (
+ FileValidator,
+ make_file_selector,
+)
from QgisModelBaker.utils import gui_utils
from QgisModelBaker.utils.globals import CATALOGUE_DATASETNAME
-from QgisModelBaker.utils.gui_utils import LogColor
+from QgisModelBaker.utils.gui_utils import TRANSFERFILE_MODELS_BLACKLIST, LogColor
PAGE_UI = gui_utils.get_ui_class("workflow_wizard/project_creation.ui")
class ProjectCreationPage(QWizardPage, PAGE_UI):
+
+ ValidExtensions = ["YAML", "yaml"]
+
def __init__(self, parent, title):
QWizardPage.__init__(self, parent)
@@ -48,6 +63,12 @@ def __init__(self, parent, title):
self.setTitle(title)
self.setStyleSheet(gui_utils.DEFAULT_STYLE)
+ self.db_simple_factory = DbSimpleFactory()
+ self.configuration = None
+
+ self.existing_projecttopping_id = None
+ self.projecttopping_id = None
+
self.optimize_combo.clear()
self.optimize_combo.addItem(
self.tr("Hide unused base class layers"), OptimizeStrategy.HIDE
@@ -57,13 +78,32 @@ def __init__(self, parent, title):
)
self.optimize_combo.addItem(self.tr("No optimization"), OptimizeStrategy.NONE)
- self.db_simple_factory = DbSimpleFactory()
- self.configuration = None
-
self.create_project_button.clicked.connect(self._create_project)
-
self.is_complete = False
+ self.existing_topping_checkbox.setVisible(False)
+ self.existing_topping_checkbox.stateChanged.connect(self._use_existing)
+
+ self.ilitoppingcache = IliDataCache(None)
+ self.ilitopping_delegate = IliDataFileCompleterDelegate()
+ self.topping_line_edit.setPlaceholderText(
+ self.tr("[Search project toppings on the repositories or the local system]")
+ )
+ self.topping_line_edit.textChanged.connect(self._complete_completer)
+ self.topping_line_edit.punched.connect(self._complete_completer)
+ self.topping_line_edit.textChanged.emit(self.topping_line_edit.text())
+ self.topping_line_edit.textChanged.connect(self._on_completer_activated)
+ self.topping_file_browse_button.clicked.connect(
+ make_file_selector(
+ self.topping_line_edit,
+ title=self.tr("Project Topping"),
+ file_filter=self.tr("Project Topping File (*.yaml *.YAML)"),
+ )
+ )
+ self.fileValidator = FileValidator(
+ pattern=["*." + ext for ext in self.ValidExtensions], allow_empty=False
+ )
+
def isComplete(self):
return self.is_complete
@@ -73,7 +113,240 @@ def setComplete(self, complete):
self.completeChanged.emit()
def restore_configuration(self, configuration):
+ self.setEnabled(False)
self.configuration = configuration
+ self.db_connector = db_utils.get_db_connector(self.configuration)
+
+ # get existing topping
+ self.existing_topping_checkbox.setVisible(False)
+ self.existing_projecttopping_id = self._existing_projecttopping_id()
+ if self.existing_projecttopping_id:
+ self.tr("Use existing project topping {}").format(self.projecttopping_id)
+ self.existing_topping_checkbox.setVisible(True)
+ self.existing_topping_checkbox.setChecked(True)
+ else:
+ self._use_existing(False)
+ self.setEnabled(True)
+
+ def _use_existing(self, state):
+ # triggered by checked state...
+ if state:
+ self._clean_topping()
+ self.topping_line_edit.setText("")
+ self._enable_topping_selection(False)
+ self._enable_optimize_combo(False)
+ self.projecttopping_id = self.existing_projecttopping_id
+ self._set_topping_info(True)
+ else:
+ self._clean_topping()
+ models = ";".join(self._modelnames())
+ self.ilitoppingcache = IliDataCache(
+ self.configuration.base_configuration, "projecttopping", models
+ )
+ self.ilitoppingcache.new_message.connect(
+ self.workflow_wizard.log_panel.show_message
+ )
+ # wait before activating untill end of refreshment
+ self.ilitoppingcache.model_refreshed.connect(
+ lambda: self._enable_topping_selection(True)
+ )
+ self._enable_optimize_combo(True)
+ self.ilitoppingcache.refresh()
+
+ completer = QCompleter(
+ self.ilitoppingcache.sorted_model,
+ self.topping_line_edit,
+ )
+ completer.setCaseSensitivity(Qt.CaseInsensitive)
+ completer.setModelSorting(
+ QCompleter.ModelSorting.CaseInsensitivelySortedModel
+ )
+ completer.setFilterMode(Qt.MatchContains)
+ completer.popup().setItemDelegate(self.ilitopping_delegate)
+ self.topping_line_edit.setCompleter(completer)
+ self._enable_optimize_combo(True)
+
+ def _enable_topping_selection(self, state):
+ # doublecheck if meanwhile user checked box again
+ if state:
+ state = state and not self.existing_topping_checkbox.isChecked()
+ self.topping_file_browse_button.setEnabled(state)
+ self.topping_line_edit.setEnabled(state)
+ self.topping_line_label.setEnabled(state)
+ self.topping_info.setEnabled(state)
+
+ def _enable_optimize_combo(self, state):
+ self.optimize_combo.setEnabled(state)
+ self.optimize_label.setEnabled(state)
+
+ def _datasource_metaconfig(self):
+ metaconfig_id = None
+ setting_records = self.db_connector.get_ili2db_settings()
+ for setting_record in setting_records:
+ if setting_record["tag"] == "ch.ehi.ili2db.metaConfigFileName":
+ metaconfig_id = setting_record["setting"]
+ break
+ if metaconfig_id:
+ metaconfig_file_path_list = self.workflow_wizard.get_topping_file_list(
+ [metaconfig_id]
+ )
+
+ if not metaconfig_file_path_list:
+ self.workflow_wizard.log_panel.print_info(
+ self.tr(
+ "Found a metaconfig-id ({}) in the data source, but no corresponding metaconfig in the repositories."
+ ).format(metaconfig_id),
+ LogColor.COLOR_TOPPING,
+ )
+ return None
+
+ metaconfig = configparser.ConfigParser()
+ with open(metaconfig_file_path_list[0]) as metaconfig_file:
+ metaconfig.read_file(metaconfig_file)
+ return metaconfig
+
+ return None
+
+ def _existing_projecttopping_id(self):
+ metaconfig = self.configuration.metaconfig
+
+ if not metaconfig:
+ metaconfig = self._datasource_metaconfig()
+
+ if not metaconfig:
+ # no existing metaconfig available
+ return None
+
+ # get projecttopping_id from metaconfig
+ if "CONFIGURATION" in metaconfig.sections():
+ configuration_section = metaconfig["CONFIGURATION"]
+ # get topping referenced in qgis.modelbaker.projecttopping
+ key = "qgis.modelbaker.projecttopping"
+ if key not in configuration_section:
+ key = "qgis.modelbaker.layertree"
+ self.workflow_wizard.log_panel.print_info(
+ self.tr(
+ 'Keyword "qgis.modelbaker.layertree" is deprecated (but still working). Use "qgis.modelbaker.projecttopping" instead.'
+ ),
+ LogColor.COLOR_TOPPING,
+ )
+
+ if key in configuration_section:
+ self.workflow_wizard.log_panel.print_info(
+ self.tr("Metaconfig contains a project topping."),
+ LogColor.COLOR_TOPPING,
+ )
+ projecttopping_id_list = configuration_section[key].split(";")
+ if len(projecttopping_id_list) > 1:
+ self.workflow_wizard.log_panel.print_info(
+ self.tr(
+ "Only one projectopping allowed. Taking first one of the list."
+ ),
+ LogColor.COLOR_TOPPING,
+ )
+ return projecttopping_id_list[0]
+ return None
+
+ def _complete_completer(self):
+ if self.topping_line_edit.hasFocus() and self.topping_line_edit.completer():
+ if not self.topping_line_edit.text():
+ self.topping_line_edit.completer().setCompletionMode(
+ QCompleter.UnfilteredPopupCompletion
+ )
+ self.topping_line_edit.completer().complete()
+ else:
+ match_contains = (
+ self.topping_line_edit.completer()
+ .completionModel()
+ .match(
+ self.topping_line_edit.completer()
+ .completionModel()
+ .index(0, 0),
+ Qt.DisplayRole,
+ self.topping_line_edit.text(),
+ -1,
+ Qt.MatchContains,
+ )
+ )
+ if len(match_contains) > 1:
+ self.topping_line_edit.completer().setCompletionMode(
+ QCompleter.PopupCompletion
+ )
+ self.topping_line_edit.completer().complete()
+ self.topping_line_edit.completer().popup().scrollToTop()
+
+ def _on_completer_activated(self, text=None):
+ self._clean_topping()
+ if os.path.isfile(self.topping_line_edit.text()):
+ self.projecttopping_id = self.topping_line_edit.text()
+ self._set_topping_info(True)
+ self._enable_optimize_combo(False)
+ return
+
+ matches = self.ilitoppingcache.model.match(
+ self.ilitoppingcache.model.index(0, 0),
+ Qt.DisplayRole,
+ self.topping_line_edit.text(),
+ 1,
+ Qt.MatchExactly,
+ )
+ if matches:
+ model_index = matches[0]
+ self.projecttopping_id = f"ilidata:{self.ilitoppingcache.model.data(model_index, int(IliDataItemModel.Roles.ID))}"
+ self._set_topping_info(True, model_index)
+ self._enable_optimize_combo(False)
+ return
+
+ self._set_topping_info(not self.topping_line_edit.text())
+ self._enable_optimize_combo(True)
+
+ def _clean_topping(self):
+ self.projecttopping_id = None
+ self.topping_info.setText("")
+
+ def _set_topping_info(self, valid, index=None):
+ if self.projecttopping_id:
+ if index:
+ self.topping_info.setText(
+ self.tr(
+ "
Current project topping is: {} ({})
{}
"
+ ).format(
+ self.ilitoppingcache.model.data(index, Qt.DisplayRole),
+ self.projecttopping_id,
+ self.ilitoppingcache.model.data(
+ index, int(IliDataItemModel.Roles.SHORT_DESCRIPTION) or ""
+ ),
+ )
+ )
+ else:
+ self.topping_info.setText(
+ self.tr(
+ "Current project topping is: {}
"
+ ).format(self.projecttopping_id)
+ )
+
+ self.topping_info.setStyleSheet(f"color: {LogColor.COLOR_TOPPING}")
+
+ self.topping_line_edit.setStyleSheet(
+ "QLineEdit {{ background-color: {} }}".format(
+ "#ffffff" if valid else "#ffd356"
+ )
+ )
+
+ def _modelnames(self):
+ modelnames = []
+ db_models = self.db_connector.get_models()
+ regex = re.compile(r"(?:\{[^\}]*\}|\s)")
+ for db_model in db_models:
+ for modelname in regex.split(db_model["modelname"]):
+ name = modelname.strip()
+ if (
+ name
+ and name not in TRANSFERFILE_MODELS_BLACKLIST
+ and name not in modelnames
+ ):
+ modelnames.append(name)
+ return modelnames
def _create_project(self):
self.progress_bar.setValue(0)
@@ -167,117 +440,92 @@ def _create_project(self):
mapthemes = {}
resolved_layouts = {}
custom_variables = {}
+ transaction_mode = None
- # Project topping file for legend and layers: collect and download
- projecttopping_file_path_list = []
- if (
- self.configuration.metaconfig
- and "CONFIGURATION" in self.configuration.metaconfig.sections()
- ):
- configuration_section = self.configuration.metaconfig["CONFIGURATION"]
- # get topping referenced in qgis.modelbaker.projecttopping
- key = "qgis.modelbaker.projecttopping"
- if key not in configuration_section:
- key = "qgis.modelbaker.layertree"
- self.workflow_wizard.log_panel.print_info(
- self.tr(
- 'Keyword "qgis.modelbaker.layertree" is deprecated (but still working). Use "qgis.modelbaker.projecttopping" instead.'
- ),
- LogColor.COLOR_TOPPING,
- )
+ if self.projecttopping_id:
+ # Project topping file for legend and layers: collect and download
+ projecttopping_file_path = self.ilidata_path_resolver(
+ "", self.projecttopping_id
+ )
- if key in configuration_section:
+ if projecttopping_file_path:
self.workflow_wizard.log_panel.print_info(
- self.tr("Metaconfig contains a project topping."),
+ self.tr("Parse project topping file {}…").format(
+ projecttopping_file_path
+ ),
LogColor.COLOR_TOPPING,
)
- projecttopping_data_list = configuration_section[key].split(";")
- projecttopping_file_path_list = (
- self.workflow_wizard.get_topping_file_list(projecttopping_data_list)
- )
-
- if len(projecttopping_file_path_list) > 1:
- self.workflow_wizard.log_panel.print_info(
- self.tr(
- "Multiple project toppings can lead to unexpected behavior, when the sections are not clearly separated."
- ),
- LogColor.COLOR_TOPPING,
- )
-
- for projecttopping_file_path in projecttopping_file_path_list:
- self.workflow_wizard.log_panel.print_info(
- self.tr("Parse project topping file {}…").format(
- projecttopping_file_path
- ),
- LogColor.COLOR_TOPPING,
- )
- with open(projecttopping_file_path) as stream:
- try:
- projecttopping_data = yaml.safe_load(stream)
-
- # layertree / legend
- layertree_key = "layertree"
- if layertree_key not in projecttopping_data:
- layertree_key = "legend"
- self.workflow_wizard.log_panel.print_info(
- self.tr(
- 'Keyword "legend" is deprecated (but still working).. Use "layertree" instead.'
- ),
- LogColor.COLOR_TOPPING,
- )
- if layertree_key in projecttopping_data:
- legend = generator.legend(
- available_layers,
- layertree_structure=projecttopping_data[layertree_key],
- path_resolver=lambda path: self.ilidata_path_resolver(
- os.path.dirname(projecttopping_file_path), path
+ with open(projecttopping_file_path) as stream:
+ try:
+ projecttopping_data = yaml.safe_load(stream)
+
+ # layertree / legend
+ layertree_key = "layertree"
+ if layertree_key not in projecttopping_data:
+ layertree_key = "legend"
+ self.workflow_wizard.log_panel.print_info(
+ self.tr(
+ 'Keyword "legend" is deprecated (but still working).. Use "layertree" instead.'
+ ),
+ LogColor.COLOR_TOPPING,
+ )
+ if layertree_key in projecttopping_data:
+ legend = generator.legend(
+ available_layers,
+ layertree_structure=projecttopping_data[layertree_key],
+ path_resolver=lambda path: self.ilidata_path_resolver(
+ os.path.dirname(projecttopping_file_path), path
+ )
+ if path
+ else None,
)
- if path
- else None,
- )
- # layer order
- layerorder_key = "layerorder"
- if layerorder_key not in projecttopping_data:
- layerorder_key = "layer-order"
-
- if layerorder_key in projecttopping_data:
- custom_layer_order_structure = projecttopping_data[
- layerorder_key
- ]
-
- # map themes
- if "mapthemes" in projecttopping_data:
- mapthemes = projecttopping_data["mapthemes"]
-
- # layouts
- if "layouts" in projecttopping_data:
- resolved_layouts = generator.resolved_layouts(
- projecttopping_data["layouts"],
- path_resolver=lambda path: self.ilidata_path_resolver(
- os.path.dirname(projecttopping_file_path), path
+ # layer order
+ layerorder_key = "layerorder"
+ if layerorder_key not in projecttopping_data:
+ layerorder_key = "layer-order"
+
+ if layerorder_key in projecttopping_data:
+ custom_layer_order_structure = projecttopping_data[
+ layerorder_key
+ ]
+
+ # map themes
+ if "mapthemes" in projecttopping_data:
+ mapthemes = projecttopping_data["mapthemes"]
+
+ # layouts
+ if "layouts" in projecttopping_data:
+ resolved_layouts = generator.resolved_layouts(
+ projecttopping_data["layouts"],
+ path_resolver=lambda path: self.ilidata_path_resolver(
+ os.path.dirname(projecttopping_file_path), path
+ )
+ if path
+ else None,
)
- if path
- else None,
- )
- # variables
- if "variables" in projecttopping_data:
- custom_variables = projecttopping_data["variables"]
+ # variables
+ if "variables" in projecttopping_data:
+ custom_variables = projecttopping_data["variables"]
- # properties (inoffical)
- if "properties" in projecttopping_data:
- custom_project_properties = projecttopping_data["properties"]
+ # properties (inoffical)
+ if "properties" in projecttopping_data:
+ custom_project_properties = projecttopping_data[
+ "properties"
+ ]
- except yaml.YAMLError as exc:
- self.workflow_wizard.log_panel.print_info(
- self.tr("Unable to parse project topping: {}").format(exc),
- LogColor.COLOR_TOPPING,
- )
+ except yaml.YAMLError as exc:
+ self.workflow_wizard.log_panel.print_info(
+ self.tr("Unable to parse project topping: {}").format(exc),
+ LogColor.COLOR_TOPPING,
+ )
- self.progress_bar.setValue(55)
+ self.progress_bar.setValue(55)
- transaction_mode = custom_project_properties.get("transaction_mode", None)
+ transaction_mode = custom_project_properties.get(
+ "transaction_mode", None
+ )
if Qgis.QGIS_VERSION_INT < 32600:
# pass transaction_mode as boolean
diff --git a/QgisModelBaker/ui/workflow_wizard/project_creation.ui b/QgisModelBaker/ui/workflow_wizard/project_creation.ui
index 5e0c435d7..d93d27753 100644
--- a/QgisModelBaker/ui/workflow_wizard/project_creation.ui
+++ b/QgisModelBaker/ui/workflow_wizard/project_creation.ui
@@ -14,61 +14,79 @@
Select Files
- -
-
+
-
+
- Qt::Vertical
+ Qt::Horizontal
- 20
- 40
+ 40
+ 20
- -
-
-
-
- 0
- 0
-
-
-
- <html><head/><body><p><span style=" font-weight:600;">Hide unused base class layers:</span></p><p>- Base class layers with same named extensions will be <span style=" font-style:italic;">hidden</span> and and base class layers with multiple extensions as well. Except if the extension is in the same model, then it's will <span style=" font-style:italic;">not</span> be <span style=" font-style:italic;">hidden</span> but <span style=" font-style:italic;">renamed</span>.</p><p>- Relations of hidden layers will <span style=" font-style:italic;">not</span> be <span style=" font-style:italic;">created</span> and with them <span style=" font-style:italic;">no</span> widgets<br/></p><p><span style=" font-weight:600;">Group unused base class layers:</span></p><p>- Base class layers with same named extensions will be <span style=" font-style:italic;">collected in a group</span> and base class layers with multiple extensions as well. Except if the extension is in the same model, then it's will <span style=" font-style:italic;">not</span> be <span style=" font-style:italic;">grouped</span> but <span style=" font-style:italic;">renamed</span>.</p><p>- Relations of grouped layers will be <span style=" font-style:italic;">created</span> but the widgets <span style=" font-style:italic;">not applied</span> to the form.</p></body></html>
-
-
-
-
- Hide unused base class layers
-
-
- -
-
- Group unused base class layers
-
-
- -
-
- No optimization
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- <html><head/><body><p>If you don't get it - nevermind and keep the default. If it's not like expected - try again with 'No optimization'...</p></body></html>
-
-
- Project optimization strategy concerning inheritances
-
+
-
+
+
+
+
+
+ false
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Project Topping
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Use existing project topping
+
+
+
+ -
+
+
+ Browse Interlis files
+
+
+ …
+
+
+
+ -
+
+
+ TextLabel
+
+
+ true
+
+
+
+
-
@@ -96,35 +114,96 @@
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
+
-
+
+
+ 0
-
+
+
+ -
+
+
+
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ <html><head/><body><p>If you don't get it - nevermind and keep the default. If it's not like expected - try again with 'No optimization'...</p></body></html>
+
+
+ Project optimization strategy concerning inheritances
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ <html><head/><body><p><span style=" font-weight:600;">Hide unused base class layers:</span></p><p>- Base class layers with same named extensions will be <span style=" font-style:italic;">hidden</span> and and base class layers with multiple extensions as well. Except if the extension is in the same model, then it's will <span style=" font-style:italic;">not</span> be <span style=" font-style:italic;">hidden</span> but <span style=" font-style:italic;">renamed</span>.</p><p>- Relations of hidden layers will <span style=" font-style:italic;">not</span> be <span style=" font-style:italic;">created</span> and with them <span style=" font-style:italic;">no</span> widgets<br/></p><p><span style=" font-weight:600;">Group unused base class layers:</span></p><p>- Base class layers with same named extensions will be <span style=" font-style:italic;">collected in a group</span> and base class layers with multiple extensions as well. Except if the extension is in the same model, then it's will <span style=" font-style:italic;">not</span> be <span style=" font-style:italic;">grouped</span> but <span style=" font-style:italic;">renamed</span>.</p><p>- Relations of grouped layers will be <span style=" font-style:italic;">created</span> but the widgets <span style=" font-style:italic;">not applied</span> to the form.</p></body></html>
+
+
-
+
+ Hide unused base class layers
+
+
+ -
+
+ Group unused base class layers
+
+
+ -
+
+ No optimization
+
+
+
+
+
+
- -
+
-
Generate
- -
-
-
- 0
+
-
+
+
+ Qt::Vertical
-
+
+
+ 20
+ 40
+
+
+
+
+
+ CompletionLineEdit
+
+ QgisModelBaker.utils.gui_utils
+ 1
+
+
From 8b6c9689f42fba881738fc231ee292fc216a4189 Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 14:20:36 +0100
Subject: [PATCH 2/9] keep it disabled when searching for reference data
---
.../gui/workflow_wizard/default_baskets_page.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py b/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
index 981cb5beb..1acfcb081 100644
--- a/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
@@ -52,9 +52,6 @@ def isComplete(self):
def setComplete(self, complete):
self.is_complete = complete
- self.create_default_baskets_button.setDisabled(complete)
- self.skip_button.setDisabled(complete)
- self.baskets_panel.setDisabled(complete)
self.completeChanged.emit()
def nextId(self):
@@ -88,6 +85,9 @@ def _create_default_baskets(self):
self.progress_bar.setFormat(self.tr("Default baskets created!"))
self.progress_bar.setValue(100)
self.setStyleSheet(gui_utils.SUCCESS_STYLE)
+ self.create_default_baskets_button.setDisabled(True)
+ self.skip_button.setDisabled(True)
+ self.baskets_panel.setDisabled(True)
self.setComplete(True)
else:
self.workflow_wizard.log_panel.print_info(message)
@@ -103,4 +103,7 @@ def _skip(self):
self.progress_bar.setFormat(self.tr("SKIPPED"))
self.progress_bar.setTextVisible(True)
self.setStyleSheet(gui_utils.INACTIVE_STYLE)
+ self.create_default_baskets_button.setDisabled(True)
+ self.skip_button.setDisabled(True)
+ self.baskets_panel.setDisabled(True)
self.setComplete(True)
From 451eb172de1d554bcc52580b33c6db856f1011f4 Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 16:28:52 +0100
Subject: [PATCH 3/9] finetuning on project create and prototype of progress
bar when loading 'something' kind of a busy indicator
---
QgisModelBaker/gui/panel/log_panel.py | 10 +++-
.../gui/workflow_wizard/execution_page.py | 7 +++
.../import_schema_configuration_page.py | 17 +++++-
.../workflow_wizard/project_creation_page.py | 52 ++++++++++++++-----
.../gui/workflow_wizard/workflow_wizard.py | 27 +++++++++-
.../ui/workflow_wizard/project_creation.ui | 29 ++++++-----
6 files changed, 113 insertions(+), 29 deletions(-)
diff --git a/QgisModelBaker/gui/panel/log_panel.py b/QgisModelBaker/gui/panel/log_panel.py
index 2e29757f8..bad6b0070 100644
--- a/QgisModelBaker/gui/panel/log_panel.py
+++ b/QgisModelBaker/gui/panel/log_panel.py
@@ -19,7 +19,7 @@
import logging
-from PyQt5.QtWidgets import QGridLayout
+from PyQt5.QtWidgets import QGridLayout, QProgressBar
from qgis.core import Qgis
from qgis.gui import QgsMessageBar
from qgis.PyQt.QtCore import QSize, Qt
@@ -40,9 +40,17 @@ def __init__(self, parent=None):
self.txtStdout.setLayout(QGridLayout())
self.txtStdout.layout().setContentsMargins(0, 0, 0, 0)
self.txtStdout.layout().addWidget(self.bar, 0, 0, Qt.AlignTop)
+ self.scrollbar = self.txtStdout.verticalScrollBar()
+
+ self.busy_bar = QProgressBar()
+ self.busy_bar.setRange(0, 0)
+ self.busy_bar.setTextVisible(True)
+ self.busy_bar.setVisible(False)
layout = QGridLayout()
layout.addWidget(self.txtStdout)
+ layout.addWidget(self.busy_bar)
+
self.setLayout(layout)
def sizeHint(self):
diff --git a/QgisModelBaker/gui/workflow_wizard/execution_page.py b/QgisModelBaker/gui/workflow_wizard/execution_page.py
index f184f92ac..2b5a5eddf 100644
--- a/QgisModelBaker/gui/workflow_wizard/execution_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/execution_page.py
@@ -195,3 +195,10 @@ def _on_process_finished(self, exit_code, result):
message = self.tr("Finished with errors!")
self.workflow_wizard.log_panel.print_info(message, color)
+
+ def busy(self, busy, text=None):
+ self.setEnabled(not busy)
+ if busy:
+ self.workflow_wizard.start_busy_bar(text)
+ else:
+ self.workflow_wizard.stop_busy_bar()
diff --git a/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py b/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py
index 8d0eb1a43..956ff3b6c 100644
--- a/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py
@@ -185,6 +185,7 @@ def _update_ilimetaconfigcache(self):
self.ilimetaconfigcache.model_refreshed.connect(
self._update_metaconfig_completer
)
+ self.busy(True, self.tr("Refresh repository data..."))
self._refresh_ili_metaconfig_cache()
def _update_ilireferencedatacache(self):
@@ -289,6 +290,7 @@ def _update_metaconfig_completer(self, rows):
completer.popup().setItemDelegate(self.metaconfig_delegate)
self.ili_metaconfig_line_edit.setCompleter(completer)
self.ili_metaconfig_line_edit.setEnabled(bool(rows))
+ self.busy(False)
def _on_metaconfig_completer_activated(self, text=None):
self._clean_metaconfig()
@@ -315,8 +317,9 @@ def _on_metaconfig_completer_activated(self, text=None):
self.ilimetaconfigcache.model.data(model_index, Qt.DisplayRole),
metaconfig_id,
self.ilimetaconfigcache.model.data(
- model_index, int(IliDataItemModel.Roles.SHORT_DESCRIPTION) or ""
- ),
+ model_index, int(IliDataItemModel.Roles.SHORT_DESCRIPTION)
+ )
+ or "",
)
)
self.metaconfig_file_info_label.setStyleSheet("color: #341d5c")
@@ -433,6 +436,7 @@ def _load_crs_from_metaconfig(self, ili2db_metaconfig):
self._crs_changed()
def _load_metaconfig(self):
+ self.busy(True, "Load metaconfiguration...")
# load ili2db parameters to the GUI
if "ch.ehi.ili2db" in self.metaconfig.sections():
self.workflow_wizard.log_panel.print_info(
@@ -570,3 +574,12 @@ def _load_metaconfig(self):
LogColor.COLOR_TOPPING,
)
self.workflow_wizard.refresh_import_models()
+
+ self.busy(False)
+
+ def busy(self, busy, text=None):
+ self.setEnabled(not busy)
+ if busy:
+ self.workflow_wizard.start_busy_bar(text)
+ else:
+ self.workflow_wizard.stop_busy_bar()
diff --git a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
index cea3b14af..dba76e769 100644
--- a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
@@ -113,7 +113,10 @@ def setComplete(self, complete):
self.completeChanged.emit()
def restore_configuration(self, configuration):
- self.setEnabled(False)
+ self.busy(
+ True,
+ self.tr("Restoring configuration and check existing metaconfigfile..."),
+ )
self.configuration = configuration
self.db_connector = db_utils.get_db_connector(self.configuration)
@@ -126,7 +129,7 @@ def restore_configuration(self, configuration):
self.existing_topping_checkbox.setChecked(True)
else:
self._use_existing(False)
- self.setEnabled(True)
+ self.busy(False)
def _use_existing(self, state):
# triggered by checked state...
@@ -139,14 +142,26 @@ def _use_existing(self, state):
self._set_topping_info(True)
else:
self._clean_topping()
- models = ";".join(self._modelnames())
self.ilitoppingcache = IliDataCache(
- self.configuration.base_configuration, "projecttopping", models
+ self.configuration.base_configuration,
+ type="projecttopping",
+ models=";".join(self._modelnames()),
+ datasources=["pg"]
+ if (
+ self.workflow_wizard.import_schema_configuration.tool & DbIliMode.pg
+ )
+ else ["gpkg"]
+ if (
+ self.workflow_wizard.import_schema_configuration.tool
+ & DbIliMode.gpkg
+ )
+ else None,
)
self.ilitoppingcache.new_message.connect(
self.workflow_wizard.log_panel.show_message
)
- # wait before activating untill end of refreshment
+ # wait before activating until end of refreshment
+ self.busy(True, self.tr("Refresh repository data..."))
self.ilitoppingcache.model_refreshed.connect(
lambda: self._enable_topping_selection(True)
)
@@ -174,6 +189,7 @@ def _enable_topping_selection(self, state):
self.topping_line_edit.setEnabled(state)
self.topping_line_label.setEnabled(state)
self.topping_info.setEnabled(state)
+ self.busy(False)
def _enable_optimize_combo(self, state):
self.optimize_combo.setEnabled(state)
@@ -307,21 +323,26 @@ def _clean_topping(self):
def _set_topping_info(self, valid, index=None):
if self.projecttopping_id:
if index:
+ if self.existing_topping_checkbox.isChecked():
+ info = self.tr(
+ "Project topping received according to the id found in the database or selected previously"
+ )
+ else:
+ info = self.tr("Project topping received according selection")
self.topping_info.setText(
- self.tr(
- "Current project topping is: {} ({})
{}
"
- ).format(
- self.ilitoppingcache.model.data(index, Qt.DisplayRole),
+ "{} ({})
{}
".format(
+ info,
self.projecttopping_id,
self.ilitoppingcache.model.data(
- index, int(IliDataItemModel.Roles.SHORT_DESCRIPTION) or ""
- ),
+ index, int(IliDataItemModel.Roles.SHORT_DESCRIPTION)
+ )
+ or "",
)
)
else:
self.topping_info.setText(
self.tr(
- "Current project topping is: {}
"
+ "Project topping from file {}
"
).format(self.projecttopping_id)
)
@@ -638,3 +659,10 @@ def ilidata_path_resolver(self, base_path, path):
data_file_path_list = self.workflow_wizard.get_topping_file_list([path])
return data_file_path_list[0] if data_file_path_list else None
return os.path.join(base_path, path)
+
+ def busy(self, busy, text=None):
+ self.setEnabled(not busy)
+ if busy:
+ self.workflow_wizard.start_busy_bar(text)
+ else:
+ self.workflow_wizard.stop_busy_bar()
diff --git a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
index b446ed079..2f67d2a25 100644
--- a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
+++ b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
@@ -59,6 +59,7 @@
IliToppingFileCache,
)
from QgisModelBaker.libs.modelbaker.utils.globals import DbActionType
+from QgisModelBaker.utils import gui_utils
from QgisModelBaker.utils.gui_utils import (
FileDropListView,
ImportDataModel,
@@ -271,6 +272,9 @@ def next_id(self):
"Checking for potential referenced data on the repositories (might take a while)..."
)
)
+ self.schema_configuration_page.busy(
+ True, self.tr("Checking for potential referenced data...")
+ )
self.schema_configuration_page.setComplete(False)
if (
self.import_data_file_model.rowCount()
@@ -283,6 +287,7 @@ def next_id(self):
self.tr("Potential referenced data found.")
)
self.schema_configuration_page.setComplete(True)
+ self.schema_configuration_page.busy(False)
return PageIds.ImportDataConfiguration
else:
self.log_panel.print_info(
@@ -291,6 +296,7 @@ def next_id(self):
)
)
self.schema_configuration_page.setComplete(True)
+ self.schema_configuration_page.busy(False)
if self.current_id == PageIds.ImportSchemaExecution:
# if basket handling active, go to the create basket
@@ -307,6 +313,9 @@ def next_id(self):
"Checking for potential referenced data on the repositories (might take a while)..."
)
)
+ self.import_schema_execution_page.busy(
+ True, self.tr("Checking for potential referenced data...")
+ )
self.import_schema_execution_page.setComplete(False)
if self.update_referecedata_cache_model(
self._db_modelnames(self.import_data_configuration),
@@ -316,8 +325,10 @@ def next_id(self):
self.tr("Potential referenced data found.")
)
self.import_schema_execution_page.setComplete(True)
+ self.import_schema_execution_page.busy(False)
return PageIds.ImportDataConfiguration
self.import_schema_execution_page.setComplete(True)
+ self.import_schema_execution_page.busy(False)
# otherwise, go to project create
return PageIds.ProjectCreation
@@ -334,6 +345,9 @@ def next_id(self):
)
)
self.default_baskets_page.setComplete(False)
+ self.ddefault_baskets_page.busy(
+ True, self.tr("Checking for potential referenced data...")
+ )
if self.update_referecedata_cache_model(
self._db_modelnames(self.import_data_configuration),
"referenceData",
@@ -342,8 +356,10 @@ def next_id(self):
self.tr("Potential referenced data found.")
)
self.default_baskets_page.setComplete(True)
+ self.default_baskets_page.busy(False)
return PageIds.ImportDataConfiguration
self.default_baskets_page.setComplete(True)
+ self.default_baskets_page.busy(False)
# otherwise, go to project create
return PageIds.ProjectCreation
@@ -670,10 +686,19 @@ def append_dropped_files(self, dropped_files, dropped_ini_files):
dropped_ini_files[0]
)
+ def start_busy_bar(self, text="Loading..."):
+ self.log_panel.busy_bar.setFormat(text)
+ self.log_panel.busy_bar.setVisible(True)
+
+ def stop_busy_bar(self):
+ self.log_panel.busy_bar.setVisible(False)
+ self.log_panel.scrollbar.setValue(self.log_panel.scrollbar.maximum())
+
class WorkflowWizardDialog(QDialog):
def __init__(self, iface, base_config, parent):
QDialog.__init__(self, parent)
+ self.setStyleSheet(gui_utils.DEFAULT_STYLE)
self.iface = iface
self.base_config = base_config
@@ -683,8 +708,8 @@ def __init__(self, iface, base_config, parent):
self.workflow_wizard.setStartId(PageIds.Intro)
self.workflow_wizard.setWindowFlags(Qt.Widget)
self.workflow_wizard.show()
-
self.workflow_wizard.finished.connect(self.done)
+
layout = QVBoxLayout()
splitter = QSplitter(Qt.Vertical)
splitter.addWidget(self.workflow_wizard)
diff --git a/QgisModelBaker/ui/workflow_wizard/project_creation.ui b/QgisModelBaker/ui/workflow_wizard/project_creation.ui
index d93d27753..4478ecc5f 100644
--- a/QgisModelBaker/ui/workflow_wizard/project_creation.ui
+++ b/QgisModelBaker/ui/workflow_wizard/project_creation.ui
@@ -61,6 +61,9 @@
-
+
+ <html><head/><body><p>A project topping is already given by the previous metaconfiguration selection or via the metaconfiguration id stored in the database. Uncheck, when you want to choose another project topping file.</p></body></html>
+
Use existing project topping
@@ -114,6 +117,19 @@
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
-
@@ -181,19 +197,6 @@
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
From 0127020deba18c615a04cd98d69779cd858c64e8 Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 16:41:54 +0100
Subject: [PATCH 4/9] fix typo
---
QgisModelBaker/gui/workflow_wizard/workflow_wizard.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
index 2f67d2a25..6c0a2cc2b 100644
--- a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
+++ b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
@@ -345,7 +345,7 @@ def next_id(self):
)
)
self.default_baskets_page.setComplete(False)
- self.ddefault_baskets_page.busy(
+ self.default_baskets_page.busy(
True, self.tr("Checking for potential referenced data...")
)
if self.update_referecedata_cache_model(
From 6282a2dde1f034d11314fc0bb82352292e7b2231 Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 17:02:49 +0100
Subject: [PATCH 5/9] cleanup
---
.../workflow_wizard/project_creation_page.py | 181 +++++++++---------
1 file changed, 91 insertions(+), 90 deletions(-)
diff --git a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
index dba76e769..294cfd74b 100644
--- a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
@@ -124,22 +124,23 @@ def restore_configuration(self, configuration):
self.existing_topping_checkbox.setVisible(False)
self.existing_projecttopping_id = self._existing_projecttopping_id()
if self.existing_projecttopping_id:
- self.tr("Use existing project topping {}").format(self.projecttopping_id)
self.existing_topping_checkbox.setVisible(True)
+ # with setting it checked _use_existing is called
self.existing_topping_checkbox.setChecked(True)
else:
self._use_existing(False)
self.busy(False)
def _use_existing(self, state):
- # triggered by checked state...
+ # triggered by checked state.
if state:
self._clean_topping()
- self.topping_line_edit.setText("")
- self._enable_topping_selection(False)
- self._enable_optimize_combo(False)
self.projecttopping_id = self.existing_projecttopping_id
self._set_topping_info(True)
+ # disable other widgets
+ self._enable_topping_selection(False)
+ self._enable_optimize_combo(False)
+ self.topping_line_edit.setText("")
else:
self._clean_topping()
self.ilitoppingcache = IliDataCache(
@@ -165,7 +166,6 @@ def _use_existing(self, state):
self.ilitoppingcache.model_refreshed.connect(
lambda: self._enable_topping_selection(True)
)
- self._enable_optimize_combo(True)
self.ilitoppingcache.refresh()
completer = QCompleter(
@@ -179,7 +179,6 @@ def _use_existing(self, state):
completer.setFilterMode(Qt.MatchContains)
completer.popup().setItemDelegate(self.ilitopping_delegate)
self.topping_line_edit.setCompleter(completer)
- self._enable_optimize_combo(True)
def _enable_topping_selection(self, state):
# doublecheck if meanwhile user checked box again
@@ -189,80 +188,14 @@ def _enable_topping_selection(self, state):
self.topping_line_edit.setEnabled(state)
self.topping_line_label.setEnabled(state)
self.topping_info.setEnabled(state)
+
+ self._enable_optimize_combo(state)
self.busy(False)
def _enable_optimize_combo(self, state):
self.optimize_combo.setEnabled(state)
self.optimize_label.setEnabled(state)
- def _datasource_metaconfig(self):
- metaconfig_id = None
- setting_records = self.db_connector.get_ili2db_settings()
- for setting_record in setting_records:
- if setting_record["tag"] == "ch.ehi.ili2db.metaConfigFileName":
- metaconfig_id = setting_record["setting"]
- break
- if metaconfig_id:
- metaconfig_file_path_list = self.workflow_wizard.get_topping_file_list(
- [metaconfig_id]
- )
-
- if not metaconfig_file_path_list:
- self.workflow_wizard.log_panel.print_info(
- self.tr(
- "Found a metaconfig-id ({}) in the data source, but no corresponding metaconfig in the repositories."
- ).format(metaconfig_id),
- LogColor.COLOR_TOPPING,
- )
- return None
-
- metaconfig = configparser.ConfigParser()
- with open(metaconfig_file_path_list[0]) as metaconfig_file:
- metaconfig.read_file(metaconfig_file)
- return metaconfig
-
- return None
-
- def _existing_projecttopping_id(self):
- metaconfig = self.configuration.metaconfig
-
- if not metaconfig:
- metaconfig = self._datasource_metaconfig()
-
- if not metaconfig:
- # no existing metaconfig available
- return None
-
- # get projecttopping_id from metaconfig
- if "CONFIGURATION" in metaconfig.sections():
- configuration_section = metaconfig["CONFIGURATION"]
- # get topping referenced in qgis.modelbaker.projecttopping
- key = "qgis.modelbaker.projecttopping"
- if key not in configuration_section:
- key = "qgis.modelbaker.layertree"
- self.workflow_wizard.log_panel.print_info(
- self.tr(
- 'Keyword "qgis.modelbaker.layertree" is deprecated (but still working). Use "qgis.modelbaker.projecttopping" instead.'
- ),
- LogColor.COLOR_TOPPING,
- )
-
- if key in configuration_section:
- self.workflow_wizard.log_panel.print_info(
- self.tr("Metaconfig contains a project topping."),
- LogColor.COLOR_TOPPING,
- )
- projecttopping_id_list = configuration_section[key].split(";")
- if len(projecttopping_id_list) > 1:
- self.workflow_wizard.log_panel.print_info(
- self.tr(
- "Only one projectopping allowed. Taking first one of the list."
- ),
- LogColor.COLOR_TOPPING,
- )
- return projecttopping_id_list[0]
- return None
-
def _complete_completer(self):
if self.topping_line_edit.hasFocus() and self.topping_line_edit.completer():
if not self.topping_line_edit.text():
@@ -354,21 +287,6 @@ def _set_topping_info(self, valid, index=None):
)
)
- def _modelnames(self):
- modelnames = []
- db_models = self.db_connector.get_models()
- regex = re.compile(r"(?:\{[^\}]*\}|\s)")
- for db_model in db_models:
- for modelname in regex.split(db_model["modelname"]):
- name = modelname.strip()
- if (
- name
- and name not in TRANSFERFILE_MODELS_BLACKLIST
- and name not in modelnames
- ):
- modelnames.append(name)
- return modelnames
-
def _create_project(self):
self.progress_bar.setValue(0)
@@ -660,6 +578,89 @@ def ilidata_path_resolver(self, base_path, path):
return data_file_path_list[0] if data_file_path_list else None
return os.path.join(base_path, path)
+ def _datasource_metaconfig(self):
+ metaconfig_id = None
+ setting_records = self.db_connector.get_ili2db_settings()
+ for setting_record in setting_records:
+ if setting_record["tag"] == "ch.ehi.ili2db.metaConfigFileName":
+ metaconfig_id = setting_record["setting"]
+ break
+ if metaconfig_id:
+ metaconfig_file_path_list = self.workflow_wizard.get_topping_file_list(
+ [metaconfig_id]
+ )
+
+ if not metaconfig_file_path_list:
+ self.workflow_wizard.log_panel.print_info(
+ self.tr(
+ "Found a metaconfig-id ({}) in the data source, but no corresponding metaconfig in the repositories."
+ ).format(metaconfig_id),
+ LogColor.COLOR_TOPPING,
+ )
+ return None
+
+ metaconfig = configparser.ConfigParser()
+ with open(metaconfig_file_path_list[0]) as metaconfig_file:
+ metaconfig.read_file(metaconfig_file)
+ return metaconfig
+
+ return None
+
+ def _existing_projecttopping_id(self):
+ metaconfig = self.configuration.metaconfig
+
+ if not metaconfig:
+ metaconfig = self._datasource_metaconfig()
+
+ if not metaconfig:
+ # no existing metaconfig available
+ return None
+
+ # get projecttopping_id from metaconfig
+ if "CONFIGURATION" in metaconfig.sections():
+ configuration_section = metaconfig["CONFIGURATION"]
+ # get topping referenced in qgis.modelbaker.projecttopping
+ key = "qgis.modelbaker.projecttopping"
+ if key not in configuration_section:
+ key = "qgis.modelbaker.layertree"
+ self.workflow_wizard.log_panel.print_info(
+ self.tr(
+ 'Keyword "qgis.modelbaker.layertree" is deprecated (but still working). Use "qgis.modelbaker.projecttopping" instead.'
+ ),
+ LogColor.COLOR_TOPPING,
+ )
+
+ if key in configuration_section:
+ self.workflow_wizard.log_panel.print_info(
+ self.tr("Metaconfig contains a project topping."),
+ LogColor.COLOR_TOPPING,
+ )
+ projecttopping_id_list = configuration_section[key].split(";")
+ if len(projecttopping_id_list) > 1:
+ self.workflow_wizard.log_panel.print_info(
+ self.tr(
+ "Only one projectopping allowed. Taking first one of the list."
+ ),
+ LogColor.COLOR_TOPPING,
+ )
+ return projecttopping_id_list[0]
+ return None
+
+ def _modelnames(self):
+ modelnames = []
+ db_models = self.db_connector.get_models()
+ regex = re.compile(r"(?:\{[^\}]*\}|\s)")
+ for db_model in db_models:
+ for modelname in regex.split(db_model["modelname"]):
+ name = modelname.strip()
+ if (
+ name
+ and name not in TRANSFERFILE_MODELS_BLACKLIST
+ and name not in modelnames
+ ):
+ modelnames.append(name)
+ return modelnames
+
def busy(self, busy, text=None):
self.setEnabled(not busy)
if busy:
From 9858be7ae303c4d32c86b5cf930c227103c61170 Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 17:34:47 +0100
Subject: [PATCH 6/9] busy state on basket page
---
QgisModelBaker/gui/workflow_wizard/default_baskets_page.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py b/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
index 1acfcb081..1d9d36ff2 100644
--- a/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
@@ -107,3 +107,10 @@ def _skip(self):
self.skip_button.setDisabled(True)
self.baskets_panel.setDisabled(True)
self.setComplete(True)
+
+ def busy(self, busy, text=None):
+ self.setEnabled(not busy)
+ if busy:
+ self.workflow_wizard.start_busy_bar(text)
+ else:
+ self.workflow_wizard.stop_busy_bar()
From ef4410b6b80ccd9dbf9eae4b670606b86f09efaf Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 17:42:51 +0100
Subject: [PATCH 7/9] move busy functionality to workflowwizard and pass the
page
---
.../workflow_wizard/default_baskets_page.py | 7 ---
.../import_schema_configuration_page.py | 15 ++-----
.../workflow_wizard/project_creation_page.py | 16 +++----
.../gui/workflow_wizard/workflow_wizard.py | 45 +++++++++++--------
4 files changed, 35 insertions(+), 48 deletions(-)
diff --git a/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py b/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
index 1d9d36ff2..1acfcb081 100644
--- a/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/default_baskets_page.py
@@ -107,10 +107,3 @@ def _skip(self):
self.skip_button.setDisabled(True)
self.baskets_panel.setDisabled(True)
self.setComplete(True)
-
- def busy(self, busy, text=None):
- self.setEnabled(not busy)
- if busy:
- self.workflow_wizard.start_busy_bar(text)
- else:
- self.workflow_wizard.stop_busy_bar()
diff --git a/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py b/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py
index 956ff3b6c..c77b205b5 100644
--- a/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py
@@ -185,7 +185,7 @@ def _update_ilimetaconfigcache(self):
self.ilimetaconfigcache.model_refreshed.connect(
self._update_metaconfig_completer
)
- self.busy(True, self.tr("Refresh repository data..."))
+ self.workflow_wizard.busy(self, True, self.tr("Refresh repository data..."))
self._refresh_ili_metaconfig_cache()
def _update_ilireferencedatacache(self):
@@ -290,7 +290,7 @@ def _update_metaconfig_completer(self, rows):
completer.popup().setItemDelegate(self.metaconfig_delegate)
self.ili_metaconfig_line_edit.setCompleter(completer)
self.ili_metaconfig_line_edit.setEnabled(bool(rows))
- self.busy(False)
+ self.workflow_wizard.busy(self, False)
def _on_metaconfig_completer_activated(self, text=None):
self._clean_metaconfig()
@@ -436,7 +436,7 @@ def _load_crs_from_metaconfig(self, ili2db_metaconfig):
self._crs_changed()
def _load_metaconfig(self):
- self.busy(True, "Load metaconfiguration...")
+ self.workflow_wizard.busy(self, True, "Load metaconfiguration...")
# load ili2db parameters to the GUI
if "ch.ehi.ili2db" in self.metaconfig.sections():
self.workflow_wizard.log_panel.print_info(
@@ -575,11 +575,4 @@ def _load_metaconfig(self):
)
self.workflow_wizard.refresh_import_models()
- self.busy(False)
-
- def busy(self, busy, text=None):
- self.setEnabled(not busy)
- if busy:
- self.workflow_wizard.start_busy_bar(text)
- else:
- self.workflow_wizard.stop_busy_bar()
+ self.workflow_wizard.busy(self, False)
diff --git a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
index 294cfd74b..65b2c6643 100644
--- a/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/project_creation_page.py
@@ -113,7 +113,8 @@ def setComplete(self, complete):
self.completeChanged.emit()
def restore_configuration(self, configuration):
- self.busy(
+ self.workflow_wizard.busy(
+ self,
True,
self.tr("Restoring configuration and check existing metaconfigfile..."),
)
@@ -129,7 +130,7 @@ def restore_configuration(self, configuration):
self.existing_topping_checkbox.setChecked(True)
else:
self._use_existing(False)
- self.busy(False)
+ self.workflow_wizard.busy(self, False)
def _use_existing(self, state):
# triggered by checked state.
@@ -162,7 +163,7 @@ def _use_existing(self, state):
self.workflow_wizard.log_panel.show_message
)
# wait before activating until end of refreshment
- self.busy(True, self.tr("Refresh repository data..."))
+ self.workflow_wizard.busy(self, True, self.tr("Refresh repository data..."))
self.ilitoppingcache.model_refreshed.connect(
lambda: self._enable_topping_selection(True)
)
@@ -190,7 +191,7 @@ def _enable_topping_selection(self, state):
self.topping_info.setEnabled(state)
self._enable_optimize_combo(state)
- self.busy(False)
+ self.workflow_wizard.busy(self, False)
def _enable_optimize_combo(self, state):
self.optimize_combo.setEnabled(state)
@@ -660,10 +661,3 @@ def _modelnames(self):
):
modelnames.append(name)
return modelnames
-
- def busy(self, busy, text=None):
- self.setEnabled(not busy)
- if busy:
- self.workflow_wizard.start_busy_bar(text)
- else:
- self.workflow_wizard.stop_busy_bar()
diff --git a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
index 6c0a2cc2b..3292c91a0 100644
--- a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
+++ b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
@@ -272,8 +272,10 @@ def next_id(self):
"Checking for potential referenced data on the repositories (might take a while)..."
)
)
- self.schema_configuration_page.busy(
- True, self.tr("Checking for potential referenced data...")
+ self.busy(
+ self.schema_configuration_page,
+ True,
+ self.tr("Checking for potential referenced data..."),
)
self.schema_configuration_page.setComplete(False)
if (
@@ -287,7 +289,7 @@ def next_id(self):
self.tr("Potential referenced data found.")
)
self.schema_configuration_page.setComplete(True)
- self.schema_configuration_page.busy(False)
+ self.busy(self.schema_configuration_page, False)
return PageIds.ImportDataConfiguration
else:
self.log_panel.print_info(
@@ -296,7 +298,7 @@ def next_id(self):
)
)
self.schema_configuration_page.setComplete(True)
- self.schema_configuration_page.busy(False)
+ self.busy(self.schema_configuration_page, False)
if self.current_id == PageIds.ImportSchemaExecution:
# if basket handling active, go to the create basket
@@ -313,8 +315,10 @@ def next_id(self):
"Checking for potential referenced data on the repositories (might take a while)..."
)
)
- self.import_schema_execution_page.busy(
- True, self.tr("Checking for potential referenced data...")
+ self.busy(
+ self.import_schema_execution_page,
+ True,
+ self.tr("Checking for potential referenced data..."),
)
self.import_schema_execution_page.setComplete(False)
if self.update_referecedata_cache_model(
@@ -325,10 +329,10 @@ def next_id(self):
self.tr("Potential referenced data found.")
)
self.import_schema_execution_page.setComplete(True)
- self.import_schema_execution_page.busy(False)
+ self.busy(self.import_schema_execution_page, False)
return PageIds.ImportDataConfiguration
self.import_schema_execution_page.setComplete(True)
- self.import_schema_execution_page.busy(False)
+ self.busy(self.import_schema_execution_page, False)
# otherwise, go to project create
return PageIds.ProjectCreation
@@ -345,8 +349,10 @@ def next_id(self):
)
)
self.default_baskets_page.setComplete(False)
- self.default_baskets_page.busy(
- True, self.tr("Checking for potential referenced data...")
+ self.busy(
+ self.default_baskets_page,
+ True,
+ self.tr("Checking for potential referenced data..."),
)
if self.update_referecedata_cache_model(
self._db_modelnames(self.import_data_configuration),
@@ -356,10 +362,10 @@ def next_id(self):
self.tr("Potential referenced data found.")
)
self.default_baskets_page.setComplete(True)
- self.default_baskets_page.busy(False)
+ self.busy(self.default_baskets_page, False)
return PageIds.ImportDataConfiguration
self.default_baskets_page.setComplete(True)
- self.default_baskets_page.busy(False)
+ self.busy(self.default_baskets_page, False)
# otherwise, go to project create
return PageIds.ProjectCreation
@@ -686,13 +692,14 @@ def append_dropped_files(self, dropped_files, dropped_ini_files):
dropped_ini_files[0]
)
- def start_busy_bar(self, text="Loading..."):
- self.log_panel.busy_bar.setFormat(text)
- self.log_panel.busy_bar.setVisible(True)
-
- def stop_busy_bar(self):
- self.log_panel.busy_bar.setVisible(False)
- self.log_panel.scrollbar.setValue(self.log_panel.scrollbar.maximum())
+ def busy(self, page, busy, text="Busy..."):
+ page.setEnabled(not busy)
+ if busy:
+ self.log_panel.busy_bar.setFormat(text)
+ self.log_panel.busy_bar.setVisible(True)
+ else:
+ self.log_panel.busy_bar.setVisible(False)
+ self.log_panel.scrollbar.setValue(self.log_panel.scrollbar.maximum())
class WorkflowWizardDialog(QDialog):
From 86f63885179e60b1eff7e985f042c4c737c3e96f Mon Sep 17 00:00:00 2001
From: signedav
Date: Mon, 4 Dec 2023 17:52:29 +0100
Subject: [PATCH 8/9] remove unused function
---
QgisModelBaker/gui/workflow_wizard/execution_page.py | 7 -------
1 file changed, 7 deletions(-)
diff --git a/QgisModelBaker/gui/workflow_wizard/execution_page.py b/QgisModelBaker/gui/workflow_wizard/execution_page.py
index 2b5a5eddf..f184f92ac 100644
--- a/QgisModelBaker/gui/workflow_wizard/execution_page.py
+++ b/QgisModelBaker/gui/workflow_wizard/execution_page.py
@@ -195,10 +195,3 @@ def _on_process_finished(self, exit_code, result):
message = self.tr("Finished with errors!")
self.workflow_wizard.log_panel.print_info(message, color)
-
- def busy(self, busy, text=None):
- self.setEnabled(not busy)
- if busy:
- self.workflow_wizard.start_busy_bar(text)
- else:
- self.workflow_wizard.stop_busy_bar()
From 3589cf95acbec8f66f030e21ffc185ff4295c3e8 Mon Sep 17 00:00:00 2001
From: signedav
Date: Wed, 6 Dec 2023 08:28:04 +0100
Subject: [PATCH 9/9] Update
QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
Co-authored-by: Damiano Lombardi
---
QgisModelBaker/gui/workflow_wizard/workflow_wizard.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
index 3292c91a0..5281860bc 100644
--- a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
+++ b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py
@@ -694,11 +694,10 @@ def append_dropped_files(self, dropped_files, dropped_ini_files):
def busy(self, page, busy, text="Busy..."):
page.setEnabled(not busy)
+ self.log_panel.busy_bar.setVisible(busy)
if busy:
self.log_panel.busy_bar.setFormat(text)
- self.log_panel.busy_bar.setVisible(True)
else:
- self.log_panel.busy_bar.setVisible(False)
self.log_panel.scrollbar.setValue(self.log_panel.scrollbar.maximum())