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/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) diff --git a/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py b/QgisModelBaker/gui/workflow_wizard/import_schema_configuration_page.py index 8d0eb1a43..c77b205b5 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.workflow_wizard.busy(self, 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.workflow_wizard.busy(self, 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.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( @@ -570,3 +574,5 @@ def _load_metaconfig(self): LogColor.COLOR_TOPPING, ) self.workflow_wizard.refresh_import_models() + + 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 dd4a7039a..65b2c6643 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,180 @@ def setComplete(self, complete): self.completeChanged.emit() def restore_configuration(self, configuration): + self.workflow_wizard.busy( + self, + True, + self.tr("Restoring configuration and check existing metaconfigfile..."), + ) 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.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.workflow_wizard.busy(self, False) + + def _use_existing(self, state): + # triggered by checked state. + if state: + self._clean_topping() + 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( + 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 until end of refreshment + self.workflow_wizard.busy(self, True, self.tr("Refresh repository data...")) + self.ilitoppingcache.model_refreshed.connect( + lambda: self._enable_topping_selection(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) + + 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) + + self._enable_optimize_combo(state) + self.workflow_wizard.busy(self, False) + + def _enable_optimize_combo(self, state): + self.optimize_combo.setEnabled(state) + self.optimize_label.setEnabled(state) + + 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: + 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( + "
{} ({})
{}
Project topping from file {}
" + ).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 _create_project(self): self.progress_bar.setValue(0) @@ -167,117 +380,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 @@ -390,3 +578,86 @@ 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 _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 diff --git a/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py b/QgisModelBaker/gui/workflow_wizard/workflow_wizard.py index b446ed079..5281860bc 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,11 @@ def next_id(self): "Checking for potential referenced data on the repositories (might take a while)..." ) ) + self.busy( + self.schema_configuration_page, + True, + self.tr("Checking for potential referenced data..."), + ) self.schema_configuration_page.setComplete(False) if ( self.import_data_file_model.rowCount() @@ -283,6 +289,7 @@ def next_id(self): self.tr("Potential referenced data found.") ) self.schema_configuration_page.setComplete(True) + self.busy(self.schema_configuration_page, False) return PageIds.ImportDataConfiguration else: self.log_panel.print_info( @@ -291,6 +298,7 @@ def next_id(self): ) ) self.schema_configuration_page.setComplete(True) + self.busy(self.schema_configuration_page, False) if self.current_id == PageIds.ImportSchemaExecution: # if basket handling active, go to the create basket @@ -307,6 +315,11 @@ def next_id(self): "Checking for potential referenced data on the repositories (might take a while)..." ) ) + 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( self._db_modelnames(self.import_data_configuration), @@ -316,8 +329,10 @@ def next_id(self): self.tr("Potential referenced data found.") ) self.import_schema_execution_page.setComplete(True) + self.busy(self.import_schema_execution_page, False) return PageIds.ImportDataConfiguration self.import_schema_execution_page.setComplete(True) + self.busy(self.import_schema_execution_page, False) # otherwise, go to project create return PageIds.ProjectCreation @@ -334,6 +349,11 @@ def next_id(self): ) ) self.default_baskets_page.setComplete(False) + 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), "referenceData", @@ -342,8 +362,10 @@ def next_id(self): self.tr("Potential referenced data found.") ) self.default_baskets_page.setComplete(True) + self.busy(self.default_baskets_page, False) return PageIds.ImportDataConfiguration self.default_baskets_page.setComplete(True) + self.busy(self.default_baskets_page, False) # otherwise, go to project create return PageIds.ProjectCreation @@ -670,10 +692,19 @@ def append_dropped_files(self, dropped_files, dropped_ini_files): dropped_ini_files[0] ) + 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) + else: + 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 +714,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 5e0c435d7..4478ecc5f 100644 --- a/QgisModelBaker/ui/workflow_wizard/project_creation.ui +++ b/QgisModelBaker/ui/workflow_wizard/project_creation.ui @@ -14,61 +14,82 @@