diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index fd9a46d21..45521375b 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - qgis_version: [focal-3.16, 3.22-jammy, latest] + qgis_version: [3.22-jammy, 3.28-jammy, latest] env: QGIS_TEST_VERSION: ${{ matrix.qgis_version }} steps: diff --git a/QgisModelBaker/gui/panel/db_config_panel.py b/QgisModelBaker/gui/panel/db_config_panel.py index 2a55a01f8..31b570dde 100644 --- a/QgisModelBaker/gui/panel/db_config_panel.py +++ b/QgisModelBaker/gui/panel/db_config_panel.py @@ -38,7 +38,7 @@ class DbConfigPanel(QWidget, metaclass=AbstractQWidgetMeta): :type notify_field_modified: pyqtSignal(str) """ - notify_fields_modified = pyqtSignal(str) + notify_fields_modified = pyqtSignal() def __init__(self, parent: QWidget, db_action_type: DbActionType): """ diff --git a/QgisModelBaker/gui/panel/gpkg_config_panel.py b/QgisModelBaker/gui/panel/gpkg_config_panel.py index ee26a799e..cc7d2eea4 100644 --- a/QgisModelBaker/gui/panel/gpkg_config_panel.py +++ b/QgisModelBaker/gui/panel/gpkg_config_panel.py @@ -17,7 +17,6 @@ """ import logging -from qgis.PyQt.QtCore import pyqtSignal from qgis.PyQt.QtGui import QValidator from QgisModelBaker.libs.modelbaker.utils.globals import DbActionType @@ -41,8 +40,6 @@ class GpkgConfigPanel(DbConfigPanel, WIDGET_UI): :type notify_field_modified: pyqtSignal(str) """ - notify_fields_modified = pyqtSignal(str) - ValidExtensions = ["gpkg", "GPKG"] def __init__(self, parent, db_action_type): diff --git a/QgisModelBaker/gui/panel/mssql_config_panel.py b/QgisModelBaker/gui/panel/mssql_config_panel.py index 8b3f75a61..d5fa152a8 100644 --- a/QgisModelBaker/gui/panel/mssql_config_panel.py +++ b/QgisModelBaker/gui/panel/mssql_config_panel.py @@ -17,8 +17,6 @@ """ import logging -from qgis.PyQt.QtCore import pyqtSignal - from QgisModelBaker.libs.modelbaker.utils.globals import DbActionType from QgisModelBaker.libs.modelbaker.utils.qt_utils import ( NonEmptyStringValidator, @@ -33,9 +31,6 @@ class MssqlConfigPanel(DbConfigPanel, WIDGET_UI): - - notify_fields_modified = pyqtSignal(str) - def __init__(self, parent, db_action_type): DbConfigPanel.__init__(self, parent, db_action_type) self.setupUi(self) diff --git a/QgisModelBaker/gui/panel/pg_config_panel.py b/QgisModelBaker/gui/panel/pg_config_panel.py index b229257f1..6f8a63590 100644 --- a/QgisModelBaker/gui/panel/pg_config_panel.py +++ b/QgisModelBaker/gui/panel/pg_config_panel.py @@ -19,9 +19,14 @@ import logging from enum import IntEnum -from qgis.PyQt.QtCore import Qt, pyqtSignal +from qgis.PyQt.QtCore import Qt, QTimer import QgisModelBaker.libs.modelbaker.libs.pgserviceparser as pgserviceparser +import QgisModelBaker.libs.modelbaker.utils.db_utils as db_utils +from QgisModelBaker.libs.modelbaker.iliwrapper.globals import DbIliMode +from QgisModelBaker.libs.modelbaker.iliwrapper.ili2dbconfig import ( + Ili2DbCommandConfiguration, +) from QgisModelBaker.libs.modelbaker.utils.globals import DbActionType from QgisModelBaker.libs.modelbaker.utils.qt_utils import ( NonEmptyStringValidator, @@ -52,7 +57,7 @@ class _SERVICE_COMBOBOX_ROLE(IntEnum): DBAUTHID = Qt.UserRole + 7 SSLMODE = Qt.UserRole + 8 - notify_fields_modified = pyqtSignal(str) + REFRESH_SCHEMAS_TIMEOUT_MS = 500 def __init__(self, parent, db_action_type): DbConfigPanel.__init__(self, parent, db_action_type) @@ -60,6 +65,10 @@ def __init__(self, parent, db_action_type): self._current_service = None + self._fill_schema_combo_box_timer = QTimer() + self._fill_schema_combo_box_timer.setSingleShot(True) + self._fill_schema_combo_box_timer.timeout.connect(self._fill_schema_combo_box) + from QgisModelBaker.libs.modelbaker.iliwrapper.ili2dbconfig import ( BaseConfiguration, ) @@ -81,7 +90,9 @@ def __init__(self, parent, db_action_type): self.pg_host_line_edit.setValidator(nonEmptyValidator) self.pg_database_line_edit.setValidator(nonEmptyValidator) - self.pg_schema_line_edit.setValidator(nonEmptyValidator) + self.pg_schema_combo_box.setValidator(nonEmptyValidator) + + self.pg_schema_combo_box.setEditable(True) self.pg_host_line_edit.textChanged.connect(self.validators.validate_line_edits) self.pg_host_line_edit.textChanged.emit(self.pg_host_line_edit.text()) @@ -89,15 +100,14 @@ def __init__(self, parent, db_action_type): self.validators.validate_line_edits ) self.pg_database_line_edit.textChanged.emit(self.pg_database_line_edit.text()) - self.pg_schema_line_edit.textChanged.connect( + self.pg_schema_combo_box.lineEdit().textChanged.connect( self.validators.validate_line_edits ) - self.pg_schema_line_edit.textChanged.emit(self.pg_host_line_edit.text()) - self.pg_host_line_edit.textChanged.connect(self.notify_fields_modified) - self.pg_port_line_edit.textChanged.connect(self.notify_fields_modified) - self.pg_database_line_edit.textChanged.connect(self.notify_fields_modified) - self.pg_schema_line_edit.textChanged.connect(self.notify_fields_modified) + self.pg_host_line_edit.textChanged.connect(self._fields_modified) + self.pg_port_line_edit.textChanged.connect(self._fields_modified) + self.pg_database_line_edit.textChanged.connect(self._fields_modified) + self.pg_schema_combo_box.currentTextChanged.connect(self.notify_fields_modified) # Fill pg_services combo box self.pg_service_combo_box.addItem(self.tr("None"), None) @@ -162,13 +172,18 @@ def __init__(self, parent, db_action_type): self._show_panel() def _show_panel(self): + + self._fill_schema_combo_box() + if ( self._db_action_type == DbActionType.GENERATE or self._db_action_type == DbActionType.IMPORT_DATA ): - self.pg_schema_line_edit.setPlaceholderText(self.tr("Schema Name")) + self.pg_schema_combo_box.lineEdit().setPlaceholderText( + self.tr("Schema Name") + ) elif self._db_action_type == DbActionType.EXPORT: - self.pg_schema_line_edit.setPlaceholderText( + self.pg_schema_combo_box.lineEdit().setPlaceholderText( self.tr("[Enter a valid schema]") ) else: @@ -181,7 +196,7 @@ def get_fields(self, configuration): configuration.dbport = self.pg_port_line_edit.text().strip() configuration.dbusr = self.pg_auth_settings.username() configuration.database = self.pg_database_line_edit.text().strip() - configuration.dbschema = self.pg_schema_line_edit.text().strip().lower() + configuration.dbschema = self.pg_schema_combo_box.currentText().strip().lower() configuration.dbpwd = self.pg_auth_settings.password() configuration.dbauthid = self.pg_auth_settings.configId() @@ -241,7 +256,7 @@ def set_fields(self, configuration): self.pg_port_line_edit.setText(configuration.dbport) self.pg_auth_settings.setUsername(configuration.dbusr) self.pg_database_line_edit.setText(configuration.database) - self.pg_schema_line_edit.setText(configuration.dbschema) + self.pg_schema_combo_box.setCurrentText(configuration.dbschema) self.pg_auth_settings.setPassword(configuration.dbpwd) self.pg_auth_settings.setConfigId(configuration.dbauthid) @@ -300,7 +315,7 @@ def _pg_service_combo_box_changed(self): self.pg_port_line_edit.setText(service_config.get("port", "")) self.pg_auth_settings.setUsername(service_config.get("user", "")) self.pg_database_line_edit.setText(service_config.get("dbname", "")) - self.pg_schema_line_edit.setText("") + self.pg_schema_combo_box.setCurrentText("") self.pg_auth_settings.setPassword(service_config.get("password", "")) self.pg_auth_settings.setConfigId("") @@ -333,7 +348,7 @@ def _pg_service_combo_box_changed(self): index, PgConfigPanel._SERVICE_COMBOBOX_ROLE.DATABASE ) ) - self.pg_schema_line_edit.setText( + self.pg_schema_combo_box.setText( self.pg_service_combo_box.itemData( index, PgConfigPanel._SERVICE_COMBOBOX_ROLE.DBSCHEMA ) @@ -395,6 +410,8 @@ def _pg_service_combo_box_changed(self): == self.pg_ssl_mode_combo_box.findData(None) ) + self._fields_modified() + def _keep_custom_settings(self): index = self.pg_service_combo_box.findData( @@ -422,7 +439,7 @@ def _keep_custom_settings(self): ) self.pg_service_combo_box.setItemData( index, - self.pg_schema_line_edit.text().strip().lower(), + self.pg_schema_combo_box.currentText().strip().lower(), PgConfigPanel._SERVICE_COMBOBOX_ROLE.DBSCHEMA, ) self.pg_service_combo_box.setItemData( @@ -440,3 +457,43 @@ def _keep_custom_settings(self): self.pg_ssl_mode_combo_box.currentData(), PgConfigPanel._SERVICE_COMBOBOX_ROLE.SSLMODE, ) + + def _fields_modified(self): + + self._fill_schema_combo_box_timer.start(self.REFRESH_SCHEMAS_TIMEOUT_MS) + + self.notify_fields_modified.emit() + + def _fill_schema_combo_box(self): + + configuration = Ili2DbCommandConfiguration() + + mode = DbIliMode.pg + self.get_fields(configuration) + + configuration.tool = mode + configuration.db_ili_version = db_utils.db_ili_version(configuration) + + db_connector = db_utils.get_db_connector(configuration) + if not db_connector: + logging.warning("Refresh schema list connection error") + return + + schemas = db_connector.get_schemas() + + AUTO_ADDED_SCHEMA = "auto_added_schema" + + currentText = self.pg_schema_combo_box.currentText() + + # Remove all items that were not added by the user + index_to_remove = self.pg_schema_combo_box.findData(AUTO_ADDED_SCHEMA) + while index_to_remove > -1: + self.pg_schema_combo_box.removeItem(index_to_remove) + index_to_remove = self.pg_schema_combo_box.findData(AUTO_ADDED_SCHEMA) + + for schema in schemas: + self.pg_schema_combo_box.addItem(schema, AUTO_ADDED_SCHEMA) + + currentTextIndex = self.pg_schema_combo_box.findText(currentText) + if currentTextIndex > -1: + self.pg_schema_combo_box.setCurrentIndex(currentTextIndex) diff --git a/QgisModelBaker/ui/pg_settings_panel.ui b/QgisModelBaker/ui/pg_settings_panel.ui index d0f2291ed..0ec660531 100644 --- a/QgisModelBaker/ui/pg_settings_panel.ui +++ b/QgisModelBaker/ui/pg_settings_panel.ui @@ -69,13 +69,6 @@ - - - - - - - @@ -110,6 +103,9 @@ + + + @@ -124,7 +120,7 @@ pg_host_line_edit pg_port_line_edit pg_database_line_edit - pg_schema_line_edit + pg_schema_combo_box pg_use_super_login