Пример #1
0
class SettingsDialog(QDialog, DIALOG_UI):
    """
    Customizable dialog to configure LADM-COL Assistant.

    It can be created passing a SettingsContext with specific params
    or it can be instantiated and then set params one by one.
    """
    db_connection_changed = pyqtSignal(DBConnector, bool,
                                       str)  # dbconn, ladm_col_db, source
    open_dlg_import_schema = pyqtSignal(
        Context)  # Context for the import schema dialog

    def __init__(self, conn_manager=None, context=None, parent=None):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.parent = parent
        self.logger = Logger()
        self.conn_manager = conn_manager
        self.app = AppInterface()

        self.sbx_tolerance.setMaximum(TOLERANCE_MAX_VALUE)
        self._valid_document_repository = False  # Needs to be True if users want to enable doc repo (using test button)

        context = context if context else SettingsContext()

        self.db_source = context.db_source  # default db source is COLLECTED_DB_SOURCE
        self._required_models = context.required_models
        self._tab_pages_list = context.tab_pages_list
        self._blocking_mode = context.blocking_mode  # Whether the dialog can only be accepted on valid DB connections or not
        self._action_type = context.action_type  # By default "config"
        self.setWindowTitle(context.title)

        self._db = None
        self.init_db_engine = None
        self.dbs_supported = ConfigDBsSupported()
        self._open_dlg_import_schema = False  # After accepting, if non-valid DB is configured, we can go to import schema

        self.online_models_radio_button.setEnabled(
            False)  # This option is disabled until we have online models back!
        self.online_models_radio_button.setChecked(True)
        self.online_models_radio_button.toggled.connect(
            self.model_provider_toggle)
        self.custom_model_directories_line_edit.setText("")
        self.custom_models_dir_button.clicked.connect(
            self.show_custom_model_dir)
        self.custom_model_directories_line_edit.setVisible(False)
        self.custom_models_dir_button.setVisible(False)

        # Set connections
        self.buttonBox.accepted.disconnect()
        self.buttonBox.accepted.connect(self.accepted)
        self.buttonBox.helpRequested.connect(self.show_help)
        self.finished.connect(self.finished_slot)
        self.btn_test_connection.clicked.connect(self.test_connection)
        self.btn_test_ladm_col_structure.clicked.connect(
            self.test_ladm_col_structure)

        self.btn_test_service.clicked.connect(self.test_service)
        self.btn_test_service_transitional_system.clicked.connect(
            self.test_service_transitional_system)
        self.txt_service_endpoint.textEdited.connect(
            self.source_service_endpoint_changed)  # For manual changes only

        self.btn_default_value_sources.clicked.connect(
            self.set_default_value_source_service)
        self.btn_default_value_transitional_system.clicked.connect(
            self.set_default_value_transitional_system_service)

        self.chk_use_roads.toggled.connect(self.update_images_state)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.layout().addWidget(self.bar, 0, 0, Qt.AlignTop)

        self.cbo_db_engine.clear()

        self._lst_db = self.dbs_supported.get_db_factories()
        self._lst_panel = dict()

        for key, value in self._lst_db.items():
            self.cbo_db_engine.addItem(value.get_name(), key)
            self._lst_panel[key] = value.get_config_panel(self)
            self._lst_panel[key].notify_message_requested.connect(
                self.show_message)
            self.db_layout.addWidget(self._lst_panel[key])

        self.db_engine_changed()

        # Trigger some default behaviours
        self.restore_db_source_settings(
        )  # restore settings with default db source
        self.restore_settings()

        self.roles = RoleRegistry()
        self.load_roles()

        self.cbo_db_engine.currentIndexChanged.connect(self.db_engine_changed)
        self.rejected.connect(self.close_dialog)

        self._update_tabs()

        if context.tip:
            self.show_tip(context.tip)

    def set_db_source(self, db_source):
        self.db_source = db_source
        self.restore_db_source_settings()

    def set_tab_pages_list(self, tab_pages_list):
        self._tab_pages_list = tab_pages_list
        self._update_tabs()

    def set_required_models(self, required_models):
        self._required_models = required_models

    def set_blocking_mode(self, block):
        self._blocking_mode = block

    def _update_tabs(self):
        """
        Show only those tabs that are listed in tab_pages_list, if any. If it's an empty list, show all tabs.
        """
        if self._tab_pages_list:
            for i in reversed(range(self.tabWidget.count())):
                if i not in self._tab_pages_list:
                    self.tabWidget.removeTab(i)

    def load_roles(self):
        """
        Initialize group box for selecting the active role
        """
        self.gbx_active_role_layout = QVBoxLayout()
        dict_roles = self.roles.get_roles_info()
        checked = False
        active_role = self.roles.get_active_role()

        # Initialize radio buttons
        for k, v in dict_roles.items():
            radio = QRadioButton(v)
            radio.setToolTip(self.roles.get_role_description(k))

            if not checked:
                if k == active_role:
                    radio.setChecked(True)
                    checked = True

            self.gbx_active_role_layout.addWidget(radio)

        self.gbx_active_role.setLayout(self.gbx_active_role_layout)

    def close_dialog(self):
        self.close()

    def showEvent(self, event):
        # It is necessary to reload the variables
        # to load the database and schema name
        self.restore_settings()

        self.btn_test_ladm_col_structure.setVisible(
            self._action_type != EnumDbActionType.SCHEMA_IMPORT)

    def model_provider_toggle(self):
        if self.offline_models_radio_button.isChecked():
            self.custom_model_directories_line_edit.setVisible(True)
            self.custom_models_dir_button.setVisible(True)
        else:
            self.custom_model_directories_line_edit.setVisible(False)
            self.custom_models_dir_button.setVisible(False)
            self.custom_model_directories_line_edit.setText("")

    def _get_db_connector_from_gui(self):
        current_db_engine = self.cbo_db_engine.currentData()
        params = self._lst_panel[current_db_engine].read_connection_parameters(
        )
        db = self._lst_db[current_db_engine].get_db_connector(params)
        return db

    def get_db_connection(self):
        if self._db is not None:
            self.logger.info(__name__, "Returning existing db connection...")
        else:
            self.logger.info(__name__, "Getting new db connection...")
            self._db = self._get_db_connector_from_gui()
            self._db.open_connection()

        return self._db

    def show_custom_model_dir(self):
        dlg = CustomModelDirDialog(
            self.custom_model_directories_line_edit.text(), self)
        dlg.exec_()

    def accepted(self):
        """
        We start checking the document repository configuration and only allow to continue if we have a valid repo or
        if the repo won't be used.

        Then, check if connection to DB/schema is valid, if not, block the dialog.
        If valid, check it complies with LADM. If not, block the dialog. If it complies, we have two options: To emit
        db_connection changed or not. Finally, we store options in QSettings.
        """
        res_doc_repo, msg_doc_repo = self.check_document_repository_before_saving_settings(
        )
        if not res_doc_repo:
            self.show_message(msg_doc_repo, Qgis.Warning, 0)
            return  # Do not close the dialog

        ladm_col_schema = False

        db = self._get_db_connector_from_gui()

        test_level = EnumTestLevel.DB_SCHEMA

        if self._action_type == EnumDbActionType.SCHEMA_IMPORT:
            # Limit the validation (used in GeoPackage)
            test_level |= EnumTestLevel.SCHEMA_IMPORT

        res, code, msg = db.test_connection(
            test_level
        )  # No need to pass required_models, we don't test that much

        if res:
            if self._action_type != EnumDbActionType.SCHEMA_IMPORT:
                # Only check LADM-schema if we are not in an SCHEMA IMPORT.
                # We know in an SCHEMA IMPORT, at this point the schema is still not LADM.
                ladm_col_schema, code, msg = db.test_connection(
                    EnumTestLevel.LADM, required_models=self._required_models)

            if not ladm_col_schema and self._action_type != EnumDbActionType.SCHEMA_IMPORT:
                if self._blocking_mode:
                    self.show_message(msg, Qgis.Warning)
                    return  # Do not close the dialog

        else:
            if self._blocking_mode:
                self.show_message(msg, Qgis.Warning)
                return  # Do not close the dialog

        # Connection is valid and complies with LADM
        current_db_engine = self.cbo_db_engine.currentData()
        if self._lst_panel[current_db_engine].state_changed(
        ) or self.init_db_engine != current_db_engine:
            # Emit db_connection_changed
            if self._db is not None:
                self._db.close_connection()

            self._db = db

            # Update db connect with new db conn
            self.conn_manager.set_db_connector_for_source(
                self._db, self.db_source)

            # Emmit signal when db source changes
            self.db_connection_changed.emit(self._db, ladm_col_schema,
                                            self.db_source)
            self.logger.debug(
                __name__, "Settings dialog emitted a db_connection_changed.")

        if not ladm_col_schema and self._action_type == EnumDbActionType.CONFIG:
            msg_box = QMessageBox(self)
            msg_box.setIcon(QMessageBox.Question)
            msg_box.setText(
                QCoreApplication.translate(
                    "SettingsDialog",
                    "No LADM-COL DB has been configured! You'll continue with limited functionality until you configure a LADM-COL DB.\n\nDo you want to go to 'Create LADM-COL structure' dialog?"
                ))
            msg_box.setWindowTitle(
                QCoreApplication.translate("SettingsDialog", "Important"))
            msg_box.setStandardButtons(QMessageBox.Yes | QMessageBox.Ignore)
            msg_box.setDefaultButton(QMessageBox.Ignore)
            msg_box.button(QMessageBox.Yes).setText(
                QCoreApplication.translate("SettingsDialog",
                                           "Yes, go to create structure"))
            msg_box.button(QMessageBox.Ignore).setText(
                QCoreApplication.translate("SettingsDialog",
                                           "No, I'll do it later"))
            reply = msg_box.exec_()

            if reply == QMessageBox.Yes:
                self._open_dlg_import_schema = True  # We will open it when we've closed this Settings dialog

        # If active role is changed (a check and confirmation may be needed), refresh the GUI
        # Note: Better to leave this check as the last one in the accepted() method.
        selected_role = self.get_selected_role()
        if self.roles.get_active_role() != selected_role:
            b_change_role = True
            if STSession().is_user_logged():
                reply = QMessageBox.question(
                    self.parent,
                    QCoreApplication.translate("SettingsDialog", "Warning"),
                    QCoreApplication.translate(
                        "SettingsDialog",
                        "You have a ST connection opened and you want to change your role.\nIf you confirm that you want to change your role, you'll be logged out from the ST.\n\nDo you really want to change your role?"
                    ), QMessageBox.Yes | QMessageBox.Cancel,
                    QMessageBox.Cancel)
                if reply == QMessageBox.Yes:
                    STSession().logout()
                elif reply == QMessageBox.Cancel:
                    # No need to switch back selected role, the Settings Dialog gets it from role registry
                    b_change_role = False

            if b_change_role:
                self.logger.info(
                    __name__,
                    "The active role has changed from '{}' to '{}'.".format(
                        self.roles.get_active_role(), selected_role))
                self.roles.set_active_role(
                    selected_role
                )  # Emits signal that refreshed the plugin for this role

        self.save_settings(db)

        QDialog.accept(self)
        self.close()

        if self._open_dlg_import_schema:
            # After Settings dialog has been closed, we could call Import Schema depending on user's answer above
            self.open_dlg_import_schema.emit(Context())
            self.logger.debug(
                __name__,
                "Settings dialog emitted a show Import Schema dialog.")

    def check_document_repository_before_saving_settings(self):
        # Check if source service is checked (active). If so, check if either status or endpoint changed. If so,
        # check if self._valid_document_repository is False. If so, we need to test the service and only allow to save
        # if such test is successful.
        res, msg = True, ''
        if self.connection_box.isChecked(
        ):  # The user wants to have the source service enabled
            initial_config = QSettings().value(
                'Asistente-LADM-COL/sources/use_service',
                DEFAULT_USE_SOURCE_SERVICE_SETTING, bool)
            initial_endpoint = QSettings().value(
                'Asistente-LADM-COL/sources/service_endpoint',
                DEFAULT_ENDPOINT_SOURCE_SERVICE)

            # Config changed or Endpoint changed?
            if initial_config != self.connection_box.isChecked(
            ) or initial_endpoint.strip() != self.txt_service_endpoint.text(
            ).strip():
                if not self._valid_document_repository:  # A test service has not been run, so we need to do it now
                    self.logger.debug(
                        __name__,
                        "The user wants to enable the source service but the 'test service' has not been run on the current URL. Testing it..."
                    )
                    res_test, msg_test = self.test_service()
                    if not res_test:
                        res = False
                        msg = QCoreApplication.translate(
                            "SettingsDialog",
                            "The source service is not valid, so it cannot be activated! Adjust such configuration before saving settings."
                        )

        return res, msg

    def source_service_endpoint_changed(self, new_text):
        # Source service endpoint was changed, so a test_service is required to make the valid variable True
        self._valid_document_repository = False

    def get_selected_role(self):
        selected_role = None
        radio_checked = None
        for i in range(self.gbx_active_role_layout.count()):
            radio = self.gbx_active_role_layout.itemAt(i).widget()
            if radio.isChecked():
                radio_checked = radio.text()
                break

        for k, v in self.roles.get_roles_info().items():
            if v == radio_checked:
                selected_role = k
                break

        return selected_role  # Role key

    def reject(self):
        self.done(0)

    def finished_slot(self, result):
        self.bar.clearWidgets()

    def save_settings(self, db):
        settings = QSettings()
        current_db_engine = self.cbo_db_engine.currentData()
        settings.setValue(
            'Asistente-LADM-COL/db/{db_source}/db_connection_engine'.format(
                db_source=self.db_source), current_db_engine)
        dict_conn = self._lst_panel[
            current_db_engine].read_connection_parameters()

        self._lst_db[current_db_engine].save_parameters_conn(
            dict_conn=dict_conn, db_source=self.db_source)

        settings.setValue(
            'Asistente-LADM-COL/models/custom_model_directories_is_checked',
            self.offline_models_radio_button.isChecked())
        if self.offline_models_radio_button.isChecked():
            settings.setValue('Asistente-LADM-COL/models/custom_models',
                              self.custom_model_directories_line_edit.text())

        self.app.settings.tolerance = self.sbx_tolerance.value()
        settings.setValue('Asistente-LADM-COL/quality/use_roads',
                          self.chk_use_roads.isChecked())

        settings.setValue(
            'Asistente-LADM-COL/models/validate_data_importing_exporting',
            self.chk_validate_data_importing_exporting.isChecked())

        endpoint_transitional_system = self.txt_service_transitional_system.text(
        ).strip()
        settings.setValue(
            'Asistente-LADM-COL/sources/service_transitional_system',
            (endpoint_transitional_system[:-1]
             if endpoint_transitional_system.endswith('/') else
             endpoint_transitional_system)
            or TransitionalSystemConfig().ST_DEFAULT_DOMAIN)

        settings.setValue('Asistente-LADM-COL/sources/use_service',
                          self.connection_box.isChecked())
        endpoint = self.txt_service_endpoint.text().strip()
        settings.setValue(
            'Asistente-LADM-COL/sources/service_endpoint',
            (endpoint[:-1] if endpoint.endswith('/') else endpoint)
            or DEFAULT_ENDPOINT_SOURCE_SERVICE)

        settings.setValue(
            'Asistente-LADM-COL/automatic_values/automatic_values_in_batch_mode',
            self.chk_automatic_values_in_batch_mode.isChecked())

        # Changes in automatic namespace, local_id or t_ili_tid configuration?
        current_namespace_enabled = settings.value(
            'Asistente-LADM-COL/automatic_values/namespace_enabled', True,
            bool)
        current_namespace_prefix = settings.value(
            'Asistente-LADM-COL/automatic_values/namespace_prefix', "")
        current_local_id_enabled = settings.value(
            'Asistente-LADM-COL/automatic_values/local_id_enabled', True, bool)
        current_t_ili_tid_enabled = settings.value(
            'Asistente-LADM-COL/automatic_values/t_ili_tid_enabled', True,
            bool)

        settings.setValue(
            'Asistente-LADM-COL/automatic_values/namespace_enabled',
            self.namespace_collapsible_group_box.isChecked())
        if self.namespace_collapsible_group_box.isChecked():
            settings.setValue(
                'Asistente-LADM-COL/automatic_values/namespace_prefix',
                self.txt_namespace.text())

        settings.setValue(
            'Asistente-LADM-COL/automatic_values/local_id_enabled',
            self.chk_local_id.isChecked())
        settings.setValue(
            'Asistente-LADM-COL/automatic_values/t_ili_tid_enabled',
            self.chk_t_ili_tid.isChecked())

        if current_namespace_enabled != self.namespace_collapsible_group_box.isChecked() or \
           current_namespace_prefix != self.txt_namespace.text() or \
           current_local_id_enabled != self.chk_local_id.isChecked() or \
           current_t_ili_tid_enabled != self.chk_t_ili_tid.isChecked():
            if db is not None:
                self.logger.info(
                    __name__,
                    "Automatic values changed in Settings dialog. All LADM-COL layers are being updated..."
                )
                self.app.core.automatic_fields_settings_changed(db)

    def restore_db_source_settings(self):
        settings = QSettings()
        default_db_engine = self.dbs_supported.id_default_db

        self.init_db_engine = settings.value(
            'Asistente-LADM-COL/db/{db_source}/db_connection_engine'.format(
                db_source=self.db_source), default_db_engine)
        index_db_engine = self.cbo_db_engine.findData(self.init_db_engine)

        if index_db_engine == -1:
            index_db_engine = self.cbo_db_engine.findData(default_db_engine)

        self.cbo_db_engine.setCurrentIndex(index_db_engine)
        self.db_engine_changed()

        # restore db settings for all panels
        for db_engine, db_factory in self._lst_db.items():
            dict_conn = db_factory.get_parameters_conn(self.db_source)
            self._lst_panel[db_engine].write_connection_parameters(dict_conn)
            self._lst_panel[db_engine].save_state()

    def restore_settings(self):
        # Restore QSettings
        settings = QSettings()

        custom_model_directories_is_checked = settings.value(
            'Asistente-LADM-COL/models/custom_model_directories_is_checked',
            DEFAULT_USE_CUSTOM_MODELS,
            type=bool)
        if custom_model_directories_is_checked:
            self.offline_models_radio_button.setChecked(True)
            self.custom_model_directories_line_edit.setText(
                settings.value('Asistente-LADM-COL/models/custom_models',
                               DEFAULT_MODELS_DIR))
            self.custom_model_directories_line_edit.setVisible(True)
            self.custom_models_dir_button.setVisible(True)
        else:
            self.online_models_radio_button.setChecked(True)
            self.custom_model_directories_line_edit.setText("")
            self.custom_model_directories_line_edit.setVisible(False)
            self.custom_models_dir_button.setVisible(False)

        self.sbx_tolerance.setValue(self.app.settings.tolerance)
        use_roads = settings.value('Asistente-LADM-COL/quality/use_roads',
                                   True, bool)
        self.chk_use_roads.setChecked(use_roads)
        self.update_images_state(use_roads)

        self.chk_automatic_values_in_batch_mode.setChecked(
            settings.value(
                'Asistente-LADM-COL/automatic_values/automatic_values_in_batch_mode',
                DEFAULT_AUTOMATIC_VALUES_IN_BATCH_MODE, bool))
        self.connection_box.setChecked(
            settings.value('Asistente-LADM-COL/sources/use_service',
                           DEFAULT_USE_SOURCE_SERVICE_SETTING, bool))
        self.namespace_collapsible_group_box.setChecked(
            settings.value(
                'Asistente-LADM-COL/automatic_values/namespace_enabled', True,
                bool))
        self.chk_local_id.setChecked(
            settings.value(
                'Asistente-LADM-COL/automatic_values/local_id_enabled', True,
                bool))
        self.chk_t_ili_tid.setChecked(
            settings.value(
                'Asistente-LADM-COL/automatic_values/t_ili_tid_enabled', True,
                bool))
        self.txt_namespace.setText(
            str(
                settings.value(
                    'Asistente-LADM-COL/automatic_values/namespace_prefix',
                    "")))

        self.chk_validate_data_importing_exporting.setChecked(
            settings.value(
                'Asistente-LADM-COL/models/validate_data_importing_exporting',
                True, bool))

        self.txt_service_transitional_system.setText(
            settings.value(
                'Asistente-LADM-COL/sources/service_transitional_system',
                TransitionalSystemConfig().ST_DEFAULT_DOMAIN))
        self.txt_service_endpoint.setText(
            settings.value('Asistente-LADM-COL/sources/service_endpoint',
                           DEFAULT_ENDPOINT_SOURCE_SERVICE))

    def db_engine_changed(self):
        if self._db is not None:
            self._db.close_connection()

        self._db = None  # Reset db connection

        for key, value in self._lst_panel.items():
            value.setVisible(False)

        current_db_engine = self.cbo_db_engine.currentData()

        self._lst_panel[current_db_engine].setVisible(True)

    def test_connection(self):
        db = self._get_db_connector_from_gui()
        test_level = EnumTestLevel.DB_SCHEMA

        if self._action_type == EnumDbActionType.SCHEMA_IMPORT:
            test_level |= EnumTestLevel.SCHEMA_IMPORT

        res, code, msg = db.test_connection(
            test_level
        )  # No need to pass required_models, we don't test that much

        if db is not None:
            db.close_connection()

        self.show_message(msg, Qgis.Info if res else Qgis.Warning)
        self.logger.info(__name__, "Test connection!")
        self.logger.debug(
            __name__,
            "Test connection ({}): {}, {}".format(test_level, res, msg))

    def test_ladm_col_structure(self):
        db = self._get_db_connector_from_gui()
        res, code, msg = db.test_connection(
            test_level=EnumTestLevel.LADM,
            required_models=self._required_models)

        if db is not None:
            db.close_connection()

        self.show_message(msg, Qgis.Info if res else Qgis.Warning)
        self.logger.info(__name__, "Test LADM structure!")
        self.logger.debug(
            __name__,
            "Test connection ({}): {}, {}".format(EnumTestLevel.LADM, res,
                                                  msg))

    def test_service(self):
        self.setEnabled(False)
        QCoreApplication.processEvents()
        res, msg = self.app.core.is_source_service_valid(
            self.txt_service_endpoint.text().strip())
        self._valid_document_repository = res  # Required to be True if the user wants to enable the source service
        self.setEnabled(True)
        self.show_message(msg['text'], msg['level'], 0)
        return res, msg

    def test_service_transitional_system(self):
        self.setEnabled(False)
        QCoreApplication.processEvents()
        res, msg = self.app.core.is_transitional_system_service_valid(
            self.txt_service_transitional_system.text().strip())
        self.setEnabled(True)
        self.show_message(msg['text'], msg['level'])

    def set_default_value_source_service(self):
        self.txt_service_endpoint.setText(DEFAULT_ENDPOINT_SOURCE_SERVICE)

    def set_default_value_transitional_system_service(self):
        self.txt_service_transitional_system.setText(
            TransitionalSystemConfig().ST_DEFAULT_DOMAIN)

    def show_message(self, message, level, duration=10):
        self.bar.clearWidgets(
        )  # Remove previous messages before showing a new one
        self.bar.pushMessage(message, level, duration)

    def show_tip(self, tip):
        self.show_message(tip, Qgis.Info,
                          0)  # Don't show counter for the tip message

    def update_images_state(self, checked):
        self.img_with_roads.setEnabled(checked)
        self.img_with_roads.setToolTip(
            QCoreApplication.translate(
                "SettingsDialog", "Missing roads will be marked as errors."
            ) if checked else '')
        self.img_without_roads.setEnabled(not checked)
        self.img_without_roads.setToolTip(
            '' if checked else QCoreApplication.translate(
                "SettingsDialog", "Missing roads will not be marked as errors."
            ))

    def show_help(self):
        show_plugin_help("settings")

    def set_action_type(self, action_type):
        self._action_type = action_type

        for key, value in self._lst_panel.items():
            value.set_action(action_type)
class WelcomeScreenDialog(QDialog, DIALOG_UI):
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.logger = Logger()
        self.help_strings = HelpStrings()

        #self.txt_help_page.setHtml(self.help_strings.DLG_WELCOME_SCREEN)
        #self.txt_help_page.anchorClicked.connect(self.save_template)

        self.finished.connect(self.finish_dialog)
        self.buttonBox.helpRequested.connect(self.show_help)

        self.gbx_layout = QVBoxLayout()
        self.roles = RoleRegistry()
        self.dict_roles = self.roles.get_roles_info()
        checked = False
        active_role = self.roles.get_active_role()

        # Initialize radio buttons
        for k,v in self.dict_roles.items():
            radio = QRadioButton(v)
            if not checked:
                if k == active_role:
                    radio.setChecked(True)
                    checked = True
                    self.show_description(self.roles.get_role_description(k), checked)  # Initialize help page

            radio.toggled.connect(partial(self.show_description, self.roles.get_role_description(k)))
            self.gbx_layout.addWidget(radio)

        self.gbx_options.setLayout(self.gbx_layout)

    def finish_dialog(self, result):
        if result == 0:
            self.roles.set_active_default_role(emit_signal=False)  # Welcome dialog should not emit role_changed signal
        else:
            self.set_checked_role_active()

        self.logger.info_msg(__name__, QCoreApplication.translate("WelcomeScreenDialog",
                                                                  "The role '{}' is now active!").format(self.roles.get_active_role_name()))

    def show_description(self, description, checked):
        if checked:
            self.txt_help_page.setHtml("<span style=\" color:#545454;\">{}</span>".format(description))

    def set_checked_role_active(self):
        radio_checked = None
        for i in range(self.gbx_layout.count()):
            radio = self.gbx_layout.itemAt(i).widget()
            if radio.isChecked():
                radio_checked = radio.text()
                break

        for k, v in self.dict_roles.items():
            if v == radio_checked:
                self.roles.set_active_role(k, emit_signal=False)  # Welcome dialog should not emit role_changed signal
                break

    def show_help(self):
        show_plugin_help()