ran black reformatter
This commit is contained in:
parent
7ef7fa95dd
commit
7f15a2d90f
1 changed files with 194 additions and 101 deletions
|
@ -11,14 +11,20 @@ from ostools import getDataDir
|
||||||
try:
|
try:
|
||||||
from PyQt6 import QtCore, QtGui, QtWidgets, QtNetwork
|
from PyQt6 import QtCore, QtGui, QtWidgets, QtNetwork
|
||||||
from PyQt6.QtGui import QAction
|
from PyQt6.QtGui import QAction
|
||||||
|
|
||||||
_flag_selectable = QtCore.Qt.TextInteractionFlag.TextSelectableByMouse
|
_flag_selectable = QtCore.Qt.TextInteractionFlag.TextSelectableByMouse
|
||||||
_flag_topalign = QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignTop
|
_flag_topalign = (
|
||||||
|
QtCore.Qt.AlignmentFlag.AlignLeading
|
||||||
|
| QtCore.Qt.AlignmentFlag.AlignLeft
|
||||||
|
| QtCore.Qt.AlignmentFlag.AlignTop
|
||||||
|
)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("PyQt5 fallback (thememanager.py)")
|
print("PyQt5 fallback (thememanager.py)")
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
|
from PyQt5 import QtCore, QtGui, QtWidgets, QtNetwork
|
||||||
from PyQt5.QtWidgets import QAction
|
from PyQt5.QtWidgets import QAction
|
||||||
|
|
||||||
_flag_selectable = QtCore.Qt.TextSelectableByMouse
|
_flag_selectable = QtCore.Qt.TextSelectableByMouse
|
||||||
_flag_topalign = QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop
|
_flag_topalign = QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop
|
||||||
|
|
||||||
PchumLog = logging.getLogger("pchumLogger")
|
PchumLog = logging.getLogger("pchumLogger")
|
||||||
themeManager = None
|
themeManager = None
|
||||||
|
@ -35,11 +41,11 @@ themeManager = None
|
||||||
|
|
||||||
class ThemeManager(QtCore.QObject):
|
class ThemeManager(QtCore.QObject):
|
||||||
# signals
|
# signals
|
||||||
theme_installed = QtCore.pyqtSignal(str) # theme name
|
theme_installed = QtCore.pyqtSignal(str) # theme name
|
||||||
zip_downloaded = QtCore.pyqtSignal(str, str) # theme name, zip location
|
zip_downloaded = QtCore.pyqtSignal(str, str) # theme name, zip location
|
||||||
database_refreshed = QtCore.pyqtSignal(dict) # self.manifest
|
database_refreshed = QtCore.pyqtSignal(dict) # self.manifest
|
||||||
manifest_updated = QtCore.pyqtSignal(dict) # self.manifest
|
manifest_updated = QtCore.pyqtSignal(dict) # self.manifest
|
||||||
errored = QtCore.pyqtSignal(str) # error_text
|
errored = QtCore.pyqtSignal(str) # error_text
|
||||||
|
|
||||||
# variables
|
# variables
|
||||||
manifest = {}
|
manifest = {}
|
||||||
|
@ -50,9 +56,10 @@ class ThemeManager(QtCore.QObject):
|
||||||
NAManager = None
|
NAManager = None
|
||||||
|
|
||||||
downloads = {}
|
downloads = {}
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
with open(self.manifest_path, 'r') as f:
|
with open(self.manifest_path, "r") as f:
|
||||||
self.manifest = json.load(f)
|
self.manifest = json.load(f)
|
||||||
PchumLog.debug("Manifest.js loaded with: %s" % self.manifest)
|
PchumLog.debug("Manifest.js loaded with: %s" % self.manifest)
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -65,15 +72,19 @@ class ThemeManager(QtCore.QObject):
|
||||||
def refresh_database(self):
|
def refresh_database(self):
|
||||||
# Fetches a new copy of the theme database from the given URL
|
# Fetches a new copy of the theme database from the given URL
|
||||||
# The initialisation & processing of it is handled in self._on_reply
|
# The initialisation & processing of it is handled in self._on_reply
|
||||||
PchumLog.debug("Refreshing theme repo database @ %s" % self.config.theme_repo_url())
|
PchumLog.debug(
|
||||||
promise = self.NAManager.get(QtNetwork.QNetworkRequest(QtCore.QUrl(self.config.theme_repo_url())))
|
"Refreshing theme repo database @ %s" % self.config.theme_repo_url()
|
||||||
|
)
|
||||||
|
promise = self.NAManager.get(
|
||||||
|
QtNetwork.QNetworkRequest(QtCore.QUrl(self.config.theme_repo_url()))
|
||||||
|
)
|
||||||
|
|
||||||
def delete_theme(self, theme_name):
|
def delete_theme(self, theme_name):
|
||||||
# TODO: check if other installed themes inherit from this to avoid broken themes
|
# TODO: check if other installed themes inherit from this to avoid broken themes
|
||||||
# would require some kinda confirmation popup which i havent figure out yet
|
# would require some kinda confirmation popup which i havent figure out yet
|
||||||
PchumLog.info("Deleting installed repo theme %s" % theme_name)
|
PchumLog.info("Deleting installed repo theme %s" % theme_name)
|
||||||
theme = self.manifest[theme_name]
|
theme = self.manifest[theme_name]
|
||||||
directory = os.path.join(getDataDir(), 'themes', theme['name'])
|
directory = os.path.join(getDataDir(), "themes", theme["name"])
|
||||||
if os.path.isdir(directory):
|
if os.path.isdir(directory):
|
||||||
rmtree(directory)
|
rmtree(directory)
|
||||||
self.manifest.pop(theme_name)
|
self.manifest.pop(theme_name)
|
||||||
|
@ -81,7 +92,7 @@ class ThemeManager(QtCore.QObject):
|
||||||
self.manifest_updated.emit(self.manifest)
|
self.manifest_updated.emit(self.manifest)
|
||||||
|
|
||||||
def save_manifest(self):
|
def save_manifest(self):
|
||||||
with open(self.manifest_path, 'w') as f:
|
with open(self.manifest_path, "w") as f:
|
||||||
json.dump(self.manifest, f)
|
json.dump(self.manifest, f)
|
||||||
PchumLog.debug("Saved manifes.js to %s" % self.manifest_path)
|
PchumLog.debug("Saved manifes.js to %s" % self.manifest_path)
|
||||||
|
|
||||||
|
@ -91,7 +102,10 @@ class ThemeManager(QtCore.QObject):
|
||||||
all_themes = self.config.availableThemes()
|
all_themes = self.config.availableThemes()
|
||||||
for theme_name in self.manifest:
|
for theme_name in self.manifest:
|
||||||
if not theme_name in all_themes:
|
if not theme_name in all_themes:
|
||||||
PchumLog.warning("Supposedly installed theme %s from the manifest seems to have been deleted, removing from manifest now" % theme_name)
|
PchumLog.warning(
|
||||||
|
"Supposedly installed theme %s from the manifest seems to have been deleted, removing from manifest now"
|
||||||
|
% theme_name
|
||||||
|
)
|
||||||
self.manifest.pop(theme_name)
|
self.manifest.pop(theme_name)
|
||||||
|
|
||||||
def download_theme(self, theme_name):
|
def download_theme(self, theme_name):
|
||||||
|
@ -103,9 +117,15 @@ class ThemeManager(QtCore.QObject):
|
||||||
if not theme_name in self.database_entries:
|
if not theme_name in self.database_entries:
|
||||||
PchumLog.error("Theme name %s does not exist in the database!" % theme_name)
|
PchumLog.error("Theme name %s does not exist in the database!" % theme_name)
|
||||||
return
|
return
|
||||||
PchumLog.debug("(From %s)" % self.database_entries[theme_name]['download'])
|
PchumLog.debug("(From %s)" % self.database_entries[theme_name]["download"])
|
||||||
promise = self.NAManager.get(QtNetwork.QNetworkRequest(QtCore.QUrl(self.database_entries[theme_name]['download'])))
|
promise = self.NAManager.get(
|
||||||
self.downloads[self.database_entries[theme_name]['download']] = self.database_entries[theme_name]
|
QtNetwork.QNetworkRequest(
|
||||||
|
QtCore.QUrl(self.database_entries[theme_name]["download"])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.downloads[
|
||||||
|
self.database_entries[theme_name]["download"]
|
||||||
|
] = self.database_entries[theme_name]
|
||||||
|
|
||||||
def install_theme(self, theme_name, force_install=False):
|
def install_theme(self, theme_name, force_install=False):
|
||||||
# A higher way to install a theme than download_theme
|
# A higher way to install a theme than download_theme
|
||||||
|
@ -124,38 +144,72 @@ class ThemeManager(QtCore.QObject):
|
||||||
|
|
||||||
all_themes = self.config.availableThemes()
|
all_themes = self.config.availableThemes()
|
||||||
theme = self.database_entries[theme_name]
|
theme = self.database_entries[theme_name]
|
||||||
if not self.is_installed(theme_name) and theme_name in all_themes: # Theme exists, but not installed by manager
|
if (
|
||||||
PchumLog.warning("Theme %s is already installed manually. The manual version will get shadowed by the repository version & will not be usable" % theme_name)
|
not self.is_installed(theme_name) and theme_name in all_themes
|
||||||
|
): # Theme exists, but not installed by manager
|
||||||
|
PchumLog.warning(
|
||||||
|
"Theme %s is already installed manually. The manual version will get shadowed by the repository version & will not be usable"
|
||||||
|
% theme_name
|
||||||
|
)
|
||||||
|
|
||||||
# Check depedencies
|
# Check depedencies
|
||||||
if theme['inherits'] != "":
|
if theme["inherits"] != "":
|
||||||
if self.is_installed(theme['inherits']):
|
if self.is_installed(theme["inherits"]):
|
||||||
# Inherited theme is installed. A-OK
|
# Inherited theme is installed. A-OK
|
||||||
PchumLog.debug("Theme %s requires theme %s, which is already installed through the repository" % (theme_name, theme['inherits']))
|
PchumLog.debug(
|
||||||
if theme['inherits'] in all_themes:
|
"Theme %s requires theme %s, which is already installed through the repository"
|
||||||
|
% (theme_name, theme["inherits"])
|
||||||
|
)
|
||||||
|
if theme["inherits"] in all_themes:
|
||||||
# Inherited theme is manually installed. A-OK
|
# Inherited theme is manually installed. A-OK
|
||||||
PchumLog.debug("Theme %s requires theme %s, which is already installed manually by the user" % (theme_name, theme['inherits']))
|
PchumLog.debug(
|
||||||
elif theme['inherits'] in self.database_entries:
|
"Theme %s requires theme %s, which is already installed manually by the user"
|
||||||
|
% (theme_name, theme["inherits"])
|
||||||
|
)
|
||||||
|
elif theme["inherits"] in self.database_entries:
|
||||||
# The Inherited theme is not installed, but can be. A-OK
|
# The Inherited theme is not installed, but can be. A-OK
|
||||||
PchumLog.info("Theme %s requires theme %s, which will now be installed" % (theme_name, theme['inherits']))
|
PchumLog.info(
|
||||||
self.install_theme(theme['inherits'])
|
"Theme %s requires theme %s, which will now be installed"
|
||||||
|
% (theme_name, theme["inherits"])
|
||||||
|
)
|
||||||
|
self.install_theme(theme["inherits"])
|
||||||
else:
|
else:
|
||||||
# Inherited theme is not installed, and can't be installed automatically. Exits unless force_install is True
|
# Inherited theme is not installed, and can't be installed automatically. Exits unless force_install is True
|
||||||
if force_install:
|
if force_install:
|
||||||
PchumLog.error("Theme %s requires theme %s, which is not installed and not in the database. Installing %s anyways, because force_install is True" % (theme_name, theme, theme_name['inherits']))
|
PchumLog.error(
|
||||||
|
"Theme %s requires theme %s, which is not installed and not in the database. Installing %s anyways, because force_install is True"
|
||||||
|
% (theme_name, theme, theme_name["inherits"])
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
PchumLog.error("Theme %s requires theme %s, which is not installed and not in the database. Cancelling install" % (theme_name, theme['inherits']))
|
PchumLog.error(
|
||||||
self.errored.emit("Theme %s requires theme %s, which is not installed and not in the database. Cancelling install" % (theme_name, theme['inherits']))
|
"Theme %s requires theme %s, which is not installed and not in the database. Cancelling install"
|
||||||
|
% (theme_name, theme["inherits"])
|
||||||
|
)
|
||||||
|
self.errored.emit(
|
||||||
|
"Theme %s requires theme %s, which is not installed and not in the database. Cancelling install"
|
||||||
|
% (theme_name, theme["inherits"])
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check if there's no need to re-install theme
|
# Check if there's no need to re-install theme
|
||||||
# This is done after the dependency check in case an inherited theme is missing two levels down
|
# This is done after the dependency check in case an inherited theme is missing two levels down
|
||||||
if self.is_installed(theme_name) and not self.has_update(theme_name): # Theme is installed by manager, and is up-to-date
|
if self.is_installed(theme_name) and not self.has_update(
|
||||||
|
theme_name
|
||||||
|
): # Theme is installed by manager, and is up-to-date
|
||||||
if force_install:
|
if force_install:
|
||||||
PchumLog.warning("Theme %s is already installed, and no update is available. Installing anyways, because force_install is True" % theme_name)
|
PchumLog.warning(
|
||||||
|
"Theme %s is already installed, and no update is available. Installing anyways, because force_install is True"
|
||||||
|
% theme_name
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
PchumLog.warning("Theme %s is already installed, and no update is available. Cancelling install" % theme_name)
|
PchumLog.warning(
|
||||||
self.errored.emit("Theme %s is already installed, and no update is available. Cancelling install" % theme_name)
|
"Theme %s is already installed, and no update is available. Cancelling install"
|
||||||
|
% theme_name
|
||||||
|
)
|
||||||
|
self.errored.emit(
|
||||||
|
"Theme %s is already installed, and no update is available. Cancelling install"
|
||||||
|
% theme_name
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# All is ok. or we're just ignoring the errors through force_install
|
# All is ok. or we're just ignoring the errors through force_install
|
||||||
|
@ -166,7 +220,10 @@ class ThemeManager(QtCore.QObject):
|
||||||
# Has the given theme an update available
|
# Has the given theme an update available
|
||||||
# Returns False if the theme is installed manually or when the theme is up to date
|
# Returns False if the theme is installed manually or when the theme is up to date
|
||||||
if self.is_installed(theme_name) and theme_name in self.database_entries:
|
if self.is_installed(theme_name) and theme_name in self.database_entries:
|
||||||
return self.manifest[theme_name]['version'] < self.database_entries[theme_name]['version']
|
return (
|
||||||
|
self.manifest[theme_name]["version"]
|
||||||
|
< self.database_entries[theme_name]["version"]
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_installed(self, theme_name):
|
def is_installed(self, theme_name):
|
||||||
|
@ -175,15 +232,21 @@ class ThemeManager(QtCore.QObject):
|
||||||
return theme_name in self.manifest
|
return theme_name in self.manifest
|
||||||
|
|
||||||
def is_database_valid(self):
|
def is_database_valid(self):
|
||||||
return 'entries' in self.database and isinstance(self.database.get('entries'), list)
|
return "entries" in self.database and isinstance(
|
||||||
|
self.database.get("entries"), list
|
||||||
|
)
|
||||||
|
|
||||||
# using a slot decorator here raises `ERROR - <class 'TypeError'>, connect() failed between finished(QNetworkReply*) and _on_reply()``
|
# using a slot decorator here raises `ERROR - <class 'TypeError'>, connect() failed between finished(QNetworkReply*) and _on_reply()``
|
||||||
# maybe because of the underscore?
|
# maybe because of the underscore?
|
||||||
# @QtCore.pyqtSlot(QtNetwork.QNetworkReply)
|
# @QtCore.pyqtSlot(QtNetwork.QNetworkReply)
|
||||||
def _on_reply(self, reply):
|
def _on_reply(self, reply):
|
||||||
if reply.error() != QtNetwork.QNetworkReply.NetworkError.NoError:
|
if reply.error() != QtNetwork.QNetworkReply.NetworkError.NoError:
|
||||||
PchumLog.error("An error occured contacting the repository: %s" % reply.error())
|
PchumLog.error(
|
||||||
self.errored.emit("An error occured contacting the repository: %s" % reply.error())
|
"An error occured contacting the repository: %s" % reply.error()
|
||||||
|
)
|
||||||
|
self.errored.emit(
|
||||||
|
"An error occured contacting the repository: %s" % reply.error()
|
||||||
|
)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
original_url = reply.request().url().url()
|
original_url = reply.request().url().url()
|
||||||
|
@ -191,12 +254,12 @@ class ThemeManager(QtCore.QObject):
|
||||||
if original_url in self.downloads:
|
if original_url in self.downloads:
|
||||||
# This is a theme zip!
|
# This is a theme zip!
|
||||||
theme = self.downloads[original_url]
|
theme = self.downloads[original_url]
|
||||||
self._handle_downloaded_zip(bytes(reply.readAll()), theme['name'])
|
self._handle_downloaded_zip(bytes(reply.readAll()), theme["name"])
|
||||||
self.downloads.pop(original_url)
|
self.downloads.pop(original_url)
|
||||||
self.manifest[theme['name']] = theme
|
self.manifest[theme["name"]] = theme
|
||||||
self.save_manifest()
|
self.save_manifest()
|
||||||
self.manifest_updated.emit(self.manifest)
|
self.manifest_updated.emit(self.manifest)
|
||||||
PchumLog.info("Theme %s is now installed" % theme['name'])
|
PchumLog.info("Theme %s is now installed" % theme["name"])
|
||||||
else:
|
else:
|
||||||
# This is a database refresh!
|
# This is a database refresh!
|
||||||
as_json = bytes(reply.readAll()).decode("utf-8")
|
as_json = bytes(reply.readAll()).decode("utf-8")
|
||||||
|
@ -209,14 +272,19 @@ class ThemeManager(QtCore.QObject):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Filter out non-QTchum client themes, like for godot
|
# Filter out non-QTchum client themes, like for godot
|
||||||
for dbindex in range(len(self.database['entries'])-1, -1, -1): # Iterate over the database in reverse
|
for dbindex in range(
|
||||||
dbitem = self.database['entries'][dbindex]
|
len(self.database["entries"]) - 1, -1, -1
|
||||||
if dbitem['client'] != "pesterchum":
|
): # Iterate over the database in reverse
|
||||||
PchumLog.debug("Removed database theme %s because it is not compatible with this client" % dbitem['name'])
|
dbitem = self.database["entries"][dbindex]
|
||||||
self.database['entries'].pop(dbindex)
|
if dbitem["client"] != "pesterchum":
|
||||||
|
PchumLog.debug(
|
||||||
|
"Removed database theme %s because it is not compatible with this client"
|
||||||
|
% dbitem["name"]
|
||||||
|
)
|
||||||
|
self.database["entries"].pop(dbindex)
|
||||||
# Make an easy lookup table instead of the array we get from the DB
|
# Make an easy lookup table instead of the array we get from the DB
|
||||||
for dbitem in self.database['entries']:
|
for dbitem in self.database["entries"]:
|
||||||
self.database_entries[dbitem['name']] = dbitem
|
self.database_entries[dbitem["name"]] = dbitem
|
||||||
PchumLog.info("Database refreshed")
|
PchumLog.info("Database refreshed")
|
||||||
self.database_refreshed.emit(self.database)
|
self.database_refreshed.emit(self.database)
|
||||||
|
|
||||||
|
@ -231,13 +299,11 @@ class ThemeManager(QtCore.QObject):
|
||||||
self.errored.emit("Vital key missing from theme database: %s" % e)
|
self.errored.emit("Vital key missing from theme database: %s" % e)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _handle_downloaded_zip(self, zip_buffer, theme_name):
|
def _handle_downloaded_zip(self, zip_buffer, theme_name):
|
||||||
# Unzips the downloaded theme package in-memory to datadir/themes/theme_name
|
# Unzips the downloaded theme package in-memory to datadir/themes/theme_name
|
||||||
# I dont think this runs in a thread so it may block, but its so fast i dont think it really matters
|
# I dont think this runs in a thread so it may block, but its so fast i dont think it really matters
|
||||||
# But i guess if its a zip bomb itll crash
|
# But i guess if its a zip bomb itll crash
|
||||||
directory = os.path.join(getDataDir(), 'themes', theme_name)
|
directory = os.path.join(getDataDir(), "themes", theme_name)
|
||||||
with zipfile.ZipFile(io.BytesIO(zip_buffer)) as z:
|
with zipfile.ZipFile(io.BytesIO(zip_buffer)) as z:
|
||||||
if os.path.isdir(directory):
|
if os.path.isdir(directory):
|
||||||
rmtree(directory)
|
rmtree(directory)
|
||||||
|
@ -245,7 +311,6 @@ class ThemeManager(QtCore.QObject):
|
||||||
z.extractall(directory)
|
z.extractall(directory)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ThemeManagerWidget(QtWidgets.QWidget):
|
class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
icons = None
|
icons = None
|
||||||
config = None
|
config = None
|
||||||
|
@ -254,7 +319,11 @@ class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
|
|
||||||
def __init__(self, config, parent=None):
|
def __init__(self, config, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.icons = [QtGui.QIcon("img/download_pending.png"), QtGui.QIcon("img/download_done.png"), QtGui.QIcon("img/download_update.png"), ]
|
self.icons = [
|
||||||
|
QtGui.QIcon("img/download_pending.png"),
|
||||||
|
QtGui.QIcon("img/download_done.png"),
|
||||||
|
QtGui.QIcon("img/download_update.png"),
|
||||||
|
]
|
||||||
self.config = config
|
self.config = config
|
||||||
global themeManager
|
global themeManager
|
||||||
if themeManager == None or not themeManager.is_database_valid():
|
if themeManager == None or not themeManager.is_database_valid():
|
||||||
|
@ -266,7 +335,6 @@ class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
themeManager.database_refreshed.connect(self._on_database_refreshed)
|
themeManager.database_refreshed.connect(self._on_database_refreshed)
|
||||||
themeManager.manifest_updated.connect(self._on_database_refreshed)
|
themeManager.manifest_updated.connect(self._on_database_refreshed)
|
||||||
|
|
||||||
|
|
||||||
def setupUI(self):
|
def setupUI(self):
|
||||||
self.layout_main = QtWidgets.QVBoxLayout(self)
|
self.layout_main = QtWidgets.QVBoxLayout(self)
|
||||||
self.setLayout(self.layout_main)
|
self.setLayout(self.layout_main)
|
||||||
|
@ -291,7 +359,6 @@ class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
self.list_results.itemClicked.connect(self._on_theme_selected)
|
self.list_results.itemClicked.connect(self._on_theme_selected)
|
||||||
layout_hbox_list_and_details.addWidget(self.list_results)
|
layout_hbox_list_and_details.addWidget(self.list_results)
|
||||||
|
|
||||||
|
|
||||||
# This is the right side, has the install buttons & all the theme details of the selected item
|
# This is the right side, has the install buttons & all the theme details of the selected item
|
||||||
layout_vbox_details = QtWidgets.QVBoxLayout()
|
layout_vbox_details = QtWidgets.QVBoxLayout()
|
||||||
# The theme details are inside a scroll container in case of small window
|
# The theme details are inside a scroll container in case of small window
|
||||||
|
@ -309,7 +376,9 @@ class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
# Selected theme's name
|
# Selected theme's name
|
||||||
self.lbl_theme_name = QtWidgets.QLabel("Click a theme to get started")
|
self.lbl_theme_name = QtWidgets.QLabel("Click a theme to get started")
|
||||||
self.lbl_theme_name.setTextInteractionFlags(_flag_selectable)
|
self.lbl_theme_name.setTextInteractionFlags(_flag_selectable)
|
||||||
self.lbl_theme_name.setStyleSheet("QLabel { font-size: 16px; font-weight:bold;}")
|
self.lbl_theme_name.setStyleSheet(
|
||||||
|
"QLabel { font-size: 16px; font-weight:bold;}"
|
||||||
|
)
|
||||||
self.lbl_theme_name.setWordWrap(True)
|
self.lbl_theme_name.setWordWrap(True)
|
||||||
layout_vbox_scroll_insides.addWidget(self.lbl_theme_name)
|
layout_vbox_scroll_insides.addWidget(self.lbl_theme_name)
|
||||||
|
|
||||||
|
@ -369,7 +438,9 @@ class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
self.layout_main.addLayout(layout_hbox_list_and_details)
|
self.layout_main.addLayout(layout_hbox_list_and_details)
|
||||||
|
|
||||||
self.btn_refresh = QtWidgets.QPushButton("Refresh", self)
|
self.btn_refresh = QtWidgets.QPushButton("Refresh", self)
|
||||||
self.btn_refresh.clicked.connect(themeManager.refresh_database) # Conneced to themeManager!
|
self.btn_refresh.clicked.connect(
|
||||||
|
themeManager.refresh_database
|
||||||
|
) # Conneced to themeManager!
|
||||||
self.layout_main.addWidget(self.btn_refresh)
|
self.layout_main.addWidget(self.btn_refresh)
|
||||||
|
|
||||||
self.lbl_error = QtWidgets.QLabel("")
|
self.lbl_error = QtWidgets.QLabel("")
|
||||||
|
@ -377,46 +448,63 @@ class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
self.lbl_error.setWordWrap(True)
|
self.lbl_error.setWordWrap(True)
|
||||||
themeManager.errored.connect(self._on_fetch_error)
|
themeManager.errored.connect(self._on_fetch_error)
|
||||||
self.lbl_error.setTextInteractionFlags(_flag_selectable)
|
self.lbl_error.setTextInteractionFlags(_flag_selectable)
|
||||||
self.lbl_error.setStyleSheet(" QLabel { background-color:black; color:red; font-size: 16px;}")
|
self.lbl_error.setStyleSheet(
|
||||||
|
" QLabel { background-color:black; color:red; font-size: 16px;}"
|
||||||
|
)
|
||||||
self.layout_main.addWidget(self.lbl_error)
|
self.layout_main.addWidget(self.lbl_error)
|
||||||
|
|
||||||
|
|
||||||
def _on_fetch_error(self, text):
|
def _on_fetch_error(self, text):
|
||||||
self.lbl_error.setText(text)
|
self.lbl_error.setText(text)
|
||||||
self.lbl_error.setVisible(True)
|
self.lbl_error.setVisible(True)
|
||||||
|
|
||||||
def _on_uninstall_clicked(self):
|
def _on_uninstall_clicked(self):
|
||||||
theme = themeManager.database['entries'][self.list_results.currentRow()]
|
theme = themeManager.database["entries"][self.list_results.currentRow()]
|
||||||
themeManager.delete_theme(theme['name'])
|
themeManager.delete_theme(theme["name"])
|
||||||
|
|
||||||
def _on_install_clicked(self):
|
def _on_install_clicked(self):
|
||||||
theme = themeManager.database['entries'][self.list_results.currentRow()]
|
theme = themeManager.database["entries"][self.list_results.currentRow()]
|
||||||
themeManager.install_theme(theme['name'])
|
themeManager.install_theme(theme["name"])
|
||||||
|
|
||||||
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
|
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
|
||||||
def _on_theme_selected(self, item):
|
def _on_theme_selected(self, item):
|
||||||
index = self.list_results.currentRow()
|
index = self.list_results.currentRow()
|
||||||
theme = themeManager.database['entries'][index]
|
theme = themeManager.database["entries"][index]
|
||||||
theme_name = theme['name']
|
theme_name = theme["name"]
|
||||||
is_installed = themeManager.is_installed(theme_name)
|
is_installed = themeManager.is_installed(theme_name)
|
||||||
has_update = themeManager.has_update(theme_name)
|
has_update = themeManager.has_update(theme_name)
|
||||||
self.btn_install.setDisabled(False)
|
self.btn_install.setDisabled(False)
|
||||||
self.btn_install.setText( "Update" if has_update else "Install" )
|
self.btn_install.setText("Update" if has_update else "Install")
|
||||||
self.btn_install.setVisible( (is_installed and has_update) or not is_installed )
|
self.btn_install.setVisible((is_installed and has_update) or not is_installed)
|
||||||
self.btn_uninstall.setVisible( themeManager.is_installed(theme_name) )
|
self.btn_uninstall.setVisible(themeManager.is_installed(theme_name))
|
||||||
|
|
||||||
self.lbl_theme_name.setText(theme_name)
|
self.lbl_theme_name.setText(theme_name)
|
||||||
self.lbl_author_name.setText("By %s" % theme['author'])
|
self.lbl_author_name.setText("By %s" % theme["author"])
|
||||||
self.lbl_description.setText(theme['description'])
|
self.lbl_description.setText(theme["description"])
|
||||||
version_text = "Version %s" % theme['version']
|
version_text = "Version %s" % theme["version"]
|
||||||
if has_update:
|
if has_update:
|
||||||
version_text += " (installed: %s)" % themeManager.manifest[theme_name]['version']
|
version_text += (
|
||||||
self.lbl_version.setText( version_text )
|
" (installed: %s)" % themeManager.manifest[theme_name]["version"]
|
||||||
self.lbl_requires.setText( ("Requires %s" % theme['inherits'] + (' (installed)' if theme['inherits'] in self.config.availableThemes() else '')) if theme['inherits'] else "")
|
)
|
||||||
self.lbl_last_update.setText( "Released on: " + datetime.fromtimestamp(theme['updated']).strftime("%d/%m/%Y, %H:%M") )
|
self.lbl_version.setText(version_text)
|
||||||
|
self.lbl_requires.setText(
|
||||||
|
(
|
||||||
|
"Requires %s" % theme["inherits"]
|
||||||
|
+ (
|
||||||
|
" (installed)"
|
||||||
|
if theme["inherits"] in self.config.availableThemes()
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if theme["inherits"]
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
self.lbl_last_update.setText(
|
||||||
|
"Released on: "
|
||||||
|
+ datetime.fromtimestamp(theme["updated"]).strftime("%d/%m/%Y, %H:%M")
|
||||||
|
)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(dict)
|
@QtCore.pyqtSlot(dict)
|
||||||
def _on_database_refreshed(self,_):
|
def _on_database_refreshed(self, _):
|
||||||
self.rebuild()
|
self.rebuild()
|
||||||
|
|
||||||
def rebuild(self):
|
def rebuild(self):
|
||||||
|
@ -430,29 +518,34 @@ class ThemeManagerWidget(QtWidgets.QWidget):
|
||||||
self.lbl_error.setVisible(True)
|
self.lbl_error.setVisible(True)
|
||||||
|
|
||||||
# Repopulate the list
|
# Repopulate the list
|
||||||
for dbitem in database['entries']:
|
for dbitem in database["entries"]:
|
||||||
# Determine the suffix
|
# Determine the suffix
|
||||||
icon = self.icons[0]
|
icon = self.icons[0]
|
||||||
status = ''
|
status = ""
|
||||||
if themeManager.is_installed(dbitem['name']):
|
if themeManager.is_installed(dbitem["name"]):
|
||||||
if themeManager.has_update(dbitem['name']):
|
if themeManager.has_update(dbitem["name"]):
|
||||||
status = '~ (update available)'
|
status = "~ (update available)"
|
||||||
icon = self.icons[2]
|
icon = self.icons[2]
|
||||||
else:
|
else:
|
||||||
status = '~ (installed)'
|
status = "~ (installed)"
|
||||||
icon = self.icons[1]
|
icon = self.icons[1]
|
||||||
text = "%s by %s %s" % (dbitem['name'], dbitem['author'], status)
|
text = "%s by %s %s" % (dbitem["name"], dbitem["author"], status)
|
||||||
item = QtWidgets.QListWidgetItem(icon, text)
|
item = QtWidgets.QListWidgetItem(icon, text)
|
||||||
self.list_results.addItem(item)
|
self.list_results.addItem(item)
|
||||||
|
|
||||||
self.btn_install.setDisabled(True)
|
self.btn_install.setDisabled(True)
|
||||||
for lbl in [self.lbl_author_name, self.lbl_description, self.lbl_version, self.lbl_requires, self.lbl_last_update]:
|
for lbl in [
|
||||||
|
self.lbl_author_name,
|
||||||
|
self.lbl_description,
|
||||||
|
self.lbl_version,
|
||||||
|
self.lbl_requires,
|
||||||
|
self.lbl_last_update,
|
||||||
|
]:
|
||||||
lbl.setText("")
|
lbl.setText("")
|
||||||
self.lbl_theme_name.setText("Click a theme to get started")
|
self.lbl_theme_name.setText("Click a theme to get started")
|
||||||
self.btn_uninstall.setVisible(False)
|
self.btn_uninstall.setVisible(False)
|
||||||
self.btn_install.setVisible(True)
|
self.btn_install.setVisible(True)
|
||||||
self.btn_install.setDisabled(True)
|
self.btn_install.setDisabled(True)
|
||||||
|
|
||||||
|
|
||||||
self.rebuilt.emit()
|
self.rebuilt.emit()
|
||||||
PchumLog.debug("Rebuilt emitted")
|
PchumLog.debug("Rebuilt emitted")
|
Loading…
Reference in a new issue