class DatabaseConfig(object): """ Reads and writes database settings in the registry. """ def __init__(self): self.host = "Host" self.port = "Port" self.db_name = "Database" self.reg_config = RegistryConfig() def read(self): ''' Get the database connection properties ''' db_props = self.reg_config.read([self.host, self.port, self.db_name]) if len(db_props) < 3: return None else: return DatabaseConnection(db_props[self.host], db_props[self.port], db_props[self.db_name]) def write(self, db_connection): ''' Writes the database connection settings to the registry ''' db_settings = {} db_settings[self.host] = db_connection.Host db_settings[self.port] = db_connection.Port db_settings[self.db_name] = db_connection.Database self.reg_config.write(db_settings)
def fontCachePath(): regConfig = RegistryConfig() try: lookupReg = regConfig.read(['Config']) cachePath = lookupReg['Config'] return cachePath + "/font.cache" except: return None
def save_current_profile(name): """ Save the profile with the given name as the current profile. :param name: Name of the current profile. :type name: unicode """ if not name: return #Save profile in the registry/settings reg_config = RegistryConfig() reg_config.write({CURRENT_PROFILE: name})
def network_document_path(): """ Get the network resource location from the registry. """ regConfig = RegistryConfig() networkResReg = regConfig.read([NETWORK_DOC_RESOURCE]) if len(networkResReg) == 0: networkLocation = "" else: networkLocation = networkResReg[NETWORK_DOC_RESOURCE].strip() return networkLocation
def networkResource(self): ''' Get the network resource location from the registry. ''' regConfig = RegistryConfig() networkResReg = regConfig.read([NETWORK_DOC_RESOURCE]) if len(networkResReg) == 0: networkLocation = "C:/" else: networkLocation = networkResReg[NETWORK_DOC_RESOURCE] return networkLocation
def _composerTemplatesPath(self): """ Reads the path of composer templates in the registry. """ regConfig = RegistryConfig() keyName = "ComposerTemplates" valueCollection = regConfig.read([keyName]) if len(valueCollection) == 0: return None else: return valueCollection[keyName]
def _composer_output_path(self): """ Returns the directory name of the composer output directory. """ regConfig = RegistryConfig() keyName = "ComposerOutputs" valueCollection = regConfig.read([keyName]) if len(valueCollection) == 0: return None else: return valueCollection[keyName]
def initLookups(): ''' Loads the initial lookup values into the STDM database. First check if there is a flag in the registry for asserting whether the lookup values have been initialized. If False or the key does not exist then initialize then set key to True ''' regConfig = RegistryConfig() lookupReg = regConfig.read([DATABASE_LOOKUP]) if len(lookupReg) == 0 : loadLookups() else: lookupState = lookupReg[DATABASE_LOOKUP].lower() if lookupState == "false":loadLookups()
def onShowOutputFolder(self): reg_config = RegistryConfig() path = reg_config.read([COMPOSER_OUTPUT]) output_path = path.get(COMPOSER_OUTPUT,'') # windows if sys.platform.startswith('win32'): os.startfile(output_path) # *nix systems if sys.platform.startswith('linux'): subprocess.Popen(['xdg-open', output_path]) # macOS if sys.platform.startswith('darwin'): subprocess.Popen(['open', output_path])
def onShowOutputFolder(self): reg_config = RegistryConfig() path = reg_config.read([COMPOSER_OUTPUT]) output_path = path.get(COMPOSER_OUTPUT, '') # windows if sys.platform.startswith('win32'): os.startfile(output_path) # *nix systems if sys.platform.startswith('linux'): subprocess.Popen(['xdg-open', output_path]) # macOS if sys.platform.startswith('darwin'): subprocess.Popen(['open', output_path])
def source_document_location(default = "/home"): """ :return: Last used source directory for source documents prior to uploading. :rtype: str """ source_doc_dir = default reg_config = RegistryConfig() doc_path_info = reg_config.read([LOCAL_SOURCE_DOC]) if len(doc_path_info) > 0: doc_path_info = doc_path_info[LOCAL_SOURCE_DOC] if len(doc_path_info.strip()) > 0: source_doc_dir = doc_path_info return source_doc_dir
def current_profile(): """ :return: Returns text on current profile in the configuration currently being used. :rtype: Profile """ from stdm.data.configuration.stdm_configuration import StdmConfiguration reg_config = RegistryConfig() profile_info = reg_config.read([CURRENT_PROFILE]) profile_name = profile_info.get(CURRENT_PROFILE, '') #Return None if there is no current profile if not profile_name: return None profiles = StdmConfiguration.instance().profiles return profiles.get(unicode(profile_name), None)
def current_profile(): """ :return: Returns text on current profile in the configuration currently being used. :rtype: Profile """ from stdm.data.configuration.stdm_configuration import StdmConfiguration reg_config = RegistryConfig() profile_info = reg_config.read([CURRENT_PROFILE]) profile_name = profile_info.get(CURRENT_PROFILE, '') # Return None if there is no current profile if not profile_name: return None profiles = StdmConfiguration.instance().profiles return profiles.get(unicode(profile_name), None)
def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.setupUi(self) self.iface = iface self.notif_bar = NotificationBar(self.vlNotification, 6000) self._apply_btn = self.buttonBox.button(QDialogButtonBox.Apply) self._reg_config = RegistryConfig() self._db_config = DatabaseConfig() version = version_from_metadata() upgrade_label_text = self.label_9.text().replace('1.4', version) self.label_9.setText(upgrade_label_text) #Connect signals self._apply_btn.clicked.connect(self.apply_settings) self.buttonBox.accepted.connect(self.on_accept) self.chk_pg_connections.toggled.connect(self._on_use_pg_connections) self.cbo_pg_connections.currentIndexChanged.connect( self._on_pg_profile_changed) self.btn_db_conn_clear.clicked.connect(self.clear_properties) self.btn_test_db_connection.clicked.connect(self._on_test_connection) self.btn_supporting_docs.clicked.connect( self._on_choose_supporting_docs_path) self.btn_template_folder.clicked.connect( self._on_choose_doc_designer_template_path) self.btn_composer_out_folder.clicked.connect( self._on_choose_doc_generator_output_path) self.upgradeButton.toggled.connect(self.manage_upgrade) self._config = StdmConfiguration.instance() self._default_style_sheet = self.txtRepoLocation.styleSheet() self.manage_upgrade() self.sort_order = OrderedDict() self.sort_order['idasc'] = 'ID - Smallest to Biggest' self.sort_order['iddesc'] = 'ID - Biggest to Smallest' self.sort_order['asc'] = 'Smallest to Biggest' self.sort_order['desc'] = 'Biggest to Smallest' self.init_gui()
def _load_column_mapping(self): """ Imports the current column mapping from a JSON definition file """ config = RegistryConfig() prev_folder = config.read(["LastImportConfigFolder"]).get("LastImportConfigFolder") if not prev_folder: prev_folder = QDir.homePath() source_path, _ = QFileDialog.getOpenFileName(self, self.tr("Load Configuration"), prev_folder, "{0} (*.json)".format(self.tr('Configuration files'))) if not source_path: return config.write({"LastImportConfigFolder": QFileInfo(source_path).path()}) with open(source_path, 'rt') as f: imported_config = json.loads(''.join(f.readlines())) self._restore_column_config(imported_config)
def loadLookups(): for k,v in stdm_lookups.iteritems(): modelName = k Values = v model = globals()[modelName] modelInstance = model() queryObj = modelInstance.queryObject() #Ensure item does not exist before being inserted for lk in v: #Convert QString to Python string lk = unicode(lk) lkObj = queryObj.filter(model.name == lk).first() if lkObj == None: lkInst = model() lkInst.name = lk lkInst.save() #Update registry regConfig = RegistryConfig() regConfig.write({DATABASE_LOOKUP:str(True)})
def _save_column_mapping(self): """ Exports the current column mapping to a JSON definition file """ config = RegistryConfig() prev_folder = config.read(["LastImportConfigFolder"]).get("LastImportConfigFolder") if not prev_folder: prev_folder = QDir.homePath() dest_path, _ = QFileDialog.getSaveFileName(self, self.tr("Save Configuration"), prev_folder, "{0} (*.json)".format(self.tr('Configuration files'))) if not dest_path: return dest_path = QgsFileUtils.ensureFileNameHasExtension(dest_path, ['.json']) config.write({"LastImportConfigFolder": QFileInfo(dest_path).path()}) with open(dest_path, 'wt') as f: f.write(json.dumps(self._get_column_config(), indent=4))
def set_source_document_location(doc_path): """ Set the latest source directory of uploaded source documents. :param doc_path: Directory path or file path. The system will attempt to extract the directory path from the file name. """ doc_dir_path = "" #Check if it is a file or directory doc_dir = QDir(doc_path) if not doc_dir.exists(): doc_file_info = QFileInfo(doc_path) if doc_file_info.exists(): doc_dir_path = doc_file_info.dir().path() else: doc_dir_path = doc_path if len(doc_dir_path) > 0: reg_config = RegistryConfig() reg_config.write({LOCAL_SOURCE_DOC:doc_dir_path})
def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet(''' QLabel { font: bold; } ''')
def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.setupUi(self) self.iface = iface self.notif_bar = NotificationBar(self.vlNotification, 6000) self._apply_btn = self.buttonBox.button(QDialogButtonBox.Apply) self._reg_config = RegistryConfig() self._db_config = DatabaseConfig() #Connect signals self._apply_btn.clicked.connect(self.apply_settings) self.buttonBox.accepted.connect(self.on_accept) self.chk_pg_connections.toggled.connect(self._on_use_pg_connections) self.cbo_pg_connections.currentIndexChanged.connect( self._on_pg_profile_changed) self.btn_db_conn_clear.clicked.connect(self.clear_properties) self.btn_test_db_connection.clicked.connect(self._on_test_connection) self.btn_supporting_docs.clicked.connect( self._on_choose_supporting_docs_path ) self.btn_template_folder.clicked.connect( self._on_choose_doc_designer_template_path ) self.btn_composer_out_folder.clicked.connect( self._on_choose_doc_generator_output_path ) self.upgradeButton.toggled.connect( self.manage_upgrade ) self._config = StdmConfiguration.instance() self._default_style_sheet = self.txtRepoLocation.styleSheet() self.manage_upgrade() self.init_gui()
class DatabaseConfig: """ Reads and writes database settings in the registry. """ HOST = "Host" PORT = "Port" DB_NAME = "Database" def __init__(self): self.reg_config = RegistryConfig() def read(self) -> Optional[DatabaseConnection]: """ Get the database connection properties """ db_props = self.reg_config.read( [DatabaseConfig.HOST, DatabaseConfig.PORT, DatabaseConfig.DB_NAME]) if len(db_props) < 3: return None else: return DatabaseConnection(db_props[DatabaseConfig.HOST], db_props[DatabaseConfig.PORT], db_props[DatabaseConfig.DB_NAME]) def write(self, db_connection): """ Writes the database connection settings to the registry """ db_settings = { DatabaseConfig.HOST: db_connection.Host, DatabaseConfig.PORT: db_connection.Port, DatabaseConfig.DB_NAME: db_connection.Database } self.reg_config.write(db_settings)
def documentTemplates(): """ Return a dictionary of document names and their corresponding absolute file paths. """ from stdm.settings.registryconfig import RegistryConfig docTemplates = OrderedDict() regConfig = RegistryConfig() keyName = "ComposerTemplates" pathConfig = regConfig.read([keyName]) if len(pathConfig) > 0: templateDir = pathConfig[keyName] pathDir = QDir(templateDir) pathDir.setNameFilters(["*.sdt"]) docFileInfos = pathDir.entryInfoList(QDir.Files, QDir.Name) for df in docFileInfos: docTemplates[df.completeBaseName()] = df.absoluteFilePath() return docTemplates
def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.setupUi(self) self.iface = iface self.notif_bar = NotificationBar(self.vlNotification, 6000) self._apply_btn = self.buttonBox.button(QDialogButtonBox.Apply) self._reg_config = RegistryConfig() self._db_config = DatabaseConfig() version = version_from_metadata() upgrade_label_text = self.label_9.text().replace('1.4', version) self.label_9.setText(upgrade_label_text) #Connect signals self._apply_btn.clicked.connect(self.apply_settings) self.buttonBox.accepted.connect(self.on_accept) self.chk_pg_connections.toggled.connect(self._on_use_pg_connections) self.cbo_pg_connections.currentIndexChanged.connect( self._on_pg_profile_changed) self.btn_db_conn_clear.clicked.connect(self.clear_properties) self.btn_test_db_connection.clicked.connect(self._on_test_connection) self.btn_supporting_docs.clicked.connect( self._on_choose_supporting_docs_path ) self.btn_template_folder.clicked.connect( self._on_choose_doc_designer_template_path ) self.btn_composer_out_folder.clicked.connect( self._on_choose_doc_generator_output_path ) self.upgradeButton.toggled.connect( self.manage_upgrade ) self._config = StdmConfiguration.instance() self._default_style_sheet = self.txtRepoLocation.styleSheet() self.manage_upgrade() self.init_gui()
def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet( ''' QLabel { font: bold; } ''' )
def get_entity_sort_order(): reg_config = RegistryConfig() rec_info = reg_config.read([ENTITY_SORT_ORDER]) sort_order = rec_info.get(ENTITY_SORT_ORDER, None) return sort_order
class OptionsDialog(QDialog, Ui_DlgOptions): """ Dialog for editing STDM settings. """ def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.setupUi(self) self.iface = iface self.notif_bar = NotificationBar(self.vlNotification, 6000) self._apply_btn = self.buttonBox.button(QDialogButtonBox.Apply) self._reg_config = RegistryConfig() self._db_config = DatabaseConfig() version = version_from_metadata() upgrade_label_text = self.label_9.text().replace('1.4', version) self.label_9.setText(upgrade_label_text) #Connect signals self._apply_btn.clicked.connect(self.apply_settings) self.buttonBox.accepted.connect(self.on_accept) self.chk_pg_connections.toggled.connect(self._on_use_pg_connections) self.cbo_pg_connections.currentIndexChanged.connect( self._on_pg_profile_changed) self.btn_db_conn_clear.clicked.connect(self.clear_properties) self.btn_test_db_connection.clicked.connect(self._on_test_connection) self.btn_supporting_docs.clicked.connect( self._on_choose_supporting_docs_path ) self.btn_template_folder.clicked.connect( self._on_choose_doc_designer_template_path ) self.btn_composer_out_folder.clicked.connect( self._on_choose_doc_generator_output_path ) self.upgradeButton.toggled.connect( self.manage_upgrade ) self._config = StdmConfiguration.instance() self._default_style_sheet = self.txtRepoLocation.styleSheet() self.manage_upgrade() self.init_gui() def init_gui(self): #Set integer validator for the port number int_validator = QIntValidator(1024, 49151) self.txtPort.setValidator(int_validator) #Load profiles self.load_profiles() #Set current profile in the combobox curr_profile = current_profile() if not curr_profile is None: setComboCurrentIndexWithText(self.cbo_profiles, curr_profile.name) #Load current database connection properties self._load_db_conn_properties() #Load existing PostgreSQL connections self._load_qgis_pg_connections() #Load directory paths self._load_directory_paths() self.edtEntityRecords.setMaximum(MAX_LIMIT) self.edtEntityRecords.setValue(get_entity_browser_record_limit()) # Debug logging lvl = debug_logging() if lvl: self.chk_logging.setCheckState(Qt.Checked) else: self.chk_logging.setCheckState(Qt.Unchecked) def load_profiles(self): """ Load existing profiles into the combobox. """ profile_names = self._config.profiles.keys() self.cbo_profiles.clear() self.cbo_profiles.addItem('') self.cbo_profiles.addItems(profile_names) def _load_db_conn_properties(self): #Load database connection properties from the registry. db_conn = self._db_config.read() if not db_conn is None: self.txtHost.setText(db_conn.Host) self.txtPort.setText(db_conn.Port) self.txtDatabase.setText(db_conn.Database) def _load_qgis_pg_connections(self): """ Load QGIS postgres connections. """ self.cbo_pg_connections.addItem('') profiles = pg_profile_names() for profile in profiles: self.cbo_pg_connections.addItem(profile[0], profile[1]) def _load_directory_paths(self): #Load paths to various directory settings. comp_out_path = composer_output_path() comp_temp_path = composer_template_path() source_doc_path = source_documents_path() if not source_doc_path is None: self.txtRepoLocation.setText(source_doc_path) if not comp_out_path is None: self.txt_output_dir.setText(comp_out_path) if not comp_temp_path is None: self.txt_template_dir.setText(comp_temp_path) def _on_use_pg_connections(self, state): #Slot raised when to (not) use existing pg connections if not state: self.cbo_pg_connections.setCurrentIndex(0) self.cbo_pg_connections.setEnabled(False) #Restore current connection in registry self._load_db_conn_properties() else: self.cbo_pg_connections.setEnabled(True) def _on_pg_profile_changed(self, index): """ Slot raised when the index of the pg profile changes. If the selection is valid then the system will attempt to extract the database connection properties of the selected profile stored in the registry. """ if index == 0: return profile_path = self.cbo_pg_connections.itemData(index) q_config = QGISRegistryConfig(profile_path) db_items = q_config.read(['Database', 'Host', 'Port']) if len(db_items) > 0: self.txtDatabase.setText(db_items['Database']) self.txtHost.setText(db_items['Host']) self.txtPort.setText(db_items['Port']) def clear_properties(self): """ Clears the host, database name and port number values from the respective controls. """ self.txtDatabase.clear() self.txtHost.clear() self.txtPort.clear() def _on_choose_supporting_docs_path(self): #Slot raised to select directory for supporting documents. self._set_selected_directory(self.txtRepoLocation, self.tr( 'Supporting Documents Directory') ) def _on_choose_doc_designer_template_path(self): #Slot raised to select directory for document designer templates. self._set_selected_directory(self.txt_template_dir, self.tr( 'Document Designer Templates Directory') ) def _on_choose_doc_generator_output_path(self): #Slot raised to select directory for doc generator outputs. self._set_selected_directory(self.txt_output_dir, self.tr( 'Document Generator Output Directory') ) def _set_selected_directory(self, txt_box, title): def_path= txt_box.text() sel_doc_path = QFileDialog.getExistingDirectory(self, title, def_path) if sel_doc_path: normalized_path = QDir.fromNativeSeparators(sel_doc_path) txt_box.clear() txt_box.setText(normalized_path) def _validate_db_props(self): #Test if all properties have been specified status = True self.notif_bar.clear() if not self.txtHost.text(): msg = self.tr('Please specify the database host address.') self.notif_bar.insertErrorNotification(msg) status = False if not self.txtPort.text(): msg = self.tr('Please specify the port number.') self.notif_bar.insertErrorNotification(msg) status = False if not self.txtDatabase.text(): msg = self.tr('Please specify the database name.') self.notif_bar.insertErrorNotification(msg) status = False return status def _database_connection(self): #Creates a databaase connection object from the specified args host = self.txtHost.text() port = self.txtPort.text() database = self.txtDatabase.text() #Create database connection object db_conn = DatabaseConnection(host, port, database) return db_conn def _on_test_connection(self): """ Slot raised to test database connection. """ status = self._validate_db_props() if not status: return login_dlg = loginDlg(self, True) db_conn = self._database_connection() login_dlg.set_database_connection(db_conn) res = login_dlg.exec_() if res == QDialog.Accepted: msg = self.tr(u"Connection to '{0}' database was " "successful.".format(db_conn.Database)) QMessageBox.information(self, self.tr('Database Connection'), msg) def set_current_profile(self): """ Saves the given profile name as the current profile. """ profile_name = self.cbo_profiles.currentText() if not profile_name: self.notif_bar.clear() msg = self.tr('Profile name is empty, current profile will not ' 'be set.') self.notif_bar.insertErrorNotification(msg) return False save_current_profile(profile_name) return True def save_database_properties(self): """ Saves the specified database connection properties to the registry. :return: True if the connection properties were successfully saved. :rtype: bool """ if not self._validate_db_props(): return False #Create a database object and write it to the registry db_conn = self._database_connection() self._db_config.write(db_conn) return True def set_supporting_documents_path(self): """ Set the directory of supporting documents. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txtRepoLocation.text() if not path: msg = self.tr('Please set the supporting documents directory.') self.notif_bar.insertErrorNotification(msg) return False #Validate path if not self._check_path_exists(path, self.txtRepoLocation): return False #Commit to registry self._reg_config.write({NETWORK_DOC_RESOURCE: path}) return True def set_document_templates_path(self): """ Set the directory of document designer templates. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txt_template_dir.text() if not path: msg = self.tr('Please set the document designer templates ' 'directory.') self.notif_bar.insertErrorNotification(msg) return False #Validate path if not self._check_path_exists(path, self.txt_template_dir): return False #Commit to registry self._reg_config.write({COMPOSER_TEMPLATE: path}) return True def set_document_output_path(self): """ Set the directory of document generator outputs. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txt_output_dir.text() if not path: msg = self.tr('Please set the document generator output directory' '.') self.notif_bar.insertErrorNotification(msg) return False #Validate path if not self._check_path_exists(path, self.txt_output_dir): return False #Commit to registry self._reg_config.write({COMPOSER_OUTPUT: path}) return True def _check_path_exists(self, path, text_box): #Validates if the specified folder exists dir = QDir() if not dir.exists(path): msg = self.tr(u"'{0}' directory does not exist.".format(path)) self.notif_bar.insertErrorNotification(msg) #Highlight textbox control text_box.setStyleSheet(INVALIDATESTYLESHEET) timer = QTimer(self) #Sync interval with that of the notification bar timer.setInterval(self.notif_bar.interval) timer.setSingleShot(True) #Remove previous connected slots (if any) receivers = timer.receivers(SIGNAL('timeout()')) if receivers > 0: self._timer.timeout.disconnect() timer.start() timer.timeout.connect(lambda:self._restore_stylesheet( text_box) ) return False return True def _restore_stylesheet(self, textbox): # Slot raised to restore the original stylesheet of the textbox control textbox.setStyleSheet(self._default_style_sheet) # Get reference to timer and delete sender = self.sender() if not sender is None: sender.deleteLater() def apply_debug_logging(self): # Save debug logging logger = logging.getLogger('stdm') if self.chk_logging.checkState() == Qt.Checked: logger.setLevel(logging.DEBUG) set_debug_logging(True) else: logger.setLevel(logging.ERROR) set_debug_logging(False) def apply_settings(self): """ Save settings. :return: True if the settings were successfully applied, otherwise False. :rtype: bool """ #Set current profile if not self.set_current_profile(): return False #Set db connection properties if not self.save_database_properties(): return False #Set supporting documents directory if not self.set_supporting_documents_path(): return False #Set document designer templates path if not self.set_document_templates_path(): return False #Set document generator output path if not self.set_document_output_path(): return False self.apply_debug_logging() # Set Entity browser record limit save_entity_browser_record_limit(self.edtEntityRecords.value()) msg = self.tr('Settings successfully saved.') self.notif_bar.insertSuccessNotification(msg) return True def on_accept(self): """ Slot raised to save the settings of the current widget and close the widget. """ if not self.apply_settings(): return self.accept() def manage_upgrade(self): """ A slot raised when the upgrade button is clicked. It disables or enables the upgrade button based on the ConfigUpdated registry value. """ self.config_updated_dic = self._reg_config.read( [CONFIG_UPDATED] ) # if config file exists, check if registry key exists if len(self.config_updated_dic) > 0: config_updated_val = self.config_updated_dic[ CONFIG_UPDATED ] # If failed to upgrade, enable the upgrade button if config_updated_val == '0' or config_updated_val == '-1': self.upgradeButton.setEnabled(True) # disable the button if any other value. else: self.upgradeButton.setEnabled(False) else: self.upgradeButton.setEnabled(False)
class OptionsDialog(QDialog, Ui_DlgOptions): """ Dialog for editing STDM settings. """ def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.setupUi(self) self.iface = iface self.notif_bar = NotificationBar(self.vlNotification, 6000) self._apply_btn = self.buttonBox.button(QDialogButtonBox.Apply) self._reg_config = RegistryConfig() self._db_config = DatabaseConfig() #Connect signals self._apply_btn.clicked.connect(self.apply_settings) self.buttonBox.accepted.connect(self.on_accept) self.chk_pg_connections.toggled.connect(self._on_use_pg_connections) self.cbo_pg_connections.currentIndexChanged.connect( self._on_pg_profile_changed) self.btn_db_conn_clear.clicked.connect(self.clear_properties) self.btn_test_db_connection.clicked.connect(self._on_test_connection) self.btn_supporting_docs.clicked.connect( self._on_choose_supporting_docs_path) self.btn_template_folder.clicked.connect( self._on_choose_doc_designer_template_path) self.btn_composer_out_folder.clicked.connect( self._on_choose_doc_generator_output_path) self.upgradeButton.toggled.connect(self.manage_upgrade) self._config = StdmConfiguration.instance() self._default_style_sheet = self.txtRepoLocation.styleSheet() self.manage_upgrade() self.init_gui() def init_gui(self): #Set integer validator for the port number int_validator = QIntValidator(1024, 49151) self.txtPort.setValidator(int_validator) #Load profiles self.load_profiles() #Set current profile in the combobox curr_profile = current_profile() if not curr_profile is None: setComboCurrentIndexWithText(self.cbo_profiles, curr_profile.name) #Load current database connection properties self._load_db_conn_properties() #Load existing PostgreSQL connections self._load_qgis_pg_connections() #Load directory paths self._load_directory_paths() # Debug logging lvl = debug_logging() if lvl: self.chk_logging.setCheckState(Qt.Checked) else: self.chk_logging.setCheckState(Qt.Unchecked) def load_profiles(self): """ Load existing profiles into the combobox. """ profile_names = self._config.profiles.keys() self.cbo_profiles.clear() self.cbo_profiles.addItem('') self.cbo_profiles.addItems(profile_names) def _load_db_conn_properties(self): #Load database connection properties from the registry. db_conn = self._db_config.read() if not db_conn is None: self.txtHost.setText(db_conn.Host) self.txtPort.setText(db_conn.Port) self.txtDatabase.setText(db_conn.Database) def _load_qgis_pg_connections(self): """ Load QGIS postgres connections. """ self.cbo_pg_connections.addItem('') profiles = pg_profile_names() for profile in profiles: self.cbo_pg_connections.addItem(profile[0], profile[1]) def _load_directory_paths(self): #Load paths to various directory settings. comp_out_path = composer_output_path() comp_temp_path = composer_template_path() source_doc_path = source_documents_path() if not source_doc_path is None: self.txtRepoLocation.setText(source_doc_path) if not comp_out_path is None: self.txt_output_dir.setText(comp_out_path) if not comp_temp_path is None: self.txt_template_dir.setText(comp_temp_path) def _on_use_pg_connections(self, state): #Slot raised when to (not) use existing pg connections if not state: self.cbo_pg_connections.setCurrentIndex(0) self.cbo_pg_connections.setEnabled(False) #Restore current connection in registry self._load_db_conn_properties() else: self.cbo_pg_connections.setEnabled(True) def _on_pg_profile_changed(self, index): """ Slot raised when the index of the pg profile changes. If the selection is valid then the system will attempt to extract the database connection properties of the selected profile stored in the registry. """ if index == 0: return profile_path = self.cbo_pg_connections.itemData(index) q_config = QGISRegistryConfig(profile_path) db_items = q_config.read(['Database', 'Host', 'Port']) if len(db_items) > 0: self.txtDatabase.setText(db_items['Database']) self.txtHost.setText(db_items['Host']) self.txtPort.setText(db_items['Port']) def clear_properties(self): """ Clears the host, database name and port number values from the respective controls. """ self.txtDatabase.clear() self.txtHost.clear() self.txtPort.clear() def _on_choose_supporting_docs_path(self): #Slot raised to select directory for supporting documents. self._set_selected_directory(self.txtRepoLocation, self.tr('Supporting Documents Directory')) def _on_choose_doc_designer_template_path(self): #Slot raised to select directory for document designer templates. self._set_selected_directory( self.txt_template_dir, self.tr('Document Designer Templates Directory')) def _on_choose_doc_generator_output_path(self): #Slot raised to select directory for doc generator outputs. self._set_selected_directory( self.txt_output_dir, self.tr('Document Generator Output Directory')) def _set_selected_directory(self, txt_box, title): def_path = txt_box.text() sel_doc_path = QFileDialog.getExistingDirectory(self, title, def_path) if sel_doc_path: normalized_path = QDir.fromNativeSeparators(sel_doc_path) txt_box.clear() txt_box.setText(normalized_path) def _validate_db_props(self): #Test if all properties have been specified status = True self.notif_bar.clear() if not self.txtHost.text(): msg = self.tr('Please specify the database host address.') self.notif_bar.insertErrorNotification(msg) status = False if not self.txtPort.text(): msg = self.tr('Please specify the port number.') self.notif_bar.insertErrorNotification(msg) status = False if not self.txtDatabase.text(): msg = self.tr('Please specify the database name.') self.notif_bar.insertErrorNotification(msg) status = False return status def _database_connection(self): #Creates a databaase connection object from the specified args host = self.txtHost.text() port = self.txtPort.text() database = self.txtDatabase.text() #Create database connection object db_conn = DatabaseConnection(host, port, database) return db_conn def _on_test_connection(self): """ Slot raised to test database connection. """ status = self._validate_db_props() if not status: return login_dlg = loginDlg(self, True) db_conn = self._database_connection() login_dlg.set_database_connection(db_conn) res = login_dlg.exec_() if res == QDialog.Accepted: msg = self.tr(u"Connection to '{0}' database was " "successful.".format(db_conn.Database)) QMessageBox.information(self, self.tr('Database Connection'), msg) def set_current_profile(self): """ Saves the given profile name as the current profile. """ profile_name = self.cbo_profiles.currentText() if not profile_name: self.notif_bar.clear() msg = self.tr('Profile name is empty, current profile will not ' 'be set.') self.notif_bar.insertErrorNotification(msg) return False save_current_profile(profile_name) return True def save_database_properties(self): """ Saves the specified database connection properties to the registry. :return: True if the connection properties were successfully saved. :rtype: bool """ if not self._validate_db_props(): return False #Create a database object and write it to the registry db_conn = self._database_connection() self._db_config.write(db_conn) return True def set_supporting_documents_path(self): """ Set the directory of supporting documents. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txtRepoLocation.text() if not path: msg = self.tr('Please set the supporting documents directory.') self.notif_bar.insertErrorNotification(msg) return False #Validate path if not self._check_path_exists(path, self.txtRepoLocation): return False #Commit to registry self._reg_config.write({NETWORK_DOC_RESOURCE: path}) return True def set_document_templates_path(self): """ Set the directory of document designer templates. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txt_template_dir.text() if not path: msg = self.tr('Please set the document designer templates ' 'directory.') self.notif_bar.insertErrorNotification(msg) return False #Validate path if not self._check_path_exists(path, self.txt_template_dir): return False #Commit to registry self._reg_config.write({COMPOSER_TEMPLATE: path}) return True def set_document_output_path(self): """ Set the directory of document generator outputs. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txt_output_dir.text() if not path: msg = self.tr('Please set the document generator output directory' '.') self.notif_bar.insertErrorNotification(msg) return False #Validate path if not self._check_path_exists(path, self.txt_output_dir): return False #Commit to registry self._reg_config.write({COMPOSER_OUTPUT: path}) return True def _check_path_exists(self, path, text_box): #Validates if the specified folder exists dir = QDir() if not dir.exists(path): msg = self.tr(u"'{0}' directory does not exist.".format(path)) self.notif_bar.insertErrorNotification(msg) #Highlight textbox control text_box.setStyleSheet(INVALIDATESTYLESHEET) timer = QTimer(self) #Sync interval with that of the notification bar timer.setInterval(self.notif_bar.interval) timer.setSingleShot(True) #Remove previous connected slots (if any) receivers = timer.receivers(SIGNAL('timeout()')) if receivers > 0: self._timer.timeout.disconnect() timer.start() timer.timeout.connect(lambda: self._restore_stylesheet(text_box)) return False return True def _restore_stylesheet(self, textbox): # Slot raised to restore the original stylesheet of the textbox control textbox.setStyleSheet(self._default_style_sheet) # Get reference to timer and delete sender = self.sender() if not sender is None: sender.deleteLater() def apply_debug_logging(self): # Save debug logging logger = logging.getLogger('stdm') if self.chk_logging.checkState() == Qt.Checked: logger.setLevel(logging.DEBUG) set_debug_logging(True) else: logger.setLevel(logging.ERROR) set_debug_logging(False) def apply_settings(self): """ Save settings. :return: True if the settings were successfully applied, otherwise False. :rtype: bool """ #Set current profile if not self.set_current_profile(): return False #Set db connection properties if not self.save_database_properties(): return False #Set supporting documents directory if not self.set_supporting_documents_path(): return False #Set document designer templates path if not self.set_document_templates_path(): return False #Set document generator output path if not self.set_document_output_path(): return False self.apply_debug_logging() msg = self.tr('Settings successfully saved.') self.notif_bar.insertSuccessNotification(msg) return True def on_accept(self): """ Slot raised to save the settings of the current widget and close the widget. """ if not self.apply_settings(): return self.accept() def manage_upgrade(self): """ A slot raised when the upgrade button is clicked. It disables or enables the upgrade button based on the ConfigUpdated registry value. """ self.config_updated_dic = self._reg_config.read([CONFIG_UPDATED]) # if config file exists, check if registry key exists if len(self.config_updated_dic) > 0: config_updated_val = self.config_updated_dic[CONFIG_UPDATED] # If failed to upgrade, enable the upgrade button if config_updated_val == '0' or config_updated_val == '-1': self.upgradeButton.setEnabled(True) # disable the button if any other value. else: self.upgradeButton.setEnabled(False) else: self.upgradeButton.setEnabled(False)
def __init__(self): self.reg_config = RegistryConfig()
class LicenseAgreement(WIDGET, BASE): def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet(''' QLabel { font: bold; } ''') def check_show_license(self): """ Checks if you need to show the license page. Checks if the flag in the registry has been set. Returns True to show license. If registry key is not yet set, show the license page. :rtype: boolean """ show_lic = 1 license_key = self.reg_config.read([SHOW_LICENSE]) if len(license_key) > 0: show_lic = license_key[SHOW_LICENSE] if show_lic == 1 or show_lic == str(1): return True elif show_lic == 0 or show_lic == str(0): self.accepted = True return False def show_license(self): """ Show STDM license window if the user have never accepted the license terms and conditions. :return: None :rtype: NoneType """ # validate if to show license show_lic = self.check_show_license() # THe user didn't accept license if show_lic: license = LicenseDocument() self.termsCondArea.setText(license.read_license_info()) self.exec_() def accept_action(self): """ A slot raised when the user clicks on the Accept button. :return: None :rtype: NoneType """ if not self.checkBoxAgree.isChecked(): msg = QApplication.translate( 'LicenseAgreement', 'To use STDM, please accept the terms ' 'and conditions by selecting' ' the checkbox "I have read and agree ..."') self.notice_bar.clear() self.notice_bar.insertNotification(msg, ERROR) return else: self.reg_config.write({SHOW_LICENSE: 0}) self.accepted = True self.close() def decline_action(self): """ A slot raised when the user clicks on the decline button. :return: None :rtype: NoneType """ self.accepted = False self.close()
def __init__(self, parent=None, args=None): self._doc = '' self.args = args self.fileHandler = FilePaths() self.config = RegistryConfig()
class FilePaths: def __init__(self, path=None): self._file = PLUGIN_DIR self.baseDir = None self._html = '' self._sql = '' self.userPath = None self.cachePath = None self.config = RegistryConfig() # self.checkPreviousSetting() def checkPreviousSetting(self): self.defaultConfigPath() try: pathSettings = self.config.read([CONFIG]) if pathSettings: self.setUserConfigPath(pathSettings[CONFIG]) else: self.setUserConfigPath() except DummyException as ex: raise ex def XMLFile(self): # this function returns the default xml file with configuration # self.setConfigPath() return self._file def cacheFile(self): # To implemented a backup file for comparing edits everytime the user # makes changes path = self.userPath + '/temp/%s' % DEFAULT_CONFIG return path def cacheDir(self): return self.cachePath def setCacheDir(self, path=None): if path: self.cachePath = self.userPath + "/%s" % path else: self.cachePath = self.userPath + "/temp" self.createDir(self.cachePath) def STDMSettingsPath(self): # To be implemented to write new file with user edits return self.userPath def HtmlFile(self): # Read the html representation of the schema self._html = self.userPath + '/%s' % HTML return self._html def SQLFile(self): # Read the html representation of the schema self._sql = self.userPath + '/%s' % BASIC_SQL return self._sql def baseSQLPath(self): path = self.baseDir + '/%s' % DEFAULT_CONFIG # path=self.userPath+'/temp/%s'%FILE return path def HelpContents(self): """Method to load help contents file""" return self._file + '/%s' % HELP def defaultConfigPath(self): """ returns the path with base configuration file """ self.baseDir = self._file + "/templates/" return self.baseDir def setUserConfigPath(self, path: Optional[str] = None): """ set new path with user configuration """ if path is not None: self.userPath = path else: self.userPath = self.localPath() self.createDir(self.userPath) self.cachePath = self.userPath + '/temp' self.createDir(self.cachePath) self.userConfigPath(self.userPath) def userConfigPath(self, path=None): # Copy template files to the user directory try: # self.compare_config_version(FILE) for fileN in [BASIC_SQL]: if not os.path.isfile(path + '/%s' % fileN): baseFile = self.baseDir + '/%s' % fileN shutil.copy(baseFile, self.userPath) if not os.path.isfile(self.cacheFile()): self.createBackup() self.localFontPath(path) except IOError as io: raise io def compare_config_version(self, path=None): """ Method to check the version of the two files being copied and return the latest one """ if not path: path = self.userPath else: path = path base_file = self.baseSQLPath() user_file = path + '/%s' % DEFAULT_CONFIG if os.path.isfile(user_file): if QMessageBox.warning(None, QApplication.translate("FilePaths", "Previous user configuration found"), QApplication.translate("FilePaths", "Wizard detected previous configuration exists in the current directory." "\nDo you want to overwrite the existing config?"), QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes: if filecmp.cmp(base_file, user_file, shallow=False): pass else: try: os.remove(user_file) shutil.copy(base_file, self.userPath) except: pass else: QMessageBox.information(None, QApplication.translate("FilePaths", "Configuration Exist"), QApplication.translate("FilePaths", "Previous configuration retained")) else: shutil.copy(base_file, user_file) self.createBackup() def localFontPath(self, path): """ Create a path where fonts will be stored""" if path is None: if platform.system() == "Windows": path = os.environ["USERPROFILE"] else: path = os.getenv("HOME") fontPath = path + "/.stdm/font.cache" else: fontPath = str(path).replace("\\", "/") + "/font.cache" SysFonts.register(fontPath) def setUserXMLFile(self): """ Default path to the config file """ xml = self.userPath + '/%s' % DEFAULT_CONFIG return xml def localPath(self): """ Look for users path based on platform, need to implement for unix systems :return: """ profPath = None if platform.system() == "Windows": userPath = os.environ["USERPROFILE"] profPath = userPath + "/.stdm" else: profPath = str(os.getenv('HOME')) + "/.stdm" return str(profPath).replace("\\", "/") def setLocalPath(self, path=None): if path: self.userPath = path if not path: self.userPath = self.localPath() def createDir(self, dirPath): if not os.access(dirPath, os.F_OK): os.makedirs(dirPath) else: return dirPath def STDMLicenseDoc(self) -> str: """ load STDM license file for viewing """ return self._file + '/%s' % LICENSE def createBackup(self): """ In case the user want to keep track of the old file when current file changes :return: """ if os.path.isfile(self.cacheFile()): os.remove(self.cacheFile()) shutil.copy(self.setUserXMLFile(), self.cacheDir()) def change_config(self): """ Method to update the config file the detected one is old :return: """ base_file = self.baseSQLPath() cur_file = self.setUserXMLFile() try: if os.path.isfile(cur_file): os.remove(cur_file) shutil.copy(base_file, self.userPath) except: pass def get_configuration_file(self): """ Default path to the config file """ xml = self.userPath + '/%s' % DEFAULT_CONFIG return xml
class LicenseAgreement(QDialog, Ui_LicenseAgreement): def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet( ''' QLabel { font: bold; } ''' ) def check_show_license(self): """ Checks if you need to show the license page. Checks if the flag in the registry has been set. Returns True to show license. If registry key is not yet set, show the license page. :rtype: boolean """ show_lic = 1 license_key = self.reg_config.read( [SHOW_LICENSE] ) if len(license_key) > 0: show_lic = license_key[SHOW_LICENSE] if show_lic == 1 or show_lic == unicode(1): return True elif show_lic == 0 or show_lic == unicode(0): self.accepted = True return False def show_license(self): """ Show STDM license window if the user have never accepted the license terms and conditions. :return: None :rtype: NoneType """ # validate if to show license show_lic = self.check_show_license() # THe user didn't accept license if show_lic: license = LicenseDocument() self.termsCondArea.setText( license.read_license_info() ) self.exec_() def accept_action(self): """ A slot raised when the user clicks on the Accept button. :return: None :rtype: NoneType """ if not self.checkBoxAgree.isChecked(): msg = QApplication.translate( 'LicenseAgreement', 'To use STDM, please accept the terms ' 'and conditions by selecting' ' the checkbox "I have read and agree ..."' ) self.notice_bar.clear() self.notice_bar.insertNotification(msg, ERROR) return else: self.reg_config.write({SHOW_LICENSE: 0}) self.accepted = True self.close() def decline_action(self): """ A slot raised when the user clicks on the decline button. :return: None :rtype: NoneType """ self.accepted = False self.close()
def save_entity_browser_record_limit(limit): """ type limit:int """ reg_config = RegistryConfig() reg_config.write({ENTITY_BROWSER_RECORD_LIMIT:limit})
def reg_setting(self): connSettings = ['Host', 'Database', 'Port'] set_conn = RegistryConfig() settings = set_conn.read(connSettings) return settings
def save_entity_browser_record_limit(limit): """ type limit:int """ reg_config = RegistryConfig() reg_config.write({ENTITY_BROWSER_RECORD_LIMIT: limit})
def get_entity_browser_record_limit(): reg_config = RegistryConfig() rec_info = reg_config.read([ENTITY_BROWSER_RECORD_LIMIT]) rec_limit = rec_info.get(ENTITY_BROWSER_RECORD_LIMIT, 10) return rec_limit
def save_entity_sort_order(sort_order): """ :type sort_order: str """ reg_config = RegistryConfig() reg_config.write({ENTITY_SORT_ORDER: sort_order})
def get_entity_sort_details(group_name, entity_name): reg_config = RegistryConfig() sort_details = reg_config.get_value(group_name, entity_name) #rec_info = reg_config.read([ENTITY_SORT_ORDER]) #sort_order = rec_info.get(ENTITY_SORT_ORDER, None) return sort_details
def __init__(self): self.host = "Host" self.port = "Port" self.db_name = "Database" self.reg_config = RegistryConfig()
class OptionsDialog(QDialog, Ui_DlgOptions): """ Dialog for editing STDM settings. """ def __init__(self, iface): QDialog.__init__(self, iface.mainWindow()) self.setupUi(self) self.iface = iface self.notif_bar = NotificationBar(self.vlNotification, 6000) self._apply_btn = self.buttonBox.button(QDialogButtonBox.Apply) self._reg_config = RegistryConfig() self._db_config = DatabaseConfig() # Connect signals self._apply_btn.clicked.connect(self.apply_settings) self.buttonBox.accepted.connect(self.on_accept) self.chk_pg_connections.toggled.connect(self._on_use_pg_connections) self.cbo_pg_connections.currentIndexChanged.connect( self._on_pg_profile_changed) self.btn_db_conn_clear.clicked.connect(self.clear_properties) self.btn_test_db_connection.clicked.connect( self._on_test_db_connection) self.btn_template_folder.clicked.connect( self._on_choose_doc_designer_template_path) self.btn_composer_out_folder.clicked.connect( self._on_choose_doc_generator_output_path) self.btn_test_docs_repo_conn.clicked.connect( self._on_test_cmis_connection) self.txt_atom_pub_url.textChanged.connect(self._on_cmis_url_changed) self.btn_holders_conf_file.clicked.connect( self._on_choose_holders_config_file) self._config = StdmConfiguration.instance() self.init_gui() def init_gui(self): # Set integer validator for the port number int_validator = QIntValidator(1024, 49151) self.txtPort.setValidator(int_validator) # Load profiles self.load_profiles() # Set current profile in the combobox curr_profile = current_profile() if not curr_profile is None: setComboCurrentIndexWithText(self.cbo_profiles, curr_profile.name) # Load current database connection properties self._load_db_conn_properties() # Load existing PostgreSQL connections self._load_qgis_pg_connections() # Load directory paths self._load_directory_paths() # Load document repository-related settings self._load_cmis_config() # Load holders configuration file path self._load_holders_configuration_file() # Debug logging lvl = debug_logging() if lvl: self.chk_logging.setCheckState(Qt.Checked) else: self.chk_logging.setCheckState(Qt.Unchecked) # Shortcut dialog self._check_shortcuts_settings() self.chk_shortcut_dlg.toggled.connect(self._on_check_shortcut_checkbox) def _load_cmis_config(self): """ Load configuration names and IDs in the combobox then select the user specified ID. """ # Load CMIS atom pub URL self.txt_atom_pub_url.setText(cmis_atom_pub_url()) self.cbo_auth_config_name.clear() self.cbo_auth_config_name.addItem('') config_ids = config_entries() for ci in config_ids: id = ci[0] name = ci[1] display = u'{0} ({1})'.format(name, id) self.cbo_auth_config_name.addItem(display, id) # Then select the user specific config ID if specified conf_id = cmis_auth_config_id() if conf_id: id_idx = self.cbo_auth_config_name.findData(conf_id) if id_idx != -1: self.cbo_auth_config_name.setCurrentIndex(id_idx) def _load_holders_configuration_file(self): # Load the path of the holders configuration file. holders_config = holders_config_path() if not holders_config: # Use the default path holders_config = DEF_HOLDERS_CONFIG_PATH self.txt_holders_config.setText(holders_config) def _on_choose_holders_config_file(self): # Slot raised to browse the holders config file holders_config = self.txt_holders_config.text() if not holders_config: holders_config = QDir.home().path() conf_file = QFileDialog.getOpenFileName( self, self.tr('Browse Holders Configuration File'), holders_config, 'Holders INI file (*.ini)') if conf_file: self.txt_holders_config.setText(conf_file) def _on_cmis_url_changed(self, new_text): # Slot raised when text for CMIS URL changes. Basically updates # the tooltip so as to display long URLs self.txt_atom_pub_url.setToolTip(new_text) def _check_shortcuts_settings(self): """ Checks the state of the show dialog checkbox :return: Bool """ # Check registry values for shortcut dialog show_dlg = 1 dlg_key = self._reg_config.read([SHOW_SHORTCUT_DIALOG]) if len(dlg_key) > 0: show_dlg = dlg_key[SHOW_SHORTCUT_DIALOG] if show_dlg == 1 or show_dlg == unicode(1): self.chk_shortcut_dlg.setChecked(True) elif show_dlg == 0 or show_dlg == unicode(0): self.chk_shortcut_dlg.setChecked(False) def _on_check_shortcut_checkbox(self, toggled): """ Slot raised when the checkbox for showing shortcut window is checked/unchecked. :param toggled: Toggle status :type toggled: bool """ if toggled: self._reg_config.write({SHOW_SHORTCUT_DIALOG: 1}) self.notif_bar.clear() msg = self.tr(u"Shortcuts window will show after login") self.notif_bar.insertWarningNotification(msg) else: self._reg_config.write({SHOW_SHORTCUT_DIALOG: 0}) self.notif_bar.clear() msg = self.tr(u"Shortcuts window will not show after login") self.notif_bar.insertWarningNotification(msg) def load_profiles(self): """ Load existing profiles into the combobox. """ profile_names = self._config.profiles.keys() self.cbo_profiles.clear() self.cbo_profiles.addItem('') self.cbo_profiles.addItems(profile_names) def _load_db_conn_properties(self): # Load database connection properties from the registry. db_conn = self._db_config.read() if not db_conn is None: self.txtHost.setText(db_conn.Host) self.txtPort.setText(db_conn.Port) self.txtDatabase.setText(db_conn.Database) def _load_qgis_pg_connections(self): """ Load QGIS postgres connections. """ self.cbo_pg_connections.addItem('') profiles = pg_profile_names() for profile in profiles: self.cbo_pg_connections.addItem(profile[0], profile[1]) def _load_directory_paths(self): # Load paths to various directory settings. comp_out_path = composer_output_path() comp_temp_path = composer_template_path() if not comp_out_path is None: self.txt_output_dir.setText(comp_out_path) if not comp_temp_path is None: self.txt_template_dir.setText(comp_temp_path) def _on_use_pg_connections(self, state): # Slot raised when to (not) use existing pg connections if not state: self.cbo_pg_connections.setCurrentIndex(0) self.cbo_pg_connections.setEnabled(False) # Restore current connection in registry self._load_db_conn_properties() else: self.cbo_pg_connections.setEnabled(True) def _on_pg_profile_changed(self, index): """ Slot raised when the index of the pg profile changes. If the selection is valid then the system will attempt to extract the database connection properties of the selected profile stored in the registry. """ if index == 0: return profile_path = self.cbo_pg_connections.itemData(index) q_config = QGISRegistryConfig(profile_path) db_items = q_config.read(['Database', 'Host', 'Port']) if len(db_items) > 0: self.txtDatabase.setText(db_items['Database']) self.txtHost.setText(db_items['Host']) self.txtPort.setText(db_items['Port']) def clear_properties(self): """ Clears the host, database name and port number values from the respective controls. """ self.txtDatabase.clear() self.txtHost.clear() self.txtPort.clear() def _on_choose_doc_designer_template_path(self): # Slot raised to select directory for document designer templates. self._set_selected_directory( self.txt_template_dir, self.tr('Document Designer Templates Directory')) def _on_choose_doc_generator_output_path(self): # Slot raised to select directory for doc generator outputs. self._set_selected_directory( self.txt_output_dir, self.tr('Document Generator Output Directory')) def _set_selected_directory(self, txt_box, title): def_path = txt_box.text() sel_doc_path = QFileDialog.getExistingDirectory(self, title, def_path) if sel_doc_path: normalized_path = QDir.fromNativeSeparators(sel_doc_path) txt_box.clear() txt_box.setText(normalized_path) def _validate_db_props(self): # Test if all properties have been specified status = True self.notif_bar.clear() if not self.txtHost.text(): msg = self.tr('Please specify the database host address.') self.notif_bar.insertErrorNotification(msg) status = False if not self.txtPort.text(): msg = self.tr('Please specify the port number.') self.notif_bar.insertErrorNotification(msg) status = False if not self.txtDatabase.text(): msg = self.tr('Please specify the database name.') self.notif_bar.insertErrorNotification(msg) status = False return status def _database_connection(self): # Creates a databaase connection object from the specified args host = self.txtHost.text() port = self.txtPort.text() database = self.txtDatabase.text() # Create database connection object db_conn = DatabaseConnection(host, port, database) return db_conn def _on_test_db_connection(self): """ Slot raised to test database connection. """ status = self._validate_db_props() if not status: return login_dlg = loginDlg(self, True) db_conn = self._database_connection() login_dlg.set_database_connection(db_conn) res = login_dlg.exec_() if res == QDialog.Accepted: msg = self.tr(u"Connection to '{0}' database was " "successful.".format(db_conn.Database)) self.notif_bar.insertSuccessNotification(msg) def _on_test_cmis_connection(self): # Slot raised to test connection to CMIS service status = self._validate_cmis_properties() if not status: return self.notif_bar.clear() atom_pub_url = self.txt_atom_pub_url.text() auth_conf_id = self.cbo_auth_config_name.itemData( self.cbo_auth_config_name.currentIndex()) cmis_mgr = CmisManager(url=atom_pub_url, auth_config_id=auth_conf_id) QgsApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) status = cmis_mgr.connect() QgsApplication.restoreOverrideCursor() if status: msg = self.tr('Connection to the CMIS server succeeded.') self.notif_bar.insertSuccessNotification(msg) else: msg = self.tr( 'Failed to connect to the CMIS server. Check URL and/or ' 'credentials.') self.notif_bar.insertErrorNotification(msg) def set_current_profile(self): """ Saves the given profile name as the current profile. """ profile_name = self.cbo_profiles.currentText() if not profile_name: self.notif_bar.clear() msg = self.tr('Profile name is empty, current profile will not ' 'be set.') self.notif_bar.insertErrorNotification(msg) return False save_current_profile(profile_name) return True def set_cmis_properties(self): """ Saves the CMIS atom pub URL and authentication configuration ID. """ if not self._validate_cmis_properties(): return False atom_pub_url = self.txt_atom_pub_url.text() set_cmis_atom_pub_url(atom_pub_url) curr_idx = self.cbo_auth_config_name.currentIndex() config_id = self.cbo_auth_config_name.itemData(curr_idx) set_cmis_auth_config_id(config_id) return True def _validate_cmis_properties(self): # Assert if user has specified URL and authentication config ID. atom_pub_url = self.txt_atom_pub_url.text() config_name_id = self.cbo_auth_config_name.currentText() status = True if not atom_pub_url: msg = self.tr( 'Please specify the URL of the CMIS atom pub service.') self.notif_bar.insertErrorNotification(msg) status = False if not config_name_id: msg = self.tr( 'Please select the configuration ID containing the CMIS authentication.' ) self.notif_bar.insertErrorNotification(msg) status = False return status def set_holders_config_file(self): # Save the path to the holders configuration file holders_config_file = self.txt_holders_config.text() if not holders_config_file: msg = self.tr( 'Please set the path to the holders configuration file.') self.notif_bar.insertErrorNotification(msg) return False set_holders_config_path(holders_config_file) return True def save_database_properties(self): """ Saves the specified database connection properties to the registry. :return: True if the connection properties were successfully saved. :rtype: bool """ if not self._validate_db_props(): return False # Create a database object and write it to the registry db_conn = self._database_connection() self._db_config.write(db_conn) return True def set_document_templates_path(self): """ Set the directory of document designer templates. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txt_template_dir.text() if not path: msg = self.tr('Please set the document designer templates ' 'directory.') self.notif_bar.insertErrorNotification(msg) return False # Validate path if not self._check_path_exists(path, self.txt_template_dir): return False # Commit to registry self._reg_config.write({COMPOSER_TEMPLATE: path}) return True def set_document_output_path(self): """ Set the directory of document generator outputs. :return: True if the directory was set in the registry, otherwise False. :rtype: bool """ path = self.txt_output_dir.text() if not path: msg = self.tr('Please set the document generator output directory' '.') self.notif_bar.insertErrorNotification(msg) return False # Validate path if not self._check_path_exists(path, self.txt_output_dir): return False # Commit to registry self._reg_config.write({COMPOSER_OUTPUT: path}) return True def _check_path_exists(self, path, text_box): # Validates if the specified folder exists dir = QDir() if not dir.exists(path): msg = self.tr(u"'{0}' directory does not exist.".format(path)) self.notif_bar.insertErrorNotification(msg) # Highlight textbox control text_box.setStyleSheet(INVALIDATESTYLESHEET) timer = QTimer(self) # Sync interval with that of the notification bar timer.setInterval(self.notif_bar.interval) timer.setSingleShot(True) # Remove previous connected slots (if any) receivers = timer.receivers(SIGNAL('timeout()')) if receivers > 0: self._timer.timeout.disconnect() timer.start() timer.timeout.connect(lambda: self._restore_stylesheet(text_box)) return False return True def _restore_stylesheet(self, textbox): # Slot raised to restore the original stylesheet of the textbox control textbox.setStyleSheet(self._default_style_sheet) # Get reference to timer and delete sender = self.sender() if not sender is None: sender.deleteLater() def apply_debug_logging(self): # Save debug logging logger = logging.getLogger('stdm') if self.chk_logging.checkState() == Qt.Checked: logger.setLevel(logging.DEBUG) set_debug_logging(True) else: logger.setLevel(logging.ERROR) set_debug_logging(False) def apply_settings(self): """ Save settings. :return: True if the settings were successfully applied, otherwise False. :rtype: bool """ # Set current profile if not self.set_current_profile(): return False # Set db connection properties if not self.save_database_properties(): return False # Set CMIS properties if not self.set_cmis_properties(): return False # Set holders configuration file path if not self.set_holders_config_file(): return False # Set document designer templates path if not self.set_document_templates_path(): return False # Set document generator output path if not self.set_document_output_path(): return False self.apply_debug_logging() msg = self.tr('Settings successfully saved.') self.notif_bar.insertSuccessNotification(msg) return True def on_accept(self): """ Slot raised to save the settings of the current widget and close the widget. """ if not self.apply_settings(): return self.accept()