diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index bc91912..a0a2603 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -21,7 +21,7 @@ repos:
- --markdown-linebreak-ext=md
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: "v0.5.0"
+ rev: "v0.6.7"
hooks:
- id: ruff
args:
@@ -29,7 +29,7 @@ repos:
- --target-version=py39
- repo: https://github.com/psf/black
- rev: 24.4.2
+ rev: 24.8.0
hooks:
- id: black
args:
@@ -53,7 +53,7 @@ repos:
- --filter-files
- repo: https://github.com/pycqa/flake8
- rev: 7.1.0
+ rev: 7.1.1
hooks:
- id: flake8
additional_dependencies: ["flake8-qgis"]
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6197ebf..d6830f7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,4 +9,3 @@ These are mostly guidelines, not rules. Use your best judgment, and feel free to
We use git hooks through [pre-commit](https://pre-commit.com/) to enforce and automatically check some "rules". Please install them (`pre-commit install`) before to push any commit.
See the relevant configuration file: `.pre-commit-config.yaml`.
-
diff --git a/profile_manager/__init__.py b/profile_manager/__init__.py
index c653fbc..6d84408 100644
--- a/profile_manager/__init__.py
+++ b/profile_manager/__init__.py
@@ -32,4 +32,5 @@ def classFactory(iface): # pylint: disable=invalid-name
"""
#
from .profile_manager import ProfileManager
+
return ProfileManager(iface)
diff --git a/profile_manager/darkdetect/__init__.py b/profile_manager/darkdetect/__init__.py
index 4cce200..b508452 100644
--- a/profile_manager/darkdetect/__init__.py
+++ b/profile_manager/darkdetect/__init__.py
@@ -1,22 +1,23 @@
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# Copyright (C) 2019 Alberto Sottile
#
# Distributed under the terms of the 3-clause BSD License.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
-__version__ = '0.1.1'
+__version__ = "0.1.1"
-import sys
import platform
+import sys
if sys.platform != "darwin":
from ._dummy import *
else:
from distutils.version import LooseVersion as V
+
if V(platform.mac_ver()[0]) < V("10.14"):
from ._dummy import *
else:
from ._detect import *
del V
-del sys, platform
\ No newline at end of file
+del sys, platform
diff --git a/profile_manager/darkdetect/_detect.py b/profile_manager/darkdetect/_detect.py
index 9a79f7c..cc6dbbf 100644
--- a/profile_manager/darkdetect/_detect.py
+++ b/profile_manager/darkdetect/_detect.py
@@ -1,14 +1,14 @@
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# Copyright (C) 2019 Alberto Sottile
#
# Distributed under the terms of the 3-clause BSD License.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
import ctypes
import ctypes.util
-appkit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('AppKit'))
-objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc'))
+appkit = ctypes.cdll.LoadLibrary(ctypes.util.find_library("AppKit"))
+objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("objc"))
void_p = ctypes.c_void_p
ull = ctypes.c_uint64
@@ -20,45 +20,51 @@
msg = objc.objc_msgSend
+
def _utf8(s):
if not isinstance(s, bytes):
- s = s.encode('utf8')
+ s = s.encode("utf8")
return s
+
def n(name):
return objc.sel_registerName(_utf8(name))
+
def C(classname):
return objc.objc_getClass(_utf8(classname))
+
def theme():
- NSAutoreleasePool = objc.objc_getClass('NSAutoreleasePool')
- pool = msg(NSAutoreleasePool, n('alloc'))
- pool = msg(pool, n('init'))
+ NSAutoreleasePool = objc.objc_getClass("NSAutoreleasePool")
+ pool = msg(NSAutoreleasePool, n("alloc"))
+ pool = msg(pool, n("init"))
- NSUserDefaults = C('NSUserDefaults')
- stdUserDef = msg(NSUserDefaults, n('standardUserDefaults'))
+ NSUserDefaults = C("NSUserDefaults")
+ stdUserDef = msg(NSUserDefaults, n("standardUserDefaults"))
- NSString = C('NSString')
+ NSString = C("NSString")
- key = msg(NSString, n("stringWithUTF8String:"), _utf8('AppleInterfaceStyle'))
- appearanceNS = msg(stdUserDef, n('stringForKey:'), void_p(key))
- appearanceC = msg(appearanceNS, n('UTF8String'))
+ key = msg(NSString, n("stringWithUTF8String:"), _utf8("AppleInterfaceStyle"))
+ appearanceNS = msg(stdUserDef, n("stringForKey:"), void_p(key))
+ appearanceC = msg(appearanceNS, n("UTF8String"))
if appearanceC is not None:
out = ctypes.string_at(appearanceC)
else:
out = None
- msg(pool, n('release'))
+ msg(pool, n("release"))
if out is not None:
- return out.decode('utf-8')
+ return out.decode("utf-8")
else:
- return 'Light'
+ return "Light"
+
def isDark():
- return theme() == 'Dark'
+ return theme() == "Dark"
+
def isLight():
- return theme() == 'Light'
+ return theme() == "Light"
diff --git a/profile_manager/darkdetect/_dummy.py b/profile_manager/darkdetect/_dummy.py
index 1e99668..f256724 100644
--- a/profile_manager/darkdetect/_dummy.py
+++ b/profile_manager/darkdetect/_dummy.py
@@ -1,14 +1,17 @@
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
# Copyright (C) 2019 Alberto Sottile
#
# Distributed under the terms of the 3-clause BSD License.
-#-----------------------------------------------------------------------------
+# -----------------------------------------------------------------------------
+
def theme():
return None
-
+
+
def isDark():
return None
-
+
+
def isLight():
return None
diff --git a/profile_manager/datasources/Bookmarks/__init__.py b/profile_manager/datasources/Bookmarks/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Bookmarks/bookmark_handler.py b/profile_manager/datasources/Bookmarks/bookmark_handler.py
index 30d1e65..7ffa314 100644
--- a/profile_manager/datasources/Bookmarks/bookmark_handler.py
+++ b/profile_manager/datasources/Bookmarks/bookmark_handler.py
@@ -1,6 +1,6 @@
-from lxml import etree as et
from pathlib import Path
+from lxml import etree as et
from qgis.core import Qgis, QgsMessageLog
@@ -26,22 +26,28 @@ def import_bookmarks(source_bookmark_file: str, target_bookmark_file: str):
# get the element tree of the source file
QgsMessageLog.logMessage("import_bookmarks", "Profile Manager", level=Qgis.Critical)
try:
- source_tree = et.parse(source_bookmark_file, et.XMLParser(remove_blank_text=True))
+ source_tree = et.parse(
+ source_bookmark_file, et.XMLParser(remove_blank_text=True)
+ )
# check if target file exists
create_bookmark_file_if_not_exist(target_bookmark_file)
# get the element tree of the target file
# fill if empty
- target_tree = et.parse(target_bookmark_file, et.XMLParser(remove_blank_text=True))
+ target_tree = et.parse(
+ target_bookmark_file, et.XMLParser(remove_blank_text=True)
+ )
# find all bookmark elements
- source_root_tag = source_tree.findall('Bookmark')
+ source_root_tag = source_tree.findall("Bookmark")
# get the root element "Bookmarks"
target_tree_root = target_tree.getroot()
# Remove duplicate entries to prevent piling data
- target_tree_root = remove_duplicates(source_root_tag, target_tree, target_tree_root)
+ target_tree_root = remove_duplicates(
+ source_root_tag, target_tree, target_tree_root
+ )
# append the elements
for element in source_root_tag:
@@ -49,7 +55,10 @@ def import_bookmarks(source_bookmark_file: str, target_bookmark_file: str):
# overwrite the xml file
et.ElementTree(target_tree_root).write(
- target_bookmark_file, pretty_print=True, encoding='utf-8', xml_declaration=True
+ target_bookmark_file,
+ pretty_print=True,
+ encoding="utf-8",
+ xml_declaration=True,
)
except et.Error as e:
# TODO: It would be nice to have a smaller and more specific try block but until then we except broadly
@@ -57,12 +66,13 @@ def import_bookmarks(source_bookmark_file: str, target_bookmark_file: str):
QgsMessageLog.logMessage(error, "Profile Manager", level=Qgis.Warning)
return error
+
def remove_duplicates(source_root_tag, target_tree, target_tree_root):
"""Removes bookmarks from target that exist in the (to be imported) source too."""
# TODO FIXME this only checks the name of the bookmarks which will lead to false positives
# it is ok and supported by QGIS to have the same name for multiple bookmarks
# TODO compare the complete content of the xml node!
- target_root_tag = target_tree.findall('Bookmark')
+ target_root_tag = target_tree.findall("Bookmark")
for s_element in source_root_tag:
for t_element in target_root_tag:
if s_element.attrib["name"] == t_element.attrib["name"]:
@@ -70,10 +80,10 @@ def remove_duplicates(source_root_tag, target_tree, target_tree_root):
return target_tree_root
+
def create_bookmark_file_if_not_exist(bookmark_file):
"""Checks if file exists and creates it if not"""
target_file = Path(bookmark_file)
if not target_file.is_file():
with open(bookmark_file, "w") as new_file:
new_file.write("")
-
diff --git a/profile_manager/datasources/Customizations/__init__.py b/profile_manager/datasources/Customizations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Customizations/customization_handler.py b/profile_manager/datasources/Customizations/customization_handler.py
index 163d8e6..36b689b 100644
--- a/profile_manager/datasources/Customizations/customization_handler.py
+++ b/profile_manager/datasources/Customizations/customization_handler.py
@@ -2,7 +2,7 @@
from os import path
from shutil import copy2
-from ...utils import adjust_to_operating_system
+from profile_manager.utils import adjust_to_operating_system
def import_customizations(source_profile_path: str, target_profile_path: str):
@@ -22,22 +22,30 @@ def import_customizations(source_profile_path: str, target_profile_path: str):
TODO
"""
# Copy (overwrite) the QGISCUSTOMIZATION3.ini if exist
- source_customini_path = adjust_to_operating_system(source_profile_path + "QGIS/QGISCUSTOMIZATION3.ini")
- target_customini_path = adjust_to_operating_system(target_profile_path + "QGIS/QGISCUSTOMIZATION3.ini")
+ source_customini_path = adjust_to_operating_system(
+ source_profile_path + "QGIS/QGISCUSTOMIZATION3.ini"
+ )
+ target_customini_path = adjust_to_operating_system(
+ target_profile_path + "QGIS/QGISCUSTOMIZATION3.ini"
+ )
if path.exists(source_customini_path):
copy2(source_customini_path, target_customini_path)
# Copy [UI] section from QGIS3.ini
- source_qgis3ini_path = adjust_to_operating_system(source_profile_path + "QGIS/QGIS3.ini")
- target_qgis3ini_path = adjust_to_operating_system(target_profile_path + "QGIS/QGIS3.ini")
+ source_qgis3ini_path = adjust_to_operating_system(
+ source_profile_path + "QGIS/QGIS3.ini"
+ )
+ target_qgis3ini_path = adjust_to_operating_system(
+ target_profile_path + "QGIS/QGIS3.ini"
+ )
source_ini_parser = RawConfigParser()
source_ini_parser.optionxform = str # str = case-sensitive option names
source_ini_parser.read(source_qgis3ini_path)
# TODO this is broken, right? It looks for [UI] but even in QGIS 3.10 (didnt check older) the (single) section is named [Customization]
- if source_ini_parser.has_section('UI'):
- ui_data = dict(source_ini_parser.items('UI'))
+ if source_ini_parser.has_section("UI"):
+ ui_data = dict(source_ini_parser.items("UI"))
target_ini_parser = RawConfigParser()
target_ini_parser.optionxform = str # str = case-sensitive option names
@@ -49,6 +57,5 @@ def import_customizations(source_profile_path: str, target_profile_path: str):
target_ini_parser.set("UI", setting, ui_data[setting])
- with open(target_qgis3ini_path, 'w') as qgisconf:
+ with open(target_qgis3ini_path, "w") as qgisconf:
target_ini_parser.write(qgisconf, space_around_delimiters=False)
-
diff --git a/profile_manager/datasources/Dataservices/__init__.py b/profile_manager/datasources/Dataservices/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Dataservices/datasource_distributor.py b/profile_manager/datasources/Dataservices/datasource_distributor.py
index 077396a..2288de3 100644
--- a/profile_manager/datasources/Dataservices/datasource_distributor.py
+++ b/profile_manager/datasources/Dataservices/datasource_distributor.py
@@ -1,8 +1,7 @@
from configparser import RawConfigParser
from urllib.parse import quote
-from ...utils import adjust_to_operating_system
-
+from profile_manager.utils import adjust_to_operating_system
KNOWN_WEB_SOURCES = [
"Vector-Tile",
@@ -15,14 +14,18 @@
"GeoNode",
] # must match the names in data source provider's DATA_SOURCE_SEARCH_LOCATIONS. TODO re-use a single rules object!
+
def import_data_sources(
- source_qgis_ini_file: str,
- target_qgis_ini_file: str,
- dictionary_of_checked_database_sources: dict,
- dictionary_of_checked_web_sources: dict
+ source_qgis_ini_file: str,
+ target_qgis_ini_file: str,
+ dictionary_of_checked_database_sources: dict,
+ dictionary_of_checked_web_sources: dict,
):
"""Handles data source import"""
- dictionary_of_checked_sources = {**dictionary_of_checked_database_sources, **dictionary_of_checked_web_sources}
+ dictionary_of_checked_sources = {
+ **dictionary_of_checked_database_sources,
+ **dictionary_of_checked_web_sources,
+ }
if dictionary_of_checked_sources:
source_qgis_ini_file = adjust_to_operating_system(source_qgis_ini_file)
@@ -40,30 +43,42 @@ def import_data_sources(
iterator = 0
if key in KNOWN_WEB_SOURCES:
- if source_ini_parser.has_section('qgis'):
+ if source_ini_parser.has_section("qgis"):
for element in range(len(dictionary_of_checked_web_sources[key])):
import_web_sources(
- source_ini_parser, target_ini_parser, dictionary_of_checked_web_sources, key, iterator
+ source_ini_parser,
+ target_ini_parser,
+ dictionary_of_checked_web_sources,
+ key,
+ iterator,
)
iterator += 1
else:
# seems to be a database source
for element in range(len(dictionary_of_checked_database_sources[key])):
import_db_sources(
- source_ini_parser, target_ini_parser, dictionary_of_checked_database_sources, key, iterator
+ source_ini_parser,
+ target_ini_parser,
+ dictionary_of_checked_database_sources,
+ key,
+ iterator,
)
iterator += 1
- with open(target_qgis_ini_file, 'w') as qgisconf:
+ with open(target_qgis_ini_file, "w") as qgisconf:
target_ini_parser.write(qgisconf, space_around_delimiters=False)
+
def remove_data_sources(
- qgis_ini_file: str,
- dictionary_of_checked_database_sources: dict,
- dictionary_of_checked_web_sources: dict
+ qgis_ini_file: str,
+ dictionary_of_checked_database_sources: dict,
+ dictionary_of_checked_web_sources: dict,
):
"""Handles data source removal from file"""
- dictionary_of_checked_sources = {**dictionary_of_checked_database_sources, **dictionary_of_checked_web_sources}
+ dictionary_of_checked_sources = {
+ **dictionary_of_checked_database_sources,
+ **dictionary_of_checked_web_sources,
+ }
qgis_ini_file = adjust_to_operating_system(qgis_ini_file)
@@ -76,25 +91,30 @@ def remove_data_sources(
iterator = 0
if key in KNOWN_WEB_SOURCES:
- if parser.has_section('qgis'):
+ if parser.has_section("qgis"):
for element in range(len(dictionary_of_checked_web_sources[key])):
- remove_web_sources(parser, dictionary_of_checked_web_sources, key, iterator)
+ remove_web_sources(
+ parser, dictionary_of_checked_web_sources, key, iterator
+ )
iterator += 1
else:
# seems to be a database source
for element in range(len(dictionary_of_checked_database_sources[key])):
- remove_db_sources(parser, dictionary_of_checked_database_sources, key, iterator)
+ remove_db_sources(
+ parser, dictionary_of_checked_database_sources, key, iterator
+ )
iterator += 1
- with open(qgis_ini_file, 'w') as qgisconf:
+ with open(qgis_ini_file, "w") as qgisconf:
parser.write(qgisconf, space_around_delimiters=False)
+
def import_web_sources(
- source_ini_parser: RawConfigParser,
- target_ini_parser: RawConfigParser,
- dictionary_of_checked_web_sources: dict, # TODO specify internal structure, TODO rename
- key: str,
- iterator: int,
+ source_ini_parser: RawConfigParser,
+ target_ini_parser: RawConfigParser,
+ dictionary_of_checked_web_sources: dict, # TODO specify internal structure, TODO rename
+ key: str,
+ iterator: int,
):
"""Imports web source strings to target file"""
@@ -115,30 +135,37 @@ def import_web_sources(
# filter to all entries matching the provider key (e. g. wms)
to_be_imported_dictionary_sources = dict(
# FIXME store the key to lookup separately to allow different GUI display vs technical implementation
- filter(lambda item: str("connections-" + key.lower()) in item[0], to_be_imported_dictionary_sources.items())
+ filter(
+ lambda item: str("connections-" + key.lower()) in item[0],
+ to_be_imported_dictionary_sources.items(),
+ )
)
# filter to all remaining entries matching the data source name
to_be_imported_dictionary_sources = dict(
filter(
- lambda item: "\\" + quote(
- dictionary_of_checked_web_sources[key][iterator].encode('latin-1')
- ) + "\\" in item[0],
- to_be_imported_dictionary_sources.items()
+ lambda item: "\\"
+ + quote(dictionary_of_checked_web_sources[key][iterator].encode("latin-1"))
+ + "\\"
+ in item[0],
+ to_be_imported_dictionary_sources.items(),
)
)
for data_source in to_be_imported_dictionary_sources:
if not target_ini_parser.has_section("qgis"):
target_ini_parser["qgis"] = {}
- target_ini_parser.set("qgis", data_source, to_be_imported_dictionary_sources[data_source])
+ target_ini_parser.set(
+ "qgis", data_source, to_be_imported_dictionary_sources[data_source]
+ )
+
def import_db_sources(
- source_ini_parser: RawConfigParser,
- target_ini_parser: RawConfigParser,
- dictionary_of_checked_database_sources: dict, # TODO specify internal structure, TODO rename
- key: str,
- iterator: int,
+ source_ini_parser: RawConfigParser,
+ target_ini_parser: RawConfigParser,
+ dictionary_of_checked_database_sources: dict, # TODO specify internal structure, TODO rename
+ key: str,
+ iterator: int,
):
"""Imports data base strings to target file"""
@@ -148,23 +175,29 @@ def import_db_sources(
# filter to all remaining entries matching the data source name
to_be_imported_dictionary_sources = dict(
filter(
- lambda item: "\\" + quote(
- dictionary_of_checked_database_sources[key][iterator].encode('latin-1')
- ) + "\\" in item[0],
- to_be_imported_dictionary_sources.items()
+ lambda item: "\\"
+ + quote(
+ dictionary_of_checked_database_sources[key][iterator].encode("latin-1")
+ )
+ + "\\"
+ in item[0],
+ to_be_imported_dictionary_sources.items(),
)
)
for data_source in to_be_imported_dictionary_sources:
if not target_ini_parser.has_section(key):
target_ini_parser[key] = {}
- target_ini_parser.set(key, data_source, to_be_imported_dictionary_sources[data_source])
+ target_ini_parser.set(
+ key, data_source, to_be_imported_dictionary_sources[data_source]
+ )
+
def remove_web_sources(
- parser: RawConfigParser,
- dictionary_of_checked_web_sources: dict, # TODO specify internal structure, TODO rename
- key: str,
- iterator: int,
+ parser: RawConfigParser,
+ dictionary_of_checked_web_sources: dict, # TODO specify internal structure, TODO rename
+ key: str,
+ iterator: int,
):
"""Removes web source strings from target file"""
@@ -173,27 +206,32 @@ def remove_web_sources(
# filter to all entries matching the provider key (e. g. wms)
to_be_deleted_dictionary_sources = dict(
- filter(lambda item: str("connections-" + key.lower()) in item[0], to_be_deleted_dictionary_sources.items())
+ filter(
+ lambda item: str("connections-" + key.lower()) in item[0],
+ to_be_deleted_dictionary_sources.items(),
+ )
)
# filter to all remaining entries matching the data source name
to_be_deleted_dictionary_sources = dict(
filter(
- lambda item: "\\" + quote(
- dictionary_of_checked_web_sources[key][iterator].encode('latin-1')
- ) + "\\" in item[0],
- to_be_deleted_dictionary_sources.items()
+ lambda item: "\\"
+ + quote(dictionary_of_checked_web_sources[key][iterator].encode("latin-1"))
+ + "\\"
+ in item[0],
+ to_be_deleted_dictionary_sources.items(),
)
)
for data_source in to_be_deleted_dictionary_sources:
parser.remove_option("qgis", data_source)
+
def remove_db_sources(
- parser: RawConfigParser,
- dictionary_of_checked_database_sources: dict, # TODO specify internal structure, TODO rename
- key: str,
- iterator: int
+ parser: RawConfigParser,
+ dictionary_of_checked_database_sources: dict, # TODO specify internal structure, TODO rename
+ key: str,
+ iterator: int,
):
"""Remove data base sources from target file"""
@@ -203,10 +241,13 @@ def remove_db_sources(
# filter to all remaining entries matching the data source name
to_be_deleted_dictionary_sources = dict(
filter(
- lambda item: "\\" + quote(
- dictionary_of_checked_database_sources[key][iterator].encode('latin-1')
- ) + "\\" in item[0],
- to_be_deleted_dictionary_sources.items()
+ lambda item: "\\"
+ + quote(
+ dictionary_of_checked_database_sources[key][iterator].encode("latin-1")
+ )
+ + "\\"
+ in item[0],
+ to_be_deleted_dictionary_sources.items(),
)
)
diff --git a/profile_manager/datasources/Dataservices/datasource_handler.py b/profile_manager/datasources/Dataservices/datasource_handler.py
index 0620855..197078e 100644
--- a/profile_manager/datasources/Dataservices/datasource_handler.py
+++ b/profile_manager/datasources/Dataservices/datasource_handler.py
@@ -1,14 +1,23 @@
-from PyQt5.QtWidgets import QMessageBox
-from .datasource_distributor import import_data_sources, remove_data_sources
-from ..Bookmarks.bookmark_handler import import_bookmarks
-from ..Customizations.customization_handler import import_customizations
-from ..Favourites.favourites_handler import import_favourites
-from ..Functions.function_handler import import_expression_functions
-from ..Models.model_handler import import_models
-from ..Models.script_handler import import_scripts
-from ..Plugins.plugin_handler import PluginHandler
-from ..Styles.style_handler import import_styles
-from ...utils import adjust_to_operating_system
+from qgis.PyQt.QtWidgets import QMessageBox
+
+from profile_manager.datasources.Bookmarks.bookmark_handler import import_bookmarks
+from profile_manager.datasources.Customizations.customization_handler import (
+ import_customizations,
+)
+from profile_manager.datasources.Dataservices.datasource_distributor import (
+ import_data_sources,
+ remove_data_sources,
+)
+from profile_manager.datasources.Favourites.favourites_handler import import_favourites
+from profile_manager.datasources.Functions.function_handler import (
+ import_expression_functions,
+)
+from profile_manager.datasources.Models.model_handler import import_models
+from profile_manager.datasources.Models.script_handler import import_scripts
+from profile_manager.datasources.Plugins.plugin_handler import PluginHandler
+from profile_manager.datasources.Styles.style_handler import import_styles
+from profile_manager.utils import adjust_to_operating_system
+
class DataSourceHandler:
@@ -26,10 +35,14 @@ def __init__(self, profile_manager_dialog, profile_manager):
self.target_bookmark_file = ""
self.plugin_handler = PluginHandler(self.profile_manager)
- def set_data_sources(self, dictionary_of_checked_web_sources, dictionary_of_checked_data_base_sources):
+ def set_data_sources(
+ self, dictionary_of_checked_web_sources, dictionary_of_checked_data_base_sources
+ ):
"""Sets data sources"""
self.dictionary_of_checked_web_sources = dictionary_of_checked_web_sources
- self.dictionary_of_checked_data_base_sources = dictionary_of_checked_data_base_sources
+ self.dictionary_of_checked_data_base_sources = (
+ dictionary_of_checked_data_base_sources
+ )
def import_all_the_things(self):
# TODO rename
@@ -47,40 +60,64 @@ def import_all_the_things(self):
self.dictionary_of_checked_data_base_sources,
)
- self.profile_manager.update_data_sources(False) # TODO moved from DS_D.import_data_sources, do we really need it?!
+ self.profile_manager.update_data_sources(
+ False
+ ) # TODO moved from DS_D.import_data_sources, do we really need it?!
if self.dlg.bookmark_check.isChecked():
- error_message = import_bookmarks(self.source_bookmark_file, self.target_bookmark_file)
+ error_message = import_bookmarks(
+ self.source_bookmark_file, self.target_bookmark_file
+ )
if error_message:
had_errors = True
- QMessageBox.critical(None, "Error while importing bookmarks", error_message)
+ QMessageBox.critical(
+ None, "Error while importing bookmarks", error_message
+ )
if self.dlg.favourites_check.isChecked():
- error_message = import_favourites(self.source_qgis_ini_file, self.target_qgis_ini_file)
+ error_message = import_favourites(
+ self.source_qgis_ini_file, self.target_qgis_ini_file
+ )
if error_message:
had_errors = True
- QMessageBox.critical(None, "Error while importing favourites", error_message)
+ QMessageBox.critical(
+ None, "Error while importing favourites", error_message
+ )
if self.dlg.models_check.isChecked():
- import_models(self.source_profile_path, self.target_profile_path) # currently has no error handling
+ import_models(
+ self.source_profile_path, self.target_profile_path
+ ) # currently has no error handling
if self.dlg.scripts_check.isChecked():
- import_scripts(self.source_profile_path, self.target_profile_path) # currently has no error handling
+ import_scripts(
+ self.source_profile_path, self.target_profile_path
+ ) # currently has no error handling
if self.dlg.styles_check.isChecked():
- error_message = import_styles(self.source_profile_path, self.target_profile_path)
+ error_message = import_styles(
+ self.source_profile_path, self.target_profile_path
+ )
if error_message:
had_errors = True
- QMessageBox.critical(None, "Error while importing styles", error_message)
+ QMessageBox.critical(
+ None, "Error while importing styles", error_message
+ )
if self.dlg.functions_check.isChecked():
- error_message = import_expression_functions(self.source_qgis_ini_file, self.target_qgis_ini_file)
+ error_message = import_expression_functions(
+ self.source_qgis_ini_file, self.target_qgis_ini_file
+ )
if error_message:
had_errors = True
- QMessageBox.critical(None, "Error while importing expression functions", error_message)
+ QMessageBox.critical(
+ None, "Error while importing expression functions", error_message
+ )
if self.dlg.ui_check.isChecked():
- import_customizations(self.source_profile_path, self.target_profile_path) # currently has no error handling
+ import_customizations(
+ self.source_profile_path, self.target_profile_path
+ ) # currently has no error handling
# TODO why does data source import also import plugins again?
self.plugin_handler.import_selected_plugins()
@@ -93,7 +130,9 @@ def import_plugins(self):
def display_plugins(self, only_for_target_profile=False):
"""Displays plugins in treeWidget"""
self.plugin_handler.set_path_files()
- self.plugin_handler.populate_plugins_list(only_for_target_profile=only_for_target_profile)
+ self.plugin_handler.populate_plugins_list(
+ only_for_target_profile=only_for_target_profile
+ )
def remove_datasources_and_plugins(self):
"""Handles data removal"""
@@ -105,20 +144,28 @@ def remove_datasources_and_plugins(self):
self.dictionary_of_checked_data_base_sources,
)
- self.profile_manager.update_data_sources(False) # TODO moved from DS_D.remove_data_sources, do we really need it?!
+ self.profile_manager.update_data_sources(
+ False
+ ) # TODO moved from DS_D.remove_data_sources, do we really need it?!
def set_path_to_files(self, source_profile_name, target_profile_name):
"""Sets file paths"""
ini_paths = self.profile_manager.get_ini_paths()
- self.source_qgis_ini_file = ini_paths['source']
- self.target_qgis_ini_file = ini_paths['target']
+ self.source_qgis_ini_file = ini_paths["source"]
+ self.target_qgis_ini_file = ini_paths["target"]
- self.source_profile_path = adjust_to_operating_system(self.qgis_path + '/' + source_profile_name + '/')
- self.target_profile_path = adjust_to_operating_system(self.qgis_path + '/' + target_profile_name + '/')
+ self.source_profile_path = adjust_to_operating_system(
+ self.qgis_path + "/" + source_profile_name + "/"
+ )
+ self.target_profile_path = adjust_to_operating_system(
+ self.qgis_path + "/" + target_profile_name + "/"
+ )
def set_path_to_bookmark_files(self, source_profile_name, target_profile_name):
"""Sets file paths"""
self.source_bookmark_file = adjust_to_operating_system(
- self.qgis_path + '/' + source_profile_name + '/' + 'bookmarks.xml')
+ self.qgis_path + "/" + source_profile_name + "/" + "bookmarks.xml"
+ )
self.target_bookmark_file = adjust_to_operating_system(
- self.qgis_path + '/' + target_profile_name + '/' + 'bookmarks.xml')
+ self.qgis_path + "/" + target_profile_name + "/" + "bookmarks.xml"
+ )
diff --git a/profile_manager/datasources/Dataservices/datasource_provider.py b/profile_manager/datasources/Dataservices/datasource_provider.py
index 15f1b5c..b0fb689 100644
--- a/profile_manager/datasources/Dataservices/datasource_provider.py
+++ b/profile_manager/datasources/Dataservices/datasource_provider.py
@@ -2,14 +2,13 @@
from re import compile, search
from urllib.parse import unquote
+from qgis.core import Qgis, QgsMessageLog
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import QTreeWidgetItem
-from qgis.core import Qgis, QgsMessageLog
-
# TODO document these! can we directly integrate them below somewhere?
-SERVICE_NAME_REGEX = compile(r'\\(.*?)\\')
-GPKG_SERVICE_NAME_REGEX = compile(r'\\(.+).\\')
+SERVICE_NAME_REGEX = compile(r"\\(.*?)\\")
+GPKG_SERVICE_NAME_REGEX = compile(r"\\(.+).\\")
"""
"providername-ish": [ # a list of searching rules, not just one, because qgis changed between versions
@@ -109,7 +108,9 @@
}
-def get_data_sources_tree(ini_path: str, provider: str, make_checkable: bool) -> QTreeWidgetItem:
+def get_data_sources_tree(
+ ini_path: str, provider: str, make_checkable: bool
+) -> QTreeWidgetItem:
"""Returns a tree of checkable items for all data sources of the specified provider in the INI file.
The tree contains a checkable item per data source found.
@@ -124,16 +125,22 @@ def get_data_sources_tree(ini_path: str, provider: str, make_checkable: bool) ->
"""
data_source_connections = gather_data_source_connections(ini_path, provider)
if not data_source_connections:
- QgsMessageLog.logMessage(f"- 0 {provider} connections found", "Profile Manager", Qgis.Info)
+ QgsMessageLog.logMessage(
+ f"- 0 {provider} connections found", "Profile Manager", Qgis.Info
+ )
return None
else:
QgsMessageLog.logMessage(
- f"- {len(data_source_connections)} {provider} connections found", "Profile Manager", Qgis.Info
+ f"- {len(data_source_connections)} {provider} connections found",
+ "Profile Manager",
+ Qgis.Info,
)
tree_root_item = QTreeWidgetItem([provider])
if make_checkable:
- tree_root_item.setFlags(tree_root_item.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
+ tree_root_item.setFlags(
+ tree_root_item.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable
+ )
data_source_items = []
for data_source_connection in data_source_connections:
@@ -146,6 +153,7 @@ def get_data_sources_tree(ini_path: str, provider: str, make_checkable: bool) ->
tree_root_item.addChildren(data_source_items)
return tree_root_item
+
def gather_data_source_connections(ini_path: str, provider: str) -> list[str]:
"""Returns the names of all data source connections of the specified provider in the INI file.
@@ -181,16 +189,24 @@ def gather_data_source_connections(ini_path: str, provider: str) -> list[str]:
regex_pattern = compile(regex)
for key in section:
if regex_pattern.search(key):
- if provider == "GeoPackage": # TODO move this logic/condition into the rules if possible?
+ if (
+ provider == "GeoPackage"
+ ): # TODO move this logic/condition into the rules if possible?
source_name_raw = search(GPKG_SERVICE_NAME_REGEX, key)
- source_name = source_name_raw.group(0).replace("\\GPKG\\connections\\", "").replace("\\", "")
+ source_name = (
+ source_name_raw.group(0)
+ .replace("\\GPKG\\connections\\", "")
+ .replace("\\", "")
+ )
else:
source_name_raw = search(SERVICE_NAME_REGEX, key)
source_name = source_name_raw.group(0).replace("\\", "")
# TODO what are the replacements needed for?!
# TODO "Bing VirtualEarth 💩" is not rendered well, also fails to import to other profile...
- source_name = unquote(source_name, 'latin-1') # needed for e.g. %20 in connection names
+ source_name = unquote(
+ source_name, "latin-1"
+ ) # needed for e.g. %20 in connection names
data_source_connections.append(source_name)
return data_source_connections
diff --git a/profile_manager/datasources/Favourites/__init__.py b/profile_manager/datasources/Favourites/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Favourites/favourites_handler.py b/profile_manager/datasources/Favourites/favourites_handler.py
index 4e348a7..eb26a7c 100644
--- a/profile_manager/datasources/Favourites/favourites_handler.py
+++ b/profile_manager/datasources/Favourites/favourites_handler.py
@@ -41,11 +41,15 @@ def import_favourites(source_qgis_ini_file, target_qgis_ini_file):
elif target_ini_parser.has_option("browser", "favourites"):
favourites_to_be_preserved = target_ini_parser.get("browser", "favourites")
- import_string = favourites_to_be_imported["favourites"].replace(favourites_to_be_preserved, "")
+ import_string = favourites_to_be_imported["favourites"].replace(
+ favourites_to_be_preserved, ""
+ )
- target_ini_parser.set("browser", "favourites", favourites_to_be_preserved + import_string)
+ target_ini_parser.set(
+ "browser", "favourites", favourites_to_be_preserved + import_string
+ )
- with open(target_qgis_ini_file, 'w') as qgisconf:
+ with open(target_qgis_ini_file, "w") as qgisconf:
target_ini_parser.write(qgisconf, space_around_delimiters=False)
except Exception as e:
# TODO: It would be nice to have a smaller and more specific try block but until then we except broadly
diff --git a/profile_manager/datasources/Functions/__init__.py b/profile_manager/datasources/Functions/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Functions/function_handler.py b/profile_manager/datasources/Functions/function_handler.py
index e6b8148..dced917 100644
--- a/profile_manager/datasources/Functions/function_handler.py
+++ b/profile_manager/datasources/Functions/function_handler.py
@@ -3,8 +3,6 @@
from qgis.core import Qgis, QgsMessageLog
-
-
def import_expression_functions(source_qgis_ini_file: str, target_qgis_ini_file: str):
"""Imports custom expression functions from source to target profile.
@@ -25,7 +23,9 @@ def import_expression_functions(source_qgis_ini_file: str, target_qgis_ini_file:
Returns:
error_message (str): An error message, if something failed.
"""
- QgsMessageLog.logMessage(f"Importing expression functions...", "Profile Manager", Qgis.Info)
+ QgsMessageLog.logMessage(
+ "Importing expression functions...", "Profile Manager", Qgis.Info
+ )
source_ini_parser = RawConfigParser()
source_ini_parser.optionxform = str # str = case-sensitive option names
@@ -44,9 +44,11 @@ def import_expression_functions(source_qgis_ini_file: str, target_qgis_ini_file:
for entry in get_functions:
if "expression" in entry or "helpText" in entry:
target_ini_parser.set("expressions", entry, get_functions[entry])
- QgsMessageLog.logMessage(f"Found '{entry}'", "Profile Manager", Qgis.Info)
+ QgsMessageLog.logMessage(
+ f"Found '{entry}'", "Profile Manager", Qgis.Info
+ )
- with open(target_qgis_ini_file, 'w') as qgisconf:
+ with open(target_qgis_ini_file, "w") as qgisconf:
target_ini_parser.write(qgisconf, space_around_delimiters=False)
except Exception as e:
# TODO: It would be nice to have a smaller and more specific try block but until then we except broadly
diff --git a/profile_manager/datasources/Models/__init__.py b/profile_manager/datasources/Models/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Plugins/__init__.py b/profile_manager/datasources/Plugins/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Plugins/plugin_handler.py b/profile_manager/datasources/Plugins/plugin_handler.py
index b883bf4..aa80d57 100644
--- a/profile_manager/datasources/Plugins/plugin_handler.py
+++ b/profile_manager/datasources/Plugins/plugin_handler.py
@@ -1,8 +1,8 @@
from qgis.PyQt.QtCore import Qt
-from .plugin_displayer import PluginDisplayer
-from .plugin_importer import import_plugins
-from .plugin_remover import remove_plugins
+from profile_manager.datasources.Plugins.plugin_displayer import PluginDisplayer
+from profile_manager.datasources.Plugins.plugin_importer import import_plugins
+from profile_manager.datasources.Plugins.plugin_remover import remove_plugins
class PluginHandler:
@@ -16,19 +16,32 @@ def __init__(self, profile_manager):
def populate_plugins_list(self, only_for_target_profile=False):
"""Gets active plugins from ini file and displays them in treeWidget"""
self.set_path_files()
- self.plugin_displayer.set_ini_paths(self.source_qgis_ini_file, self.target_qgis_ini_file)
- self.plugin_displayer.populate_plugins_list(only_populate_target_profile=only_for_target_profile)
+ self.plugin_displayer.set_ini_paths(
+ self.source_qgis_ini_file, self.target_qgis_ini_file
+ )
+ self.plugin_displayer.populate_plugins_list(
+ only_populate_target_profile=only_for_target_profile
+ )
def import_selected_plugins(self):
"""Import selected plugins into target profile"""
- source_profile_path, target_profile_path = self.profile_manager.get_profile_paths()
+ source_profile_path, target_profile_path = (
+ self.profile_manager.get_profile_paths()
+ )
plugin_names = []
- for item in self.profile_manager.dlg.list_plugins.findItems("", Qt.MatchContains | Qt.MatchRecursive):
+ for item in self.profile_manager.dlg.list_plugins.findItems(
+ "", Qt.MatchContains | Qt.MatchRecursive
+ ):
if item.checkState() == Qt.Checked:
plugin_names.append(item.text())
- import_plugins(source_profile_path, target_profile_path, self.target_qgis_ini_file, plugin_names)
+ import_plugins(
+ source_profile_path,
+ target_profile_path,
+ self.target_qgis_ini_file,
+ plugin_names,
+ )
self.populate_plugins_list()
def remove_selected_plugins(self):
@@ -36,7 +49,9 @@ def remove_selected_plugins(self):
source_profile_path, _ = self.profile_manager.get_profile_paths()
plugin_names = []
- for item in self.profile_manager.dlg.list_plugins.findItems("", Qt.MatchContains | Qt.MatchRecursive):
+ for item in self.profile_manager.dlg.list_plugins.findItems(
+ "", Qt.MatchContains | Qt.MatchRecursive
+ ):
if item.checkState() == Qt.Checked:
plugin_names.append(item.text())
diff --git a/profile_manager/datasources/Plugins/plugin_importer.py b/profile_manager/datasources/Plugins/plugin_importer.py
index 16e405b..fd1b2e1 100644
--- a/profile_manager/datasources/Plugins/plugin_importer.py
+++ b/profile_manager/datasources/Plugins/plugin_importer.py
@@ -3,14 +3,14 @@
from pathlib import Path
from shutil import copytree
-from ...utils import adjust_to_operating_system
+from profile_manager.utils import adjust_to_operating_system
def import_plugins(
- source_profile_path: str,
- target_profile_path: str,
- target_qgis_ini_file: str,
- plugin_names: list[str],
+ source_profile_path: str,
+ target_profile_path: str,
+ target_qgis_ini_file: str,
+ plugin_names: list[str],
):
"""Copies the specified plugins from source to target profile.
@@ -42,16 +42,22 @@ def import_plugins(
for plugin_name in plugin_names:
ini_parser.set("PythonPlugins", plugin_name, "true")
- source_plugin_dir = adjust_to_operating_system(source_profile_path + 'python/plugins/' + plugin_name + '/')
- target_plugin_dir = adjust_to_operating_system(target_profile_path + 'python/plugins/' + plugin_name + '/')
+ source_plugin_dir = adjust_to_operating_system(
+ source_profile_path + "python/plugins/" + plugin_name + "/"
+ )
+ target_plugin_dir = adjust_to_operating_system(
+ target_profile_path + "python/plugins/" + plugin_name + "/"
+ )
if path.exists(source_plugin_dir):
- if not path.exists(target_profile_path + 'python/plugins/'):
- Path(target_profile_path + 'python/plugins/').mkdir(parents=True, exist_ok=True)
+ if not path.exists(target_profile_path + "python/plugins/"):
+ Path(target_profile_path + "python/plugins/").mkdir(
+ parents=True, exist_ok=True
+ )
if not path.isdir(target_plugin_dir):
copytree(source_plugin_dir, target_plugin_dir)
else:
continue # TODO error, dont skip silently!
- with open(target_qgis_ini_file, 'w') as qgisconf:
+ with open(target_qgis_ini_file, "w") as qgisconf:
ini_parser.write(qgisconf, space_around_delimiters=False)
diff --git a/profile_manager/datasources/Plugins/plugin_remover.py b/profile_manager/datasources/Plugins/plugin_remover.py
index 0300f07..f79d4fd 100644
--- a/profile_manager/datasources/Plugins/plugin_remover.py
+++ b/profile_manager/datasources/Plugins/plugin_remover.py
@@ -3,13 +3,13 @@
from qgis.PyQt.QtWidgets import QMessageBox
-from ...utils import adjust_to_operating_system, tr
+from profile_manager.utils import adjust_to_operating_system, tr
def remove_plugins(
- profile_path: str,
- qgis_ini_file: str,
- plugin_names: list[str],
+ profile_path: str,
+ qgis_ini_file: str,
+ plugin_names: list[str],
):
"""Removes the specified plugins from the profile.
@@ -29,7 +29,9 @@ def remove_plugins(
if ini_parser.has_option("PythonPlugins", plugin_name):
ini_parser.remove_option("PythonPlugins", plugin_name)
- plugins_dir = adjust_to_operating_system(profile_path + 'python/plugins/' + plugin_name + '/')
+ plugins_dir = adjust_to_operating_system(
+ profile_path + "python/plugins/" + plugin_name + "/"
+ )
try:
rmtree(plugins_dir)
@@ -38,9 +40,11 @@ def remove_plugins(
QMessageBox.critical(
None,
tr("Plugin could not be removed"),
- tr("Plugin '{0}' could not be removed due to error:\n{1}").format(plugin_name, e)
+ tr("Plugin '{0}' could not be removed due to error:\n{1}").format(
+ plugin_name, e
+ ),
)
continue
- with open(qgis_ini_file, 'w') as qgisconf:
+ with open(qgis_ini_file, "w") as qgisconf:
ini_parser.write(qgisconf, space_around_delimiters=False)
diff --git a/profile_manager/datasources/Styles/__init__.py b/profile_manager/datasources/Styles/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/datasources/Styles/style_handler.py b/profile_manager/datasources/Styles/style_handler.py
index c9a7fed..6e6c9b0 100644
--- a/profile_manager/datasources/Styles/style_handler.py
+++ b/profile_manager/datasources/Styles/style_handler.py
@@ -1,5 +1,4 @@
import sqlite3
-
from os import path
from shutil import copy
@@ -35,14 +34,18 @@ def import_styles(source_profile_path: str, target_profile_path: str):
try:
# import label settings
- custom_labels = source_db_cursor.execute('SELECT * FROM labelsettings')
- target_db_cursor.executemany('INSERT OR REPLACE INTO labelsettings VALUES (?,?,?,?)', custom_labels)
+ custom_labels = source_db_cursor.execute("SELECT * FROM labelsettings")
+ target_db_cursor.executemany(
+ "INSERT OR REPLACE INTO labelsettings VALUES (?,?,?,?)", custom_labels
+ )
# import symbols
# FIXME: This has a hard-coded assumption that symbols with ids <= 115 are builtin symbols,
# this will fail as soon as a new builtin symbol is shipped by QGIS.
- custom_symbols = source_db_cursor.execute('SELECT * FROM symbol WHERE id>115')
- target_db_cursor.executemany('INSERT OR REPLACE INTO symbol VALUES (?,?,?,?)', custom_symbols)
+ custom_symbols = source_db_cursor.execute("SELECT * FROM symbol WHERE id>115")
+ target_db_cursor.executemany(
+ "INSERT OR REPLACE INTO symbol VALUES (?,?,?,?)", custom_symbols
+ )
source_db.commit()
target_db.commit()
diff --git a/profile_manager/datasources/__init__.py b/profile_manager/datasources/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/metadata.txt b/profile_manager/metadata.txt
similarity index 100%
rename from metadata.txt
rename to profile_manager/metadata.txt
diff --git a/profile_manager/profile_manager.py b/profile_manager/profile_manager.py
index 283cee3..a1405aa 100644
--- a/profile_manager/profile_manager.py
+++ b/profile_manager/profile_manager.py
@@ -20,6 +20,7 @@
* *
***************************************************************************/
"""
+
# Import the code for the dialog
import time
from collections import defaultdict
@@ -28,17 +29,26 @@
from shutil import copytree
from sys import platform
-from qgis.PyQt.QtCore import QCoreApplication, QLocale, QSettings, QSize, Qt, QTranslator
+from qgis.core import Qgis, QgsMessageLog, QgsUserProfileManager
+from qgis.PyQt.QtCore import (
+ QCoreApplication,
+ QLocale,
+ QSettings,
+ QSize,
+ Qt,
+ QTranslator,
+)
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction, QMessageBox, QWidget
-from qgis.core import Qgis, QgsMessageLog, QgsUserProfileManager
# Import subclasses
-from .datasources.Dataservices.datasource_handler import DataSourceHandler
-from .profile_manager_dialog import ProfileManagerDialog
-from .profiles.profile_action_handler import ProfileActionHandler
-from .userInterface.interface_handler import InterfaceHandler
-from .utils import adjust_to_operating_system, wait_cursor
+from profile_manager.datasources.Dataservices.datasource_handler import (
+ DataSourceHandler,
+)
+from profile_manager.profile_manager_dialog import ProfileManagerDialog
+from profile_manager.profiles.profile_action_handler import ProfileActionHandler
+from profile_manager.userInterface.interface_handler import InterfaceHandler
+from profile_manager.utils import adjust_to_operating_system, wait_cursor
class ProfileManager:
@@ -59,7 +69,9 @@ def __init__(self, iface):
self.qgis_profiles_path = ""
self.ini_path = ""
self.operating_system = ""
- self.qgs_profile_manager = None # TODO in QGIS 3.30 we could and should use iface.userProfileManager()
+ self.qgs_profile_manager = (
+ None # TODO in QGIS 3.30 we could and should use iface.userProfileManager()
+ )
self.data_source_handler: DataSourceHandler = None
self.profile_manager_action_handler: ProfileActionHandler = None
self.interface_handler: InterfaceHandler = None
@@ -71,11 +83,10 @@ def __init__(self, iface):
self.plugin_dir = path.dirname(__file__)
# initialize locale
- locale = QSettings().value('locale/userLocale', QLocale().name())[0:2]
+ locale = QSettings().value("locale/userLocale", QLocale().name())[0:2]
locale_path = path.join(
- self.plugin_dir,
- 'i18n',
- 'ProfileManager_{}.qm'.format(locale))
+ self.plugin_dir, "i18n", "ProfileManager_{}.qm".format(locale)
+ )
if path.exists(locale_path):
self.translator = QTranslator()
@@ -84,7 +95,7 @@ def __init__(self, iface):
# Declare instance attributes
self.actions = []
- self.menu = self.tr(u'&Profile Manager')
+ self.menu = self.tr("&Profile Manager")
# Check if plugin was started the first time in current QGIS session
# Must be set in initGui() to survive plugin reloads
@@ -103,19 +114,20 @@ def tr(self, message):
:rtype: QString
"""
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass
- return QCoreApplication.translate('ProfileManager', message)
+ return QCoreApplication.translate("ProfileManager", message)
def add_action(
- self,
- icon_path,
- text,
- callback,
- enabled_flag=True,
- add_to_menu=True,
- add_to_toolbar=True,
- status_tip=None,
- whats_this=None,
- parent=None):
+ self,
+ icon_path,
+ text,
+ callback,
+ enabled_flag=True,
+ add_to_menu=True,
+ add_to_toolbar=True,
+ status_tip=None,
+ whats_this=None,
+ parent=None,
+ ):
"""Add a toolbar icon to the toolbar.
:param icon_path: Path to the icon for this action. Can be a resource
@@ -171,9 +183,7 @@ def add_action(
self.iface.addToolBarIcon(action)
if add_to_menu:
- self.iface.addPluginToMenu(
- self.menu,
- action)
+ self.iface.addPluginToMenu(self.menu, action)
self.actions.append(action)
@@ -183,10 +193,11 @@ def initGui(self):
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
self.add_action(
- path.join(path.dirname(__file__), 'icon.png'),
- text=self.tr('Profile Manager'),
+ path.join(path.dirname(__file__), "icon.png"),
+ text=self.tr("Profile Manager"),
callback=self.run,
- parent=self.iface.mainWindow())
+ parent=self.iface.mainWindow(),
+ )
# will be set False in run()
self.first_start = True
@@ -194,9 +205,7 @@ def initGui(self):
def unload(self):
"""Removes the plugin menu item and icon from QGIS GUI."""
for action in self.actions:
- self.iface.removePluginMenu(
- self.tr('&Profile Manager'),
- action)
+ self.iface.removePluginMenu(self.tr("&Profile Manager"), action)
self.iface.removeToolBarIcon(action)
def run(self):
@@ -212,47 +221,72 @@ def run(self):
self.set_paths()
- self.qgs_profile_manager = QgsUserProfileManager(self.qgis_profiles_path)
+ self.qgs_profile_manager = QgsUserProfileManager(
+ self.qgis_profiles_path
+ )
self.data_source_handler = DataSourceHandler(self.dlg, self)
- self.profile_manager_action_handler = ProfileActionHandler(self.dlg, self.qgis_profiles_path, self)
+ self.profile_manager_action_handler = ProfileActionHandler(
+ self.dlg, self.qgis_profiles_path, self
+ )
self.interface_handler = InterfaceHandler(self, self.dlg)
self.interface_handler.setup_connections()
self.interface_handler.populate_profile_listings()
- self.interface_handler.populate_data_source_tree(self.dlg.comboBoxNamesSource.currentText(), True)
- self.interface_handler.populate_data_source_tree(self.dlg.comboBoxNamesTarget.currentText(), False)
+ self.interface_handler.populate_data_source_tree(
+ self.dlg.comboBoxNamesSource.currentText(), True
+ )
+ self.interface_handler.populate_data_source_tree(
+ self.dlg.comboBoxNamesTarget.currentText(), False
+ )
self.data_source_handler.set_path_to_files(
self.dlg.comboBoxNamesSource.currentText(),
- self.dlg.comboBoxNamesTarget.currentText()
+ self.dlg.comboBoxNamesTarget.currentText(),
)
self.data_source_handler.display_plugins()
-
self.dlg.exec()
def set_paths(self):
"""Sets various OS and profile dependent paths"""
home_path = Path.home()
- if platform.startswith('win32'):
- self.qgis_profiles_path = f'{home_path}/AppData/Roaming/QGIS/QGIS3/profiles'.replace("\\", "/")
- self.ini_path = \
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesSource.currentText() + "/QGIS/QGIS3.ini"
+ if platform.startswith("win32"):
+ self.qgis_profiles_path = (
+ f"{home_path}/AppData/Roaming/QGIS/QGIS3/profiles".replace("\\", "/")
+ )
+ self.ini_path = (
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesSource.currentText()
+ + "/QGIS/QGIS3.ini"
+ )
self.operating_system = "windows"
- elif platform is 'darwin':
- self.qgis_profiles_path = f'{home_path}/Library/Application Support/QGIS/QGIS3/profiles'
- self.ini_path = \
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesSource.currentText() + "/qgis.org/QGIS3.ini"
+ elif platform == "darwin":
+ self.qgis_profiles_path = (
+ f"{home_path}/Library/Application Support/QGIS/QGIS3/profiles"
+ )
+ self.ini_path = (
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesSource.currentText()
+ + "/qgis.org/QGIS3.ini"
+ )
self.operating_system = "mac"
self.interface_handler.adjust_to_macOSDark()
else:
- self.qgis_profiles_path = f'{home_path}/.local/share/QGIS/QGIS3/profiles'
- self.ini_path = \
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesSource.currentText() + "/QGIS/QGIS3.ini"
+ self.qgis_profiles_path = f"{home_path}/.local/share/QGIS/QGIS3/profiles"
+ self.ini_path = (
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesSource.currentText()
+ + "/QGIS/QGIS3.ini"
+ )
self.operating_system = "unix"
- self.backup_path = adjust_to_operating_system(str(Path.home()) + "/QGIS Profile Manager Backup/")
+ self.backup_path = adjust_to_operating_system(
+ str(Path.home()) + "/QGIS Profile Manager Backup/"
+ )
def make_backup(self, profile: str):
"""Creates a backup of the specified profile.
@@ -267,7 +301,9 @@ def make_backup(self, profile: str):
target_path = self.backup_path + str(ts)
source_path = f"{self.qgis_profiles_path}/{profile}"
QgsMessageLog.logMessage(
- f"Backing up profile '{source_path}' to '{target_path}'", "Profile Manager", level=Qgis.Info
+ f"Backing up profile '{source_path}' to '{target_path}'",
+ "Profile Manager",
+ level=Qgis.Info,
)
copytree(source_path, target_path)
@@ -281,18 +317,24 @@ def import_action_handler(self):
self.get_checked_sources()
source_profile_name = self.dlg.comboBoxNamesSource.currentText()
target_profile_name = self.dlg.comboBoxNamesTarget.currentText()
- assert source_profile_name != target_profile_name # should be forced by the GUI
- self.data_source_handler.set_path_to_files(source_profile_name,
- target_profile_name)
- self.data_source_handler.set_path_to_bookmark_files(source_profile_name,
- target_profile_name)
+ assert (
+ source_profile_name != target_profile_name
+ ) # should be forced by the GUI
+ self.data_source_handler.set_path_to_files(
+ source_profile_name, target_profile_name
+ )
+ self.data_source_handler.set_path_to_bookmark_files(
+ source_profile_name, target_profile_name
+ )
try:
self.make_backup(target_profile_name)
except OSError as e:
error_message = self.tr("Aborting import due to error:\n{}").format(e)
if error_message:
- QMessageBox.critical(None, self.tr("Backup could not be created"), error_message)
+ QMessageBox.critical(
+ None, self.tr("Backup could not be created"), error_message
+ )
return
with wait_cursor():
@@ -304,7 +346,9 @@ def import_action_handler(self):
QMessageBox.critical(
None,
self.tr("Data Source Import"),
- self.tr("There were errors on import."), # The user should have been shown dialogs or see a log
+ self.tr(
+ "There were errors on import."
+ ), # The user should have been shown dialogs or see a log
)
else:
QMessageBox.information(
@@ -330,8 +374,9 @@ def remove_source_action_handler(self):
clicked_button = QMessageBox.question(
None,
self.tr("Remove Data Sources"),
- self.tr("Are you sure you want to remove these sources?\n\nA backup will be created at '{}'") \
- .format(self.backup_path),
+ self.tr(
+ "Are you sure you want to remove these sources?\n\nA backup will be created at '{}'"
+ ).format(self.backup_path),
)
if clicked_button == QMessageBox.Yes:
@@ -340,14 +385,18 @@ def remove_source_action_handler(self):
try:
self.make_backup(source_profile_name)
except OSError as e:
- error_message = self.tr("Aborting removal due to error:\n{}").format(e)
+ error_message = self.tr(
+ "Aborting removal due to error:\n{}"
+ ).format(e)
if not error_message:
self.data_source_handler.remove_datasources_and_plugins()
self.update_data_sources(True)
if error_message:
- QMessageBox.critical(None, self.tr("Backup could not be created"), error_message)
+ QMessageBox.critical(
+ None, self.tr("Backup could not be created"), error_message
+ )
else:
QMessageBox.information(
None,
@@ -360,7 +409,9 @@ def remove_source_action_handler(self):
self.refresh_browser_model()
self.interface_handler.uncheck_everything()
- def update_data_sources(self, only_update_plugins_for_target_profile=False, update_source=True):
+ def update_data_sources(
+ self, only_update_plugins_for_target_profile=False, update_source=True
+ ):
"""Updates data sources and plugin lists in the UI"""
source_profile = self.dlg.comboBoxNamesSource.currentText()
target_profile = self.dlg.comboBoxNamesTarget.currentText()
@@ -371,7 +422,9 @@ def update_data_sources(self, only_update_plugins_for_target_profile=False, upda
else:
self.interface_handler.populate_data_source_tree(target_profile, False)
- self.data_source_handler.display_plugins(only_for_target_profile=only_update_plugins_for_target_profile)
+ self.data_source_handler.display_plugins(
+ only_for_target_profile=only_update_plugins_for_target_profile
+ )
def get_checked_sources(self):
"""Gets all checked data sources and communicates them to the data source handler"""
@@ -382,20 +435,34 @@ def get_checked_sources(self):
checked_web_sources = defaultdict(list)
checked_database_sources = defaultdict(list)
- for item in self.dlg.treeWidgetSource.findItems("", Qt.MatchContains | Qt.MatchRecursive):
+ for item in self.dlg.treeWidgetSource.findItems(
+ "", Qt.MatchContains | Qt.MatchRecursive
+ ):
if item.childCount() == 0 and item.checkState(0) == Qt.Checked:
parent_text = item.parent().text(0) # the provider group in the tree
- item_text = item.text(0) # a specific data source in the provider's group
+ item_text = item.text(
+ 0
+ ) # a specific data source in the provider's group
# FIXME hardcoded list of GUI titles
- if parent_text in ["SpatiaLite", "PostgreSQL", "MSSQL", "DB2", "Oracle"]:
+ if parent_text in [
+ "SpatiaLite",
+ "PostgreSQL",
+ "MSSQL",
+ "DB2",
+ "Oracle",
+ ]:
checked_database_sources[parent_text].append(item_text)
# GeoPackage connections are stored under [providers] in the ini
- elif parent_text == "GeoPackage": # FIXME hardcoded relationship between GeoPackage and 'providers'
+ elif (
+ parent_text == "GeoPackage"
+ ): # FIXME hardcoded relationship between GeoPackage and 'providers'
checked_database_sources["providers"].append(item_text)
else:
checked_web_sources[parent_text].append(item_text)
- self.data_source_handler.set_data_sources(checked_web_sources, checked_database_sources)
+ self.data_source_handler.set_data_sources(
+ checked_web_sources, checked_database_sources
+ )
def get_profile_paths(self) -> tuple[str, str]:
"""Returns the paths to the currently chosen source and target profiles.
@@ -404,9 +471,17 @@ def get_profile_paths(self) -> tuple[str, str]:
tuple[str, str]: Path to source profile, path to target profile
"""
source = adjust_to_operating_system(
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesSource.currentText() + "/")
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesSource.currentText()
+ + "/"
+ )
target = adjust_to_operating_system(
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesTarget.currentText() + "/")
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesTarget.currentText()
+ + "/"
+ )
return source, target
@@ -414,14 +489,30 @@ def get_ini_paths(self):
"""Gets path to current chosen source and target qgis.ini file"""
if self.operating_system == "mac":
ini_path_source = adjust_to_operating_system(
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesSource.currentText() + "/qgis.org/QGIS3.ini")
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesSource.currentText()
+ + "/qgis.org/QGIS3.ini"
+ )
ini_path_target = adjust_to_operating_system(
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesTarget.currentText() + "/qgis.org/QGIS3.ini")
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesTarget.currentText()
+ + "/qgis.org/QGIS3.ini"
+ )
else:
ini_path_source = adjust_to_operating_system(
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesSource.currentText() + "/QGIS/QGIS3.ini")
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesSource.currentText()
+ + "/QGIS/QGIS3.ini"
+ )
ini_path_target = adjust_to_operating_system(
- self.qgis_profiles_path + "/" + self.dlg.comboBoxNamesTarget.currentText() + "/QGIS/QGIS3.ini")
+ self.qgis_profiles_path
+ + "/"
+ + self.dlg.comboBoxNamesTarget.currentText()
+ + "/QGIS/QGIS3.ini"
+ )
ini_paths = {
"source": ini_path_source,
@@ -432,5 +523,5 @@ def get_ini_paths(self):
def refresh_browser_model(self):
"""Refreshes the browser of the qgis instance from which this plugin was started"""
- self.iface.mainWindow().findChildren(QWidget, 'Browser')[0].refresh()
- self.iface.mainWindow().findChildren(QWidget, 'Browser2')[0].refresh()
+ self.iface.mainWindow().findChildren(QWidget, "Browser")[0].refresh()
+ self.iface.mainWindow().findChildren(QWidget, "Browser2")[0].refresh()
diff --git a/profile_manager/profile_manager_dialog.py b/profile_manager/profile_manager_dialog.py
index 5e627dd..12639bd 100644
--- a/profile_manager/profile_manager_dialog.py
+++ b/profile_manager/profile_manager_dialog.py
@@ -26,8 +26,9 @@
from qgis.PyQt import QtWidgets, uic
# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'profile_manager_dialog_base.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "profile_manager_dialog_base.ui")
+)
class ProfileManagerDialog(QtWidgets.QDialog, FORM_CLASS):
diff --git a/profile_manager/profiles/__init__.py b/profile_manager/profiles/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/profiles/profile_action_handler.py b/profile_manager/profiles/profile_action_handler.py
index 34acc2e..23d4d8e 100644
--- a/profile_manager/profiles/profile_action_handler.py
+++ b/profile_manager/profiles/profile_action_handler.py
@@ -1,14 +1,16 @@
from qgis.PyQt.QtWidgets import QDialog
-from .profile_copier import ProfileCopier
-from .profile_creator import ProfileCreator
-from .profile_editor import ProfileEditor
-from .profile_remover import ProfileRemover
+from profile_manager.profiles.profile_copier import ProfileCopier
+from profile_manager.profiles.profile_creator import ProfileCreator
+from profile_manager.profiles.profile_editor import ProfileEditor
+from profile_manager.profiles.profile_remover import ProfileRemover
class ProfileActionHandler(QDialog):
- def __init__(self, profile_manager_dialog, qgis_path, profile_manager, *args, **kwargs):
+ def __init__(
+ self, profile_manager_dialog, qgis_path, profile_manager, *args, **kwargs
+ ):
super().__init__(*args, **kwargs)
self.is_cancel_button_clicked = False
@@ -16,9 +18,13 @@ def __init__(self, profile_manager_dialog, qgis_path, profile_manager, *args, **
self.dlg = profile_manager_dialog
self.qgis_path = qgis_path
self.profile_manager = profile_manager
- self.profile_remover = ProfileRemover(self.dlg, self.qgis_path, self.profile_manager)
+ self.profile_remover = ProfileRemover(
+ self.dlg, self.qgis_path, self.profile_manager
+ )
self.profile_creator = ProfileCreator(self.qgis_path, self.profile_manager)
- self.profile_editor = ProfileEditor(self.dlg, self.qgis_path, self.profile_manager)
+ self.profile_editor = ProfileEditor(
+ self.dlg, self.qgis_path, self.profile_manager
+ )
self.profile_copier = ProfileCopier(self.dlg, self.qgis_path)
def create_new_profile(self):
diff --git a/profile_manager/profiles/profile_copier.py b/profile_manager/profiles/profile_copier.py
index 8bca6f5..d897c35 100644
--- a/profile_manager/profiles/profile_copier.py
+++ b/profile_manager/profiles/profile_copier.py
@@ -2,8 +2,8 @@
from qgis.PyQt.QtWidgets import QDialog, QMessageBox
-from ..userInterface.name_profile_dialog import NameProfileDialog
-from ..utils import wait_cursor
+from profile_manager.userInterface.name_profile_dialog import NameProfileDialog
+from profile_manager.utils import wait_cursor
class ProfileCopier(QDialog):
@@ -30,10 +30,16 @@ def copy_profile(self):
try:
copytree(source_profile_path, profile_path)
except FileExistsError:
- error_message = self.tr("Profile directory '{}' already exists.").format(profile_name)
+ error_message = self.tr(
+ "Profile directory '{}' already exists."
+ ).format(profile_name)
if error_message:
- QMessageBox.critical(None, self.tr("Profile could not be copied"), error_message)
+ QMessageBox.critical(
+ None, self.tr("Profile could not be copied"), error_message
+ )
else:
QMessageBox.information(
- None, self.tr("Profile copied"), self.tr("Profile '{}' successfully copied.").format(profile_name)
+ None,
+ self.tr("Profile copied"),
+ self.tr("Profile '{}' successfully copied.").format(profile_name),
)
diff --git a/profile_manager/profiles/profile_creator.py b/profile_manager/profiles/profile_creator.py
index 96fd8b3..9b93bdc 100644
--- a/profile_manager/profiles/profile_creator.py
+++ b/profile_manager/profiles/profile_creator.py
@@ -1,10 +1,10 @@
from os import mkdir
-from qgis.PyQt.QtWidgets import QDialog, QMessageBox
from qgis.core import QgsUserProfileManager
+from qgis.PyQt.QtWidgets import QDialog, QMessageBox
-from ..userInterface.name_profile_dialog import NameProfileDialog
-from ..utils import adjust_to_operating_system, wait_cursor
+from profile_manager.userInterface.name_profile_dialog import NameProfileDialog
+from profile_manager.utils import adjust_to_operating_system, wait_cursor
class ProfileCreator(QDialog):
@@ -27,23 +27,31 @@ def create_new_profile(self):
assert profile_name != "" # should be forced by the GUI
self.qgs_profile_manager.createUserProfile(profile_name)
try:
- if self.profile_manager.operating_system is "mac":
- profile_path = self.qgis_path + "/" + profile_name + "/qgis.org/"
+ if self.profile_manager.operating_system == "mac":
+ profile_path = (
+ self.qgis_path + "/" + profile_name + "/qgis.org/"
+ )
else:
profile_path = self.qgis_path + "/" + profile_name + "/QGIS/"
profile_path = adjust_to_operating_system(profile_path)
mkdir(profile_path)
- ini_path = profile_path + adjust_to_operating_system('QGIS3.ini')
+ ini_path = profile_path + adjust_to_operating_system("QGIS3.ini")
qgis_ini_file = open(ini_path, "w")
qgis_ini_file.close()
except FileExistsError:
- error_message = self.tr("Profile directory '{}' already exists.").format(profile_name)
+ error_message = self.tr(
+ "Profile directory '{}' already exists."
+ ).format(profile_name)
if error_message:
- QMessageBox.critical(None, self.tr("Profile could not be created"), error_message)
+ QMessageBox.critical(
+ None, self.tr("Profile could not be created"), error_message
+ )
else:
QMessageBox.information(
- None, self.tr("Profile created"), self.tr("Profile '{}' successfully created.").format(profile_name)
+ None,
+ self.tr("Profile created"),
+ self.tr("Profile '{}' successfully created.").format(profile_name),
)
diff --git a/profile_manager/profiles/profile_editor.py b/profile_manager/profiles/profile_editor.py
index 6d7096a..f0de194 100644
--- a/profile_manager/profiles/profile_editor.py
+++ b/profile_manager/profiles/profile_editor.py
@@ -1,16 +1,18 @@
from os import rename
from pathlib import Path
-from qgis.PyQt.QtWidgets import QDialog, QMessageBox
from qgis.core import QgsApplication
+from qgis.PyQt.QtWidgets import QDialog, QMessageBox
-from ..userInterface.name_profile_dialog import NameProfileDialog
-from ..utils import adjust_to_operating_system, wait_cursor
+from profile_manager.userInterface.name_profile_dialog import NameProfileDialog
+from profile_manager.utils import adjust_to_operating_system, wait_cursor
class ProfileEditor(QDialog):
- def __init__(self, profile_manager_dialog, qgis_path, profile_manager, *args, **kwargs):
+ def __init__(
+ self, profile_manager_dialog, qgis_path, profile_manager, *args, **kwargs
+ ):
super().__init__(*args, **kwargs)
self.dlg = profile_manager_dialog
@@ -24,9 +26,13 @@ def edit_profile(self):
assert old_profile_name is not None
assert old_profile_name != Path(QgsApplication.qgisSettingsDirPath()).name
- profile_before_change = adjust_to_operating_system(self.qgis_path + "/" + old_profile_name)
+ profile_before_change = adjust_to_operating_system(
+ self.qgis_path + "/" + old_profile_name
+ )
- dialog = NameProfileDialog(title=self.tr("Rename Profile '{}'").format(old_profile_name))
+ dialog = NameProfileDialog(
+ title=self.tr("Rename Profile '{}'").format(old_profile_name)
+ )
return_code = dialog.exec()
if return_code == QDialog.Accepted:
@@ -34,7 +40,9 @@ def edit_profile(self):
with wait_cursor():
new_profile_name = dialog.text_input.text()
assert new_profile_name != "" # should be forced by the GUI
- profile_after_change = adjust_to_operating_system(self.qgis_path + "/" + new_profile_name)
+ profile_after_change = adjust_to_operating_system(
+ self.qgis_path + "/" + new_profile_name
+ )
try:
rename(profile_before_change, profile_after_change)
@@ -42,10 +50,14 @@ def edit_profile(self):
error_message = str(e)
if error_message:
- QMessageBox.critical(None, self.tr("Profile could not be renamed"), error_message)
+ QMessageBox.critical(
+ None, self.tr("Profile could not be renamed"), error_message
+ )
else:
QMessageBox.information(
None,
self.tr("Profile renamed"),
- self.tr("Profile '{0}' successfully renamed to '{1}'.").format(old_profile_name, new_profile_name),
+ self.tr("Profile '{0}' successfully renamed to '{1}'.").format(
+ old_profile_name, new_profile_name
+ ),
)
diff --git a/profile_manager/profiles/profile_remover.py b/profile_manager/profiles/profile_remover.py
index ed299f8..a2bb5f8 100644
--- a/profile_manager/profiles/profile_remover.py
+++ b/profile_manager/profiles/profile_remover.py
@@ -1,15 +1,17 @@
from pathlib import Path
from shutil import rmtree
-from qgis.PyQt.QtWidgets import QDialog, QMessageBox
from qgis.core import QgsApplication
+from qgis.PyQt.QtWidgets import QDialog, QMessageBox
-from ..utils import adjust_to_operating_system, wait_cursor
+from profile_manager.utils import adjust_to_operating_system, wait_cursor
class ProfileRemover(QDialog):
- def __init__(self, profile_manager_dialog, qgis_path, profile_manager, *args, **kwargs):
+ def __init__(
+ self, profile_manager_dialog, qgis_path, profile_manager, *args, **kwargs
+ ):
super().__init__(*args, **kwargs)
self.dlg = profile_manager_dialog
@@ -32,8 +34,9 @@ def remove_profile(self):
clicked_button = QMessageBox.question(
None,
self.tr("Remove Profile"),
- self.tr("Are you sure you want to remove the profile '{0}'?\n\nA backup will be created at '{1}'") \
- .format(profile_name, self.profile_manager.backup_path),
+ self.tr(
+ "Are you sure you want to remove the profile '{0}'?\n\nA backup will be created at '{1}'"
+ ).format(profile_name, self.profile_manager.backup_path),
)
if clicked_button == QMessageBox.Yes:
@@ -43,18 +46,22 @@ def remove_profile(self):
try:
self.profile_manager.make_backup(profile_name)
except OSError as e:
- error_message = \
- self.tr("Aborting removal of profile '{0}' due to error:\n{1}").format(profile_name, e)
+ error_message = self.tr(
+ "Aborting removal of profile '{0}' due to error:\n{1}"
+ ).format(profile_name, e)
if error_message:
- QMessageBox.critical(None, self.tr("Backup could not be created"), error_message)
+ QMessageBox.critical(
+ None, self.tr("Backup could not be created"), error_message
+ )
return
with wait_cursor():
try:
rmtree(profile_path)
except FileNotFoundError as e:
- error_message = self.tr("Aborting removal of profile '{0}' due to error:\n{1}") \
- .format(profile_name, e)
+ error_message = self.tr(
+ "Aborting removal of profile '{0}' due to error:\n{1}"
+ ).format(profile_name, e)
if error_message:
QMessageBox.critical(
@@ -62,5 +69,7 @@ def remove_profile(self):
)
else:
QMessageBox.information(
- None, self.tr("Profile removed"), self.tr("Profile '{}' has been removed.").format(profile_name)
+ None,
+ self.tr("Profile removed"),
+ self.tr("Profile '{}' has been removed.").format(profile_name),
)
diff --git a/profile_manager/userInterface/__init__.py b/profile_manager/userInterface/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/profile_manager/userInterface/interface_handler.py b/profile_manager/userInterface/interface_handler.py
index df1c564..4c9e9b0 100644
--- a/profile_manager/userInterface/interface_handler.py
+++ b/profile_manager/userInterface/interface_handler.py
@@ -1,12 +1,14 @@
-import time
from pathlib import Path
-from qgis.PyQt.QtCore import QVariant, Qt
+from qgis.core import Qgis, QgsApplication, QgsMessageLog
+from qgis.PyQt.QtCore import Qt, QVariant
from qgis.PyQt.QtGui import QColor, QIcon, QPalette
from qgis.PyQt.QtWidgets import QDialog, QListWidgetItem
-from qgis.core import Qgis, QgsApplication, QgsMessageLog
-from ..datasources.Dataservices.datasource_provider import get_data_sources_tree, DATA_SOURCE_SEARCH_LOCATIONS
+from profile_manager.datasources.Dataservices.datasource_provider import (
+ DATA_SOURCE_SEARCH_LOCATIONS,
+ get_data_sources_tree,
+)
class InterfaceHandler(QDialog):
@@ -26,7 +28,9 @@ def populate_data_source_tree(self, profile_name, populating_source_profile):
populating_source_profile (bool): If the source profile is populated
"""
QgsMessageLog.logMessage(
- f"Scanning profile '{profile_name}' for data source connections:", "Profile Manager", Qgis.Info
+ f"Scanning profile '{profile_name}' for data source connections:",
+ "Profile Manager",
+ Qgis.Info,
)
ini_paths = self.profile_manager.get_ini_paths()
if populating_source_profile:
@@ -37,22 +41,30 @@ def populate_data_source_tree(self, profile_name, populating_source_profile):
# collect data source tree items from ini file
data_source_list = []
for provider in DATA_SOURCE_SEARCH_LOCATIONS.keys():
- tree_root_item = get_data_sources_tree(target_ini_path, provider, make_checkable=populating_source_profile)
+ tree_root_item = get_data_sources_tree(
+ target_ini_path, provider, make_checkable=populating_source_profile
+ )
if tree_root_item:
data_source_list.append(tree_root_item)
QgsMessageLog.logMessage(
- f"Scanning profile '{profile_name}' for data source connections: Done!", "Profile Manager", Qgis.Info
+ f"Scanning profile '{profile_name}' for data source connections: Done!",
+ "Profile Manager",
+ Qgis.Info,
)
# populate tree
if populating_source_profile:
self.dlg.treeWidgetSource.clear()
- self.dlg.treeWidgetSource.setHeaderLabel(self.tr("Source Profile: {}").format(profile_name))
+ self.dlg.treeWidgetSource.setHeaderLabel(
+ self.tr("Source Profile: {}").format(profile_name)
+ )
for tree_root_item in data_source_list:
self.dlg.treeWidgetSource.addTopLevelItem(tree_root_item)
else:
self.dlg.treeWidgetTarget.clear()
- self.dlg.treeWidgetTarget.setHeaderLabel(self.tr("Target Profile: {}").format(profile_name))
+ self.dlg.treeWidgetTarget.setHeaderLabel(
+ self.tr("Target Profile: {}").format(profile_name)
+ )
for tree_root_item in data_source_list:
self.dlg.treeWidgetTarget.addTopLevelItem(tree_root_item)
@@ -85,7 +97,7 @@ def populate_profile_listings(self):
font.setItalic(True)
self.dlg.comboBoxNamesTarget.setItemData(i, QVariant(font), Qt.FontRole)
# Add profiles to list view
- list_item = QListWidgetItem(QIcon('../icon.png'), name)
+ list_item = QListWidgetItem(QIcon("../icon.png"), name)
if name == active_profile_name:
font = list_item.font()
font.setItalic(True)
@@ -100,11 +112,12 @@ def populate_profile_listings(self):
self.conditionally_enable_profile_buttons()
def adjust_to_macOSDark(self):
- from ..darkdetect import _detect
+ from profile_manager.darkdetect import _detect
+
if _detect.isDark():
# Change ComboBox selected from black to white
- self.dlg.comboBoxNamesSource.setStyleSheet('color: white')
- self.dlg.comboBoxNamesTarget.setStyleSheet('color: white')
+ self.dlg.comboBoxNamesSource.setStyleSheet("color: white")
+ self.dlg.comboBoxNamesTarget.setStyleSheet("color: white")
# Set checkbox indicator of the treewidget from black to white
file_tree_palette = QPalette()
@@ -119,15 +132,25 @@ def adjust_to_macOSDark(self):
def setup_connections(self):
"""Set up connections"""
# buttons
- self.dlg.importButton.clicked.connect(self.profile_manager.import_action_handler)
+ self.dlg.importButton.clicked.connect(
+ self.profile_manager.import_action_handler
+ )
self.dlg.closeDialog.rejected.connect(self.dlg.close)
self.dlg.createProfileButton.clicked.connect(
self.profile_manager.profile_manager_action_handler.create_new_profile
)
- self.dlg.removeProfileButton.clicked.connect(self.profile_manager.profile_manager_action_handler.remove_profile)
- self.dlg.removeSourcesButton.clicked.connect(self.profile_manager.remove_source_action_handler)
- self.dlg.editProfileButton.clicked.connect(self.profile_manager.profile_manager_action_handler.edit_profile)
- self.dlg.copyProfileButton.clicked.connect(self.profile_manager.profile_manager_action_handler.copy_profile)
+ self.dlg.removeProfileButton.clicked.connect(
+ self.profile_manager.profile_manager_action_handler.remove_profile
+ )
+ self.dlg.removeSourcesButton.clicked.connect(
+ self.profile_manager.remove_source_action_handler
+ )
+ self.dlg.editProfileButton.clicked.connect(
+ self.profile_manager.profile_manager_action_handler.edit_profile
+ )
+ self.dlg.copyProfileButton.clicked.connect(
+ self.profile_manager.profile_manager_action_handler.copy_profile
+ )
# checkbox
self.dlg.checkBox_checkAll.stateChanged.connect(self.check_everything)
@@ -139,18 +162,29 @@ def setup_connections(self):
self.dlg.comboBoxNamesTarget.currentIndexChanged.connect(
lambda: self.profile_manager.update_data_sources(True, False)
)
- self.dlg.comboBoxNamesSource.currentIndexChanged.connect(self.conditionally_enable_import_button)
- self.dlg.comboBoxNamesTarget.currentIndexChanged.connect(self.conditionally_enable_import_button)
- self.dlg.list_profiles.currentItemChanged.connect(self.conditionally_enable_profile_buttons)
+ self.dlg.comboBoxNamesSource.currentIndexChanged.connect(
+ self.conditionally_enable_import_button
+ )
+ self.dlg.comboBoxNamesTarget.currentIndexChanged.connect(
+ self.conditionally_enable_import_button
+ )
+ self.dlg.list_profiles.currentItemChanged.connect(
+ self.conditionally_enable_profile_buttons
+ )
+
def check_everything(self):
"""Checks/Unchecks every checkbox in the gui"""
if self.checked:
self.uncheck_everything()
else:
- for item in self.dlg.treeWidgetSource.findItems("", Qt.MatchContains | Qt.MatchRecursive):
+ for item in self.dlg.treeWidgetSource.findItems(
+ "", Qt.MatchContains | Qt.MatchRecursive
+ ):
item.setCheckState(0, Qt.Checked)
- for item in self.dlg.list_plugins.findItems("", Qt.MatchContains | Qt.MatchRecursive):
+ for item in self.dlg.list_plugins.findItems(
+ "", Qt.MatchContains | Qt.MatchRecursive
+ ):
item.setCheckState(Qt.Checked)
self.dlg.bookmark_check.setCheckState(Qt.Checked)
@@ -174,7 +208,9 @@ def uncheck_everything(self):
self.dlg.ui_check.setChecked(Qt.Unchecked)
self.dlg.checkBox_checkAll.setChecked(Qt.Unchecked)
- for item in self.dlg.treeWidgetSource.findItems("", Qt.MatchContains | Qt.MatchRecursive):
+ for item in self.dlg.treeWidgetSource.findItems(
+ "", Qt.MatchContains | Qt.MatchRecursive
+ ):
item.setCheckState(0, Qt.Unchecked)
for iterator in range(self.dlg.list_plugins.count()):
@@ -187,8 +223,13 @@ def conditionally_enable_import_button(self):
"""
# Don't allow import of a profile into itself
- if self.dlg.comboBoxNamesSource.currentText() == self.dlg.comboBoxNamesTarget.currentText():
- self.dlg.importButton.setToolTip(self.tr("Target profile can not be same as source profile"))
+ if (
+ self.dlg.comboBoxNamesSource.currentText()
+ == self.dlg.comboBoxNamesTarget.currentText()
+ ):
+ self.dlg.importButton.setToolTip(
+ self.tr("Target profile can not be same as source profile")
+ )
self.dlg.importButton.setEnabled(False)
else:
self.dlg.importButton.setToolTip("")
@@ -201,17 +242,30 @@ def conditionally_enable_profile_buttons(self):
"""
# A profile must be selected
if self.dlg.list_profiles.currentItem() is None:
- self.dlg.removeProfileButton.setToolTip(self.tr("Please choose a profile to remove"))
+ self.dlg.removeProfileButton.setToolTip(
+ self.tr("Please choose a profile to remove")
+ )
self.dlg.removeProfileButton.setEnabled(False)
- self.dlg.editProfileButton.setToolTip(self.tr("Please choose a profile to rename"))
+ self.dlg.editProfileButton.setToolTip(
+ self.tr("Please choose a profile to rename")
+ )
self.dlg.editProfileButton.setEnabled(False)
- self.dlg.copyProfileButton.setToolTip(self.tr("Please select a profile to copy from"))
+ self.dlg.copyProfileButton.setToolTip(
+ self.tr("Please select a profile to copy from")
+ )
self.dlg.copyProfileButton.setEnabled(False)
# Some actions can/should not be done on the currently active profile
- elif self.dlg.list_profiles.currentItem().text() == Path(QgsApplication.qgisSettingsDirPath()).name:
- self.dlg.removeProfileButton.setToolTip(self.tr("The active profile cannot be removed"))
+ elif (
+ self.dlg.list_profiles.currentItem().text()
+ == Path(QgsApplication.qgisSettingsDirPath()).name
+ ):
+ self.dlg.removeProfileButton.setToolTip(
+ self.tr("The active profile cannot be removed")
+ )
self.dlg.removeProfileButton.setEnabled(False)
- self.dlg.editProfileButton.setToolTip(self.tr("The active profile cannot be renamed"))
+ self.dlg.editProfileButton.setToolTip(
+ self.tr("The active profile cannot be renamed")
+ )
self.dlg.editProfileButton.setEnabled(False)
self.dlg.copyProfileButton.setToolTip("")
self.dlg.copyProfileButton.setEnabled(True)
diff --git a/profile_manager/userInterface/name_profile_dialog.py b/profile_manager/userInterface/name_profile_dialog.py
index 2b23489..06f904e 100644
--- a/profile_manager/userInterface/name_profile_dialog.py
+++ b/profile_manager/userInterface/name_profile_dialog.py
@@ -1,4 +1,4 @@
-from qgis.PyQt.QtCore import QRegularExpression, Qt
+from qgis.PyQt.QtCore import QRegularExpression
from qgis.PyQt.QtGui import QRegularExpressionValidator
from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QLineEdit, QVBoxLayout
@@ -22,7 +22,9 @@ def __init__(self, title=None, *args, **kwargs):
self.text_input = QLineEdit()
self.text_input.setPlaceholderText(self.tr("Profile Name"))
# validation rule from QGIS' QgsUserProfileSelectionDialog
- self.text_input.setValidator(QRegularExpressionValidator(QRegularExpression("[^/\\\\]+")))
+ self.text_input.setValidator(
+ QRegularExpressionValidator(QRegularExpression("[^/\\\\]+"))
+ )
self.button_box = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
self.button_box = QDialogButtonBox(self.button_box)
diff --git a/profile_manager/utils.py b/profile_manager/utils.py
index a9ec8b1..6e821cb 100644
--- a/profile_manager/utils.py
+++ b/profile_manager/utils.py
@@ -1,7 +1,7 @@
from contextlib import contextmanager
from sys import platform
-from qgis.PyQt.QtCore import Qt, QCoreApplication
+from qgis.PyQt.QtCore import QCoreApplication, Qt
from qgis.PyQt.QtGui import QCursor, QGuiApplication
@@ -19,15 +19,18 @@ def adjust_to_operating_system(path_to_adjust):
For MacOS it contains special logic to also replace the /QGIS/ -> /qgis.org/ directory name.
"""
- if platform.startswith('win32'):
+ if platform.startswith("win32"):
return path_to_adjust.replace("/", "\\")
elif platform.startswith("linux") or "bsd" in platform:
return path_to_adjust.replace("\\", "/")
elif platform.startswith("darwin"): # macos
- return path_to_adjust.replace("\\", "/").replace("/QGIS/QGIS3.ini", "/qgis.org/QGIS3.ini")
+ return path_to_adjust.replace("\\", "/").replace(
+ "/QGIS/QGIS3.ini", "/qgis.org/QGIS3.ini"
+ )
else:
raise NotImplementedError(f"Unsupported platform '{platform}'")
+
def tr(message):
# for translating in non-QObject class contexts
- return QCoreApplication.translate('ProfileManager', message)
+ return QCoreApplication.translate("ProfileManager", message)
diff --git a/test/__init__.py b/test/__init__.py
index 8feeb0b..2aea085 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -1,2 +1,2 @@
# import qgis libs so that ve set the correct sip api version
-import qgis # pylint: disable=W0611 # NOQA
\ No newline at end of file
+import qgis # pylint: disable=W0611 # NOQA
diff --git a/test/qgis_interface.py b/test/qgis_interface.py
index a407052..c5bd8fd 100644
--- a/test/qgis_interface.py
+++ b/test/qgis_interface.py
@@ -1,4 +1,3 @@
-# coding=utf-8
"""QGIS plugin implementation.
.. note:: This program is free software; you can redistribute it and/or modify
@@ -14,29 +13,32 @@
"""
-__author__ = 'tim@linfiniti.com'
-__revision__ = '$Format:%H$'
-__date__ = '10/01/2011'
+__author__ = "tim@linfiniti.com"
+__revision__ = "$Format:%H$"
+__date__ = "10/01/2011"
__copyright__ = (
- 'Copyright (c) 2010 by Ivan Mincik, ivan.mincik@gista.sk and '
- 'Copyright (c) 2011 German Carrillo, geotux_tuxman@linuxmail.org'
- 'Copyright (c) 2014 Tim Sutton, tim@linfiniti.com'
+ "Copyright (c) 2010 by Ivan Mincik, ivan.mincik@gista.sk and "
+ "Copyright (c) 2011 German Carrillo, geotux_tuxman@linuxmail.org"
+ "Copyright (c) 2014 Tim Sutton, tim@linfiniti.com"
)
import logging
-from qgis.PyQt.QtCore import QObject, pyqtSlot, pyqtSignal
+
from qgis.core import QgsMapLayerRegistry
from qgis.gui import QgsMapCanvasLayer
-LOGGER = logging.getLogger('QGIS')
+from qgis.PyQt.QtCore import QObject, pyqtSignal, pyqtSlot
+
+LOGGER = logging.getLogger("QGIS")
-#noinspection PyMethodMayBeStatic,PyPep8Naming
+# noinspection PyMethodMayBeStatic,PyPep8Naming
class QgisInterface(QObject):
"""Class to expose QGIS objects and functions to plugins.
This class is here for enabling us to run unit tests only,
so most methods are simply stubs.
"""
+
currentLayerChanged = pyqtSignal(QgsMapCanvasLayer)
def __init__(self, canvas):
@@ -47,7 +49,7 @@ def __init__(self, canvas):
self.canvas = canvas
# Set up slots so we can mimic the behaviour of QGIS when layers
# are added.
- LOGGER.debug('Initialising canvas...')
+ LOGGER.debug("Initialising canvas...")
# noinspection PyArgumentList
QgsMapLayerRegistry.instance().layersAdded.connect(self.addLayers)
# noinspection PyArgumentList
@@ -58,7 +60,7 @@ def __init__(self, canvas):
# For processing module
self.destCrs = None
- @pyqtSlot('QStringList')
+ @pyqtSlot("QStringList")
def addLayers(self, layers):
"""Handle layers being added to the registry so they show up in canvas.
@@ -67,9 +69,9 @@ def addLayers(self, layers):
.. note:: The QgsInterface api does not include this method,
it is added here as a helper to facilitate testing.
"""
- #LOGGER.debug('addLayers called on qgis_interface')
- #LOGGER.debug('Number of layers being added: %s' % len(layers))
- #LOGGER.debug('Layer Count Before: %s' % len(self.canvas.layers()))
+ # LOGGER.debug('addLayers called on qgis_interface')
+ # LOGGER.debug('Number of layers being added: %s' % len(layers))
+ # LOGGER.debug('Layer Count Before: %s' % len(self.canvas.layers()))
current_layers = self.canvas.layers()
final_layers = []
for layer in current_layers:
@@ -78,9 +80,9 @@ def addLayers(self, layers):
final_layers.append(QgsMapCanvasLayer(layer))
self.canvas.setLayerSet(final_layers)
- #LOGGER.debug('Layer Count After: %s' % len(self.canvas.layers()))
+ # LOGGER.debug('Layer Count After: %s' % len(self.canvas.layers()))
- @pyqtSlot('QgsMapLayer')
+ @pyqtSlot("QgsMapLayer")
def addLayer(self, layer):
"""Handle a layer being added to the registry so it shows up in canvas.
diff --git a/test/test_init.py b/test/test_init.py
index 383303d..4120b56 100644
--- a/test/test_init.py
+++ b/test/test_init.py
@@ -1,19 +1,18 @@
-# coding=utf-8
"""Tests QGIS plugin init."""
-__author__ = 'Tim Sutton '
-__revision__ = '$Format:%H$'
-__date__ = '17/10/2010'
+__author__ = "Tim Sutton "
+__revision__ = "$Format:%H$"
+__date__ = "17/10/2010"
__license__ = "GPL"
-__copyright__ = 'Copyright 2012, Australia Indonesia Facility for '
-__copyright__ += 'Disaster Reduction'
+__copyright__ = "Copyright 2012, Australia Indonesia Facility for "
+__copyright__ += "Disaster Reduction"
+import configparser
+import logging
import os
import unittest
-import logging
-import configparser
-LOGGER = logging.getLogger('QGIS')
+LOGGER = logging.getLogger("QGIS")
class TestInit(unittest.TestCase):
@@ -35,30 +34,34 @@ def test_read_init(self):
# plugins/validator.py
required_metadata = [
- 'name',
- 'description',
- 'version',
- 'qgisMinimumVersion',
- 'email',
- 'author']
-
- file_path = os.path.abspath(os.path.join(
- os.path.dirname(__file__), os.pardir,
- 'metadata.txt'))
+ "name",
+ "description",
+ "version",
+ "qgisMinimumVersion",
+ "email",
+ "author",
+ ]
+
+ file_path = os.path.abspath(
+ os.path.join(os.path.dirname(__file__), os.pardir, "metadata.txt")
+ )
LOGGER.info(file_path)
metadata = []
parser = configparser.ConfigParser()
parser.optionxform = str # str = case sensitive option names
parser.read(file_path)
message = 'Cannot find a section named "general" in %s' % file_path
- assert parser.has_section('general'), message
- metadata.extend(parser.items('general'))
+ assert parser.has_section("general"), message
+ metadata.extend(parser.items("general"))
for expectation in required_metadata:
- message = ('Cannot find metadata "%s" in metadata source (%s).' % (
- expectation, file_path))
+ message = 'Cannot find metadata "%s" in metadata source (%s).' % (
+ expectation,
+ file_path,
+ )
self.assertIn(expectation, dict(metadata), message)
-if __name__ == '__main__':
+
+if __name__ == "__main__":
unittest.main()
diff --git a/test/test_profile_manager_dialog.py b/test/test_profile_manager_dialog.py
index 2c8e928..98bf12e 100644
--- a/test/test_profile_manager_dialog.py
+++ b/test/test_profile_manager_dialog.py
@@ -1,4 +1,3 @@
-# coding=utf-8
"""Dialog test.
.. note:: This program is free software; you can redistribute it and/or modify
@@ -8,17 +7,17 @@
"""
-__author__ = 'dominik.szill@wheregroup.com'
-__date__ = '2020-03-17'
-__copyright__ = 'Copyright 2020, Dominik Szill / WhereGroup GmbH'
+__author__ = "dominik.szill@wheregroup.com"
+__date__ = "2020-03-17"
+__copyright__ = "Copyright 2020, Dominik Szill / WhereGroup GmbH"
import unittest
-from qgis.PyQt.QtGui import QDialogButtonBox, QDialog
+from qgis.PyQt.QtGui import QDialog, QDialogButtonBox
+from utilities import get_qgis_app
-from profile_manager_dialog import ProfileManagerDialog
+from profile_manager.profile_manager_dialog import ProfileManagerDialog
-from utilities import get_qgis_app
QGIS_APP = get_qgis_app()
@@ -48,8 +47,8 @@ def test_dialog_cancel(self):
result = self.dialog.result()
self.assertEqual(result, QDialog.Rejected)
+
if __name__ == "__main__":
suite = unittest.makeSuite(ProfileManagerDialogTest)
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
-
diff --git a/test/test_translations.py b/test/test_translations.py
index 035dc62..2faabdd 100644
--- a/test/test_translations.py
+++ b/test/test_translations.py
@@ -1,4 +1,3 @@
-# coding=utf-8
"""Safe Translations Test.
.. note:: This program is free software; you can redistribute it and/or modify
@@ -7,14 +6,14 @@
(at your option) any later version.
"""
+
from .utilities import get_qgis_app
-__author__ = 'ismailsunni@yahoo.co.id'
-__date__ = '12/10/2011'
-__copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
- 'Disaster Reduction')
-import unittest
+__author__ = "ismailsunni@yahoo.co.id"
+__date__ = "12/10/2011"
+__copyright__ = "Copyright 2012, Australia Indonesia Facility for " "Disaster Reduction"
import os
+import unittest
from qgis.PyQt.QtCore import QCoreApplication, QTranslator
@@ -26,26 +25,25 @@ class SafeTranslationsTest(unittest.TestCase):
def setUp(self):
"""Runs before each test."""
- if 'LANG' in iter(os.environ.keys()):
- os.environ.__delitem__('LANG')
+ if "LANG" in iter(os.environ.keys()):
+ os.environ.__delitem__("LANG")
def tearDown(self):
"""Runs after each test."""
- if 'LANG' in iter(os.environ.keys()):
- os.environ.__delitem__('LANG')
+ if "LANG" in iter(os.environ.keys()):
+ os.environ.__delitem__("LANG")
def test_qgis_translations(self):
"""Test that translations work."""
parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir)
dir_path = os.path.abspath(parent_path)
- file_path = os.path.join(
- dir_path, 'i18n', 'af.qm')
+ file_path = os.path.join(dir_path, "i18n", "af.qm")
translator = QTranslator()
translator.load(file_path)
QCoreApplication.installTranslator(translator)
- expected_message = 'Goeie more'
- real_message = QCoreApplication.translate("@default", 'Good morning')
+ expected_message = "Goeie more"
+ real_message = QCoreApplication.translate("@default", "Good morning")
self.assertEqual(real_message, expected_message)
diff --git a/test/utilities.py b/test/utilities.py
index be7ee3b..d441403 100644
--- a/test/utilities.py
+++ b/test/utilities.py
@@ -1,11 +1,9 @@
-# coding=utf-8
"""Common functionality used by regression tests."""
-import sys
import logging
+import sys
-
-LOGGER = logging.getLogger('QGIS')
+LOGGER = logging.getLogger("QGIS")
QGIS_APP = None # Static variable used to hold hand to running QGIS app
CANVAS = None
PARENT = None
@@ -13,7 +11,7 @@
def get_qgis_app():
- """ Start one QGIS application to test against.
+ """Start one QGIS application to test against.
:returns: Handle to QGIS app, canvas, iface and parent. If there are any
errors the tuple members will be returned as None.
@@ -23,9 +21,10 @@ def get_qgis_app():
"""
try:
- from qgis.PyQt import QtGui, QtCore
from qgis.core import QgsApplication
from qgis.gui import QgsMapCanvas
+ from qgis.PyQt import QtCore, QtGui
+
from .qgis_interface import QgisInterface
except ImportError:
return None, None, None, None
@@ -34,7 +33,7 @@ def get_qgis_app():
if QGIS_APP is None:
gui_flag = True # All test will run qgis in gui mode
- #noinspection PyPep8Naming
+ # noinspection PyPep8Naming
QGIS_APP = QgsApplication(sys.argv, gui_flag)
# Make sure QGIS_PREFIX_PATH is set in your env if needed!
QGIS_APP.initQgis()
@@ -43,19 +42,19 @@ def get_qgis_app():
global PARENT # pylint: disable=W0603
if PARENT is None:
- #noinspection PyPep8Naming
+ # noinspection PyPep8Naming
PARENT = QtGui.QWidget()
global CANVAS # pylint: disable=W0603
if CANVAS is None:
- #noinspection PyPep8Naming
+ # noinspection PyPep8Naming
CANVAS = QgsMapCanvas(PARENT)
CANVAS.resize(QtCore.QSize(400, 400))
global IFACE # pylint: disable=W0603
if IFACE is None:
# QgisInterface is a stub implementation of the QGIS plugin interface
- #noinspection PyPep8Naming
+ # noinspection PyPep8Naming
IFACE = QgisInterface(CANVAS)
return QGIS_APP, CANVAS, IFACE, PARENT