Addon Manager: Improve display of install details
As suggested in the forums, this adds display of the installation date and installed version to the expanded display and detail view.
This commit is contained in:
@@ -78,6 +78,7 @@ class CommandAddonManager:
|
||||
"update_metadata_cache_worker", "update_all_worker"]
|
||||
|
||||
lock = threading.Lock()
|
||||
restart_required = False
|
||||
|
||||
def __init__(self):
|
||||
FreeCADGui.addPreferencePage(os.path.join(os.path.dirname(__file__),
|
||||
@@ -201,6 +202,7 @@ class CommandAddonManager:
|
||||
self.packageDetails.uninstall.connect(self.remove)
|
||||
self.packageDetails.update.connect(self.update)
|
||||
self.packageDetails.back.connect(self.on_buttonBack_clicked)
|
||||
self.packageDetails.update_status.connect(self.status_updated)
|
||||
|
||||
# center the dialog over the FreeCAD window
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
@@ -276,8 +278,7 @@ class CommandAddonManager:
|
||||
|
||||
# all threads have finished
|
||||
if oktoclose:
|
||||
if ((hasattr(self, "install_worker") and self.install_worker) or
|
||||
(hasattr(self, "addon_removed") and self.addon_removed)):
|
||||
if self.restart_required:
|
||||
# display restart dialog
|
||||
m = QtWidgets.QMessageBox()
|
||||
m.setWindowTitle(translate("AddonsInstaller", "Addon manager"))
|
||||
@@ -478,9 +479,9 @@ class CommandAddonManager:
|
||||
self.check_worker.start()
|
||||
self.enable_updates(len(self.packages_with_updates))
|
||||
|
||||
def status_updated(self, repo:str, status:AddonManagerRepo.UpdateStatus) -> None:
|
||||
self.item_model.update_item_status(repo.name, status)
|
||||
if status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
def status_updated(self, repo:AddonManagerRepo) -> None:
|
||||
self.item_model.reload_item(repo)
|
||||
if repo.update_status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
self.packages_with_updates.append(repo)
|
||||
self.enable_updates(len(self.packages_with_updates))
|
||||
|
||||
@@ -578,6 +579,7 @@ class CommandAddonManager:
|
||||
return
|
||||
|
||||
if repo.repo_type == AddonManagerRepo.RepoType.WORKBENCH or repo.repo_type == AddonManagerRepo.RepoType.PACKAGE:
|
||||
self.show_progress_widgets()
|
||||
self.install_worker = InstallWorkbenchWorker(repo)
|
||||
self.install_worker.status_message.connect(self.show_information)
|
||||
self.current_progress_region = 1
|
||||
@@ -610,7 +612,7 @@ class CommandAddonManager:
|
||||
"now available from the Macros dialog.")
|
||||
self.on_package_installed (repo, message)
|
||||
else:
|
||||
message = translate("AddonsInstaller", "Installation of macro failed" + ":")
|
||||
message = translate("AddonsInstaller", "Installation of macro failed") + ":"
|
||||
for error in errors:
|
||||
message += "\n * "
|
||||
message += error
|
||||
@@ -629,6 +631,7 @@ class CommandAddonManager:
|
||||
self.subupdates_succeeded = []
|
||||
self.subupdates_failed = []
|
||||
|
||||
self.show_progress_widgets()
|
||||
self.current_progress_region = 1
|
||||
self.number_of_progress_regions = 1
|
||||
self.update_all_worker = UpdateAllWorker(self.packages_with_updates)
|
||||
@@ -640,7 +643,7 @@ class CommandAddonManager:
|
||||
self.update_all_worker.start()
|
||||
|
||||
def on_update_all_completed(self) -> None:
|
||||
#self.show_progress_bar(False)
|
||||
self.hide_progress_widgets()
|
||||
if not self.subupdates_failed:
|
||||
message = translate ("AddonsInstaller", "All packages were successfully updated. Packages:") + "\n"
|
||||
message += ''.join([repo.name + "\n" for repo in self.subupdates_succeeded])
|
||||
@@ -654,6 +657,9 @@ class CommandAddonManager:
|
||||
message += ''.join([repo.name + "\n" for repo in self.subupdates_failed])
|
||||
|
||||
for installed_repo in self.subupdates_succeeded:
|
||||
self.restart_required = True
|
||||
installed_repo.update_status = AddonManagerRepo.UpdateStatus.PENDING_RESTART
|
||||
self.item_model.reload_item(installed_repo)
|
||||
for requested_repo in self.packages_with_updates:
|
||||
if installed_repo.name == requested_repo.name:
|
||||
self.packages_with_updates.remove(installed_repo)
|
||||
@@ -704,22 +710,22 @@ class CommandAddonManager:
|
||||
self.hide_progress_widgets()
|
||||
|
||||
def on_package_installed(self, repo:AddonManagerRepo, message:str) -> None:
|
||||
self.hide_progress_widgets()
|
||||
QtWidgets.QMessageBox.information(None,
|
||||
translate("AddonsInstaller", "Installation succeeded"),
|
||||
message,
|
||||
QtWidgets.QMessageBox.Close)
|
||||
if repo.contains_workbench():
|
||||
self.item_model.update_item_status(repo.name, AddonManagerRepo.UpdateStatus.PENDING_RESTART)
|
||||
else:
|
||||
self.item_model.update_item_status(repo.name, AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
self.packageDetails.show_repo(repo, reload=True)
|
||||
repo.update_status = AddonManagerRepo.UpdateStatus.PENDING_RESTART
|
||||
self.item_model.reload_item(repo)
|
||||
self.packageDetails.show_repo(repo)
|
||||
self.restart_required = True
|
||||
|
||||
def on_installation_failed(self, _:AddonManagerRepo, message:str) -> None:
|
||||
self.hide_progress_widgets()
|
||||
QtWidgets.QMessageBox.warning(None,
|
||||
translate("AddonsInstaller", "Installation failed"),
|
||||
message,
|
||||
QtWidgets.QMessageBox.Close)
|
||||
self.dialog.progressBar.hide()
|
||||
|
||||
def executemacro(self, repo:AddonManagerRepo) -> None:
|
||||
"""executes a selected macro"""
|
||||
@@ -732,7 +738,7 @@ class CommandAddonManager:
|
||||
macro_path = os.path.join(self.macro_repo_dir,macro.filename)
|
||||
FreeCADGui.open(str(macro_path))
|
||||
self.dialog.hide()
|
||||
FreeCADGui.SendMsgToActiveView("Run")
|
||||
FreeCADGui.SendMsgToActiveView("Run")
|
||||
else:
|
||||
with tempfile.TemporaryDirectory() as dir:
|
||||
temp_install_succeeded = macro.install(dir)
|
||||
@@ -764,7 +770,8 @@ class CommandAddonManager:
|
||||
shutil.rmtree(clonedir, onerror=self.remove_readonly)
|
||||
self.item_model.update_item_status(repo.name, AddonManagerRepo.UpdateStatus.NOT_INSTALLED)
|
||||
self.addon_removed = True # A value to trigger the restart message on dialog close
|
||||
self.packageDetails.show_repo(repo, reload=True)
|
||||
self.packageDetails.show_repo(repo)
|
||||
self.restart_required = True
|
||||
else:
|
||||
self.dialog.textBrowserReadMe.setText(translate("AddonsInstaller", "Unable to remove this addon with the Addon Manager."))
|
||||
|
||||
@@ -772,7 +779,7 @@ class CommandAddonManager:
|
||||
macro = repo.macro
|
||||
if macro.remove():
|
||||
self.item_model.update_item_status(repo.name, AddonManagerRepo.UpdateStatus.NOT_INSTALLED)
|
||||
self.packageDetails.show_repo(repo, reload=True)
|
||||
self.packageDetails.show_repo(repo)
|
||||
else:
|
||||
self.dialog.textBrowserReadMe.setText(translate("AddonsInstaller", "Macro could not be removed."))
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ class AddonManagerRepo:
|
||||
self.icon = None
|
||||
self.cached_icon_filename = ""
|
||||
self.macro = None # Bridge to Gaël Écorchard's macro management class
|
||||
self.updated_timestamp = None
|
||||
self.installed_version = None
|
||||
|
||||
def __str__ (self) -> str:
|
||||
result = f"FreeCAD {self.repo_type}\n"
|
||||
|
||||
@@ -30,6 +30,7 @@ import tempfile
|
||||
import hashlib
|
||||
import threading
|
||||
import queue
|
||||
from datetime import datetime
|
||||
from typing import Union, List
|
||||
|
||||
from PySide2 import QtCore, QtGui, QtNetwork
|
||||
@@ -39,11 +40,11 @@ if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
|
||||
import addonmanager_utilities as utils
|
||||
from addonmanager_utilities import translate # this needs to be as is for pylupdate
|
||||
from addonmanager_macro import Macro
|
||||
from addonmanager_metadata import MetadataDownloadWorker
|
||||
from AddonManagerRepo import AddonManagerRepo
|
||||
|
||||
translate = FreeCAD.Qt.translate
|
||||
|
||||
have_git = False
|
||||
try:
|
||||
@@ -240,9 +241,7 @@ class LoadMacrosFromCacheWorker(QtCore.QThread):
|
||||
class CheckWorkbenchesForUpdatesWorker(QtCore.QThread):
|
||||
"""This worker checks for available updates for all workbenches"""
|
||||
|
||||
# Emitting an Enum fails on Ubuntu 20.04, so use an int instead
|
||||
#update_status = QtCore.Signal(AddonManagerRepo, AddonManagerRepo.UpdateStatus)
|
||||
update_status = QtCore.Signal(AddonManagerRepo, int)
|
||||
update_status = QtCore.Signal(AddonManagerRepo)
|
||||
progress_made = QtCore.Signal(int, int)
|
||||
done = QtCore.Signal()
|
||||
|
||||
@@ -307,31 +306,47 @@ class CheckWorkbenchesForUpdatesWorker(QtCore.QThread):
|
||||
try:
|
||||
gitrepo.fetch()
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintWarning("AddonManager: Unable to fetch git updates for workbench " + wb.name)
|
||||
FreeCAD.Console.PrintWarning("AddonManager: " + translate("AddonsInstaller","Unable to fetch git updates for workbench") + " " + wb.name)
|
||||
else:
|
||||
try:
|
||||
if "git pull" in gitrepo.status():
|
||||
self.update_status.emit(wb, AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE)
|
||||
wb.update_status = AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE
|
||||
else:
|
||||
self.update_status.emit(wb, AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
except stderr:
|
||||
wb.update_status = AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE
|
||||
self.update_status.emit(wb)
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintWarning("AddonManager - " + wb.name + " git status"
|
||||
" fatal: this operation must be run in a work tree \n")
|
||||
|
||||
def check_package(self, package):
|
||||
def check_package(self, package:AddonManagerRepo) -> None:
|
||||
clonedir = self.moddir + os.sep + package.name
|
||||
if os.path.exists(clonedir):
|
||||
installed_metadata_file = os.path.join(clonedir, "package.xml")
|
||||
installed_metadata = FreeCAD.Metadata(installed_metadata_file)
|
||||
# Packages are considered up-to-date if the metadata version matches. Authors should update
|
||||
# their version string when they want the addon manager to alert users of a new version.
|
||||
if package.metadata.Version > installed_metadata.Version:
|
||||
self.update_status.emit(package, AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE)
|
||||
if not os.path.isfile(installed_metadata_file):
|
||||
# If there is no package.xml file, then it's because the package author added it after the last time
|
||||
# the local installation was updated. By definition, then, there is an update available, if only to
|
||||
# download the new XML file.
|
||||
package.update_status = AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE
|
||||
package.installed_version = None
|
||||
self.update_status.emit(package)
|
||||
return
|
||||
else:
|
||||
self.update_status.emit(package, AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
package.updated_timestamp = os.path.getmtime(installed_metadata_file)
|
||||
try:
|
||||
installed_metadata = FreeCAD.Metadata(installed_metadata_file)
|
||||
package.installed_version = installed_metadata.Version
|
||||
# Packages are considered up-to-date if the metadata version matches. Authors should update
|
||||
# their version string when they want the addon manager to alert users of a new version.
|
||||
if package.metadata.Version != installed_metadata.Version:
|
||||
package.update_status = AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE
|
||||
else:
|
||||
package.update_status = AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE
|
||||
self.update_status.emit(package)
|
||||
except Exception as e:
|
||||
FreeCAD.Console.PrintWarning(translate("AddonsInstaller", "Failed to read metadata from") + f" {installed_metadata_file}")
|
||||
|
||||
|
||||
def check_macro(self, macro_wrapper):
|
||||
def check_macro(self, macro_wrapper:AddonManagerRepo) -> None:
|
||||
# Make sure this macro has its code downloaded:
|
||||
try:
|
||||
if not macro_wrapper.macro.parsed and macro_wrapper.macro.on_git:
|
||||
@@ -365,9 +380,10 @@ class CheckWorkbenchesForUpdatesWorker(QtCore.QThread):
|
||||
else:
|
||||
return
|
||||
if new_sha1 == old_sha1:
|
||||
self.update_status.emit(macro_wrapper, AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE)
|
||||
macro_wrapper.update_status = AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE
|
||||
else:
|
||||
self.update_status.emit(macro_wrapper, AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE)
|
||||
macro_wrapper.update_status = AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE
|
||||
self.update_status.emit(macro_wrapper)
|
||||
|
||||
|
||||
class FillMacroListWorker(QtCore.QThread):
|
||||
@@ -489,7 +505,7 @@ class ShowWorker(QtCore.QThread):
|
||||
|
||||
status_message = QtCore.Signal(str)
|
||||
readme_updated = QtCore.Signal(str)
|
||||
addon_repos = QtCore.Signal(object)
|
||||
update_status = QtCore.Signal(AddonManagerRepo)
|
||||
done = QtCore.Signal()
|
||||
|
||||
def __init__(self, repo, cache_path):
|
||||
@@ -570,9 +586,9 @@ class ShowWorker(QtCore.QThread):
|
||||
self.repo.description = desc
|
||||
if QtCore.QThread.currentThread().isInterruptionRequested():
|
||||
return
|
||||
self.addon_repos.emit(self.repo)
|
||||
# Addon is installed so lets check if it has an update
|
||||
if self.repo.update_status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
message = desc
|
||||
if self.repo.update_status == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
# Addon is installed but we haven't checked it yet, so lets check if it has an update
|
||||
upd = False
|
||||
# checking for updates
|
||||
if not NOGIT and have_git:
|
||||
@@ -598,72 +614,14 @@ class ShowWorker(QtCore.QThread):
|
||||
gitrepo.fetch()
|
||||
if "git pull" in gitrepo.status():
|
||||
upd = True
|
||||
# If there is an update pending, lets user know via the UI
|
||||
if upd:
|
||||
message = """
|
||||
<div style="width: 100%;text-align: center;background: #75AFFD;">
|
||||
<br/>
|
||||
<strong style="background: #397FF7;color: #FFFFFF;">
|
||||
"""
|
||||
message += translate("AddonsInstaller", "An update is available for this addon.")
|
||||
message += "</strong><br/></div><hr/>" + desc + '<br/><br/>Addon repository: <a href="'
|
||||
message += self.repo.url + '">' + self.repo.url + "</a>"
|
||||
self.repo.update_status = AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE
|
||||
# If there isn't, indicate that this addon is already installed
|
||||
else:
|
||||
message = """
|
||||
<div style="width: 100%;text-align: center;background: #C1FEB2;">
|
||||
<br/>
|
||||
<strong style="background: #00B629;color: #FFFFFF;">
|
||||
"""
|
||||
message += translate("AddonsInstaller", "This addon is already installed.")
|
||||
message += "</strong><br/></div><hr/>" + desc
|
||||
message += '<br/><br/>Addon repository: <a href="'
|
||||
message += self.repo.url + '">' + self.repo.url + "</a>"
|
||||
self.repo.update_status = AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE
|
||||
# Let the user know the install path for this addon
|
||||
message += "<br/>" + translate("AddonsInstaller", "Installed location") + ": "
|
||||
message += FreeCAD.getUserAppDataDir() + os.sep + "Mod" + os.sep + self.repo.name
|
||||
self.update_status.emit(self.repo)
|
||||
|
||||
if QtCore.QThread.currentThread().isInterruptionRequested():
|
||||
return
|
||||
self.addon_repos.emit(self.repo)
|
||||
elif self.repo.update_status == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
message = """
|
||||
<div style="width: 100%;text-align: center;background: #C1FEB2;">
|
||||
<br/>
|
||||
<strong style="background: #00B629;color: #FFFFFF;">
|
||||
"""
|
||||
message += translate("AddonsInstaller", "This addon has been updated, a restart is now required before it can be used.")
|
||||
message += "</strong><br/></div><hr/>" + desc + '<br/><br/>Addon repository: <a href="'
|
||||
message += self.repo.url + '">' + self.repo.url + "</a>"
|
||||
message += "<br/>" + translate("AddonsInstaller", "Installed location") + ": "
|
||||
message += FreeCAD.getUserAppDataDir() + os.sep + "Mod" + os.sep + self.repo.name
|
||||
elif self.repo.update_status == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
message = """
|
||||
<div style="width: 100%;text-align: center;background: #C1FEB2;">
|
||||
<br/>
|
||||
<strong style="background: #00B629;color: #FFFFFF;">
|
||||
"""
|
||||
message += translate("AddonsInstaller", "This addon is already installed.")
|
||||
message += "</strong><br></div><hr/>" + desc
|
||||
message += '<br/><br/>Addon repository: <a href="'
|
||||
message += self.repo.url + '">' + self.repo.url + "</a>"
|
||||
message += "<br/>" + translate("AddonsInstaller", "Installed location") + ": "
|
||||
message += FreeCAD.getUserAppDataDir() + os.sep + "Mod" + os.sep + self.repo.name
|
||||
elif self.repo.update_status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
message = """
|
||||
<div style="width: 100%;text-align: center;background: #75AFFD;">
|
||||
<br/>
|
||||
<strong style="background: #397FF7;color: #FFFFFF;">
|
||||
"""
|
||||
message += translate("AddonsInstaller", "An update is available for this addon.")
|
||||
message += "</strong><br/></div><hr/>" + desc + '<br/><br/>Addon repository: <a href="'
|
||||
message += self.repo.url + '">' + self.repo.url + "</a>"
|
||||
message += "<br/>" + translate("AddonsInstaller", "Installed location") + ": "
|
||||
message += FreeCAD.getUserAppDataDir() + os.sep + "Mod" + os.sep + self.repo.name
|
||||
else:
|
||||
message = desc + '<br/><br/>Addon repository: <a href="'
|
||||
message += self.repo.url + '">' + self.repo.url + '</a>'
|
||||
|
||||
# If the Addon is obsolete, let the user know through the Addon UI
|
||||
if self.repo.name in obsolete:
|
||||
@@ -905,6 +863,7 @@ class InstallWorkbenchWorker(QtCore.QThread):
|
||||
self.status_message.emit("Updating submodules...")
|
||||
for submodule in repo_sms.submodules:
|
||||
submodule.update(init=True, recursive=True)
|
||||
self.update_metadata()
|
||||
self.success.emit(self.repo, answer)
|
||||
|
||||
def run_git_clone(self, clonedir:str) -> None:
|
||||
@@ -946,6 +905,7 @@ class InstallWorkbenchWorker(QtCore.QThread):
|
||||
"A macro has been installed and is available "
|
||||
"under Macro -> Macros menu")
|
||||
answer += ":\n<b>" + f + "</b>"
|
||||
self.update_metadata()
|
||||
self.success.emit(self.repo, answer)
|
||||
|
||||
def check_python_dependencies(self, baseurl:str) -> Union[bool,str]:
|
||||
@@ -960,7 +920,7 @@ class InstallWorkbenchWorker(QtCore.QThread):
|
||||
try:
|
||||
mu = utils.urlopen(depsurl)
|
||||
except Exception:
|
||||
return True,"No metadata.txt found"
|
||||
return True, translate("AddonsInstaller", "No metadata.txt found, cannot evaluate Python dependencies")
|
||||
if mu:
|
||||
# metadata.txt found
|
||||
depsfile = mu.read()
|
||||
@@ -1003,7 +963,7 @@ class InstallWorkbenchWorker(QtCore.QThread):
|
||||
"Missing optional python module (doesn't prevent installing)")
|
||||
message += ": " + pl + ", "
|
||||
if message and (not ok):
|
||||
message = translate("AddonsInstaller", "Some errors were found that prevent to install this workbench")
|
||||
message = translate("AddonsInstaller", "Some errors were found that prevent installation of this workbench")
|
||||
message += ": <b>" + message + "</b>. "
|
||||
message += translate("AddonsInstaller", "Please install the missing components first.")
|
||||
return ok, message
|
||||
@@ -1067,8 +1027,17 @@ class InstallWorkbenchWorker(QtCore.QThread):
|
||||
os.rmdir(zipdir + os.sep + master)
|
||||
if bakdir:
|
||||
shutil.rmtree(bakdir)
|
||||
self.update_metadata()
|
||||
self.success.emit(self.repo, translate("AddonsInstaller", "Successfully installed") + " " + zipurl)
|
||||
|
||||
def update_metadata(self):
|
||||
basedir = FreeCAD.getUserAppDataDir()
|
||||
package_xml = os.path.join(basedir,"Mod",self.repo.name,"package.xml")
|
||||
if os.path.isfile(package_xml):
|
||||
self.repo.metadata = FreeCAD.Metadata(package_xml)
|
||||
self.repo.installed_version = self.repo.metadata.Version
|
||||
self.repo.updated_timestamp = datetime.now().timestamp()
|
||||
|
||||
class CheckSingleWorker(QtCore.QThread):
|
||||
"""Worker to check for updates for a single addon"""
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ class PackageDetails(QWidget):
|
||||
uninstall = Signal(AddonManagerRepo)
|
||||
update = Signal(AddonManagerRepo)
|
||||
execute = Signal(AddonManagerRepo)
|
||||
update_status = Signal(AddonManagerRepo)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
@@ -86,6 +87,45 @@ class PackageDetails(QWidget):
|
||||
self.show_package(repo)
|
||||
self.ui.buttonExecute.hide()
|
||||
|
||||
if repo.update_status != AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
installed_version_string = ""
|
||||
if repo.installed_version:
|
||||
installed_version_string = translate("AddonsInstaller", "Version") + " "
|
||||
installed_version_string += repo.installed_version
|
||||
else:
|
||||
installed_version_string = translate("AddonsInstaller", "Unknown version (no package.xml file found)") + " "
|
||||
|
||||
|
||||
if repo.updated_timestamp:
|
||||
installed_version_string += " " + translate("AddonsInstaller", "installed on") + " "
|
||||
installed_version_string += QDateTime.fromTime_t(repo.updated_timestamp).date().toString(Qt.SystemLocaleShortDate)
|
||||
installed_version_string += ". "
|
||||
else:
|
||||
installed_version_string += translate("AddonsInstaller", "installed") + ". "
|
||||
|
||||
if repo.update_status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
if repo.metadata:
|
||||
installed_version_string += "<b>" + translate("AddonsInstaller", "Update available to version") + " "
|
||||
installed_version_string += repo.metadata.Version
|
||||
installed_version_string += ".</b>"
|
||||
else:
|
||||
installed_version_string += "<b>" + translate("AddonsInstaller", "Update available to unknown version (no package.xml file found)") + ".</b>"
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
installed_version_string += translate("AddonsInstaller", "This is the latest version available") + "."
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
installed_version_string += translate("AddonsInstaller", "Updated, please restart FreeCAD to use") + "."
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
installed_version_string += translate("AddonsInstaller", "Update check in progress") + "."
|
||||
|
||||
basedir = FreeCAD.getUserAppDataDir()
|
||||
moddir = os.path.join(basedir , "Mod", repo.name)
|
||||
installed_version_string += "<br/>" + translate("AddonsInstaller", "Installation location") + ": " + moddir
|
||||
|
||||
self.ui.labelPackageDetails.setText(installed_version_string)
|
||||
self.ui.labelPackageDetails.show()
|
||||
else:
|
||||
self.ui.labelPackageDetails.hide()
|
||||
|
||||
if repo.update_status == AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
self.ui.buttonInstall.show()
|
||||
self.ui.buttonUninstall.hide()
|
||||
@@ -160,6 +200,8 @@ class PackageDetails(QWidget):
|
||||
self.worker = ShowWorker(repo, PackageDetails.cache_path(repo))
|
||||
self.worker.readme_updated.connect(lambda desc: self.cache_readme(repo, desc))
|
||||
self.worker.readme_updated.connect(lambda desc: self.ui.textBrowserReadMe.setText(desc))
|
||||
self.worker.update_status.connect(self.update_status.emit)
|
||||
self.worker.update_status.connect(self.show)
|
||||
self.worker.start()
|
||||
|
||||
def show_package(self, repo:AddonManagerRepo) -> None:
|
||||
@@ -170,6 +212,8 @@ class PackageDetails(QWidget):
|
||||
self.worker = ShowWorker(repo,PackageDetails.cache_path(repo))
|
||||
self.worker.readme_updated.connect(lambda desc: self.cache_readme(repo, desc))
|
||||
self.worker.readme_updated.connect(lambda desc: self.ui.textBrowserReadMe.setText(desc))
|
||||
self.worker.update_status.connect(self.update_status.emit)
|
||||
self.worker.update_status.connect(self.show)
|
||||
self.worker.start()
|
||||
|
||||
def show_macro(self, repo:AddonManagerRepo) -> None:
|
||||
@@ -232,9 +276,13 @@ class Ui_PackageDetails(object):
|
||||
|
||||
self.layoutDetailsBackButton.addWidget(self.buttonExecute)
|
||||
|
||||
|
||||
self.verticalLayout_2.addLayout(self.layoutDetailsBackButton)
|
||||
|
||||
self.labelPackageDetails = QLabel(PackageDetails)
|
||||
self.labelPackageDetails.hide()
|
||||
|
||||
self.verticalLayout_2.addWidget(self.labelPackageDetails)
|
||||
|
||||
self.textBrowserReadMe = QTextBrowser(PackageDetails)
|
||||
self.textBrowserReadMe.setObjectName(u"textBrowserReadMe")
|
||||
self.textBrowserReadMe.setOpenExternalLinks(True)
|
||||
|
||||
@@ -76,6 +76,19 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelInstallationDetails">
|
||||
<property name="text">
|
||||
<string notr="true">Installation details go here</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="textBrowserReadMe"/>
|
||||
</item>
|
||||
|
||||
@@ -28,6 +28,7 @@ from PySide2.QtCore import *
|
||||
from PySide2.QtGui import *
|
||||
from PySide2.QtWidgets import *
|
||||
|
||||
import datetime
|
||||
from typing import Dict, Union
|
||||
from enum import IntEnum
|
||||
import threading
|
||||
@@ -291,18 +292,68 @@ class PackageListItemDelegate(QStyledItemDelegate):
|
||||
self.widget.ui.labelMaintainer.setText("")
|
||||
|
||||
# Update status
|
||||
if repo.update_status == AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
self.widget.ui.labelStatus.setText("")
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
self.widget.ui.labelStatus.setText(translate("AddonsInstaller","Installed"))
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
self.widget.ui.labelStatus.setText(translate("AddonsInstaller","Up-to-date"))
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
self.widget.ui.labelStatus.setText(translate("AddonsInstaller","Update available"))
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
self.widget.ui.labelStatus.setText(translate("AddonsInstaller","Pending restart"))
|
||||
if self.displayStyle == ListDisplayStyle.EXPANDED:
|
||||
self.widget.ui.labelStatus.setText(self.get_expanded_update_string(repo))
|
||||
else:
|
||||
self.widget.ui.labelStatus.setText(self.get_compact_update_string(repo))
|
||||
|
||||
self.widget.adjustSize()
|
||||
|
||||
def get_compact_update_string(self, repo:AddonManagerRepo) -> str:
|
||||
""" Get a single-line string listing details about the installed version and date """
|
||||
|
||||
result = ""
|
||||
if repo.update_status == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
result = translate("AddonsInstaller","Installed")
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller","Up-to-date")
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller","Update available")
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
result = translate("AddonsInstaller","Pending restart")
|
||||
return result
|
||||
|
||||
def get_expanded_update_string(self, repo:AddonManagerRepo) -> str:
|
||||
""" Get a multi-line string listing details about the installed version and date """
|
||||
|
||||
result = ""
|
||||
|
||||
installed_version_string = ""
|
||||
if repo.update_status != AddonManagerRepo.UpdateStatus.NOT_INSTALLED:
|
||||
if repo.installed_version:
|
||||
installed_version_string = "\n" + translate("AddonsInstaller", "Installed version") + ": "
|
||||
installed_version_string += repo.installed_version
|
||||
else:
|
||||
installed_version_string = "\n" + translate("AddonsInstaller", "Unknown version")
|
||||
|
||||
installed_date_string = ""
|
||||
if repo.updated_timestamp:
|
||||
installed_date_string = "\n" + translate("AddonsInstaller", "Installed on") + ": "
|
||||
installed_date_string += QDateTime.fromTime_t(repo.updated_timestamp).date().toString(Qt.SystemLocaleShortDate)
|
||||
|
||||
available_version_string = ""
|
||||
if repo.metadata:
|
||||
available_version_string = "\n" + translate("AddonsInstaller", "Available version") + ": "
|
||||
available_version_string += repo.metadata.Version
|
||||
|
||||
if repo.update_status == AddonManagerRepo.UpdateStatus.UNCHECKED:
|
||||
result = translate("AddonsInstaller","Installed")
|
||||
result += installed_version_string
|
||||
result += installed_date_string
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.NO_UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller","Up-to-date")
|
||||
result += installed_version_string
|
||||
result += installed_date_string
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.UPDATE_AVAILABLE:
|
||||
result = translate("AddonsInstaller","Update available")
|
||||
result += installed_version_string
|
||||
result += installed_date_string
|
||||
result += available_version_string
|
||||
elif repo.update_status == AddonManagerRepo.UpdateStatus.PENDING_RESTART:
|
||||
result = translate("AddonsInstaller","Pending restart")
|
||||
|
||||
return result
|
||||
|
||||
def paint(self, painter:QPainter, option:QStyleOptionViewItem, index:QModelIndex):
|
||||
painter.save()
|
||||
self.widget.resize(option.rect.size())
|
||||
|
||||
Reference in New Issue
Block a user