diff --git a/src/Mod/AddonManager/AddonManager.py b/src/Mod/AddonManager/AddonManager.py
index 7253877b29..13c2440cf8 100644
--- a/src/Mod/AddonManager/AddonManager.py
+++ b/src/Mod/AddonManager/AddonManager.py
@@ -755,6 +755,8 @@ class CommandAddonManager:
real_install_succeeded, errors = macro.install(self.macro_repo_dir)
if not real_install_succeeded:
failed = True
+ else:
+ utils.update_macro_installation_details(repo)
if not failed:
message = translate(
diff --git a/src/Mod/AddonManager/addonmanager_utilities.py b/src/Mod/AddonManager/addonmanager_utilities.py
index 5cc3ca5950..1ab5fafc15 100644
--- a/src/Mod/AddonManager/addonmanager_utilities.py
+++ b/src/Mod/AddonManager/addonmanager_utilities.py
@@ -28,6 +28,7 @@ import ssl
from typing import Union
import urllib
+from urllib.request import Request
from urllib.error import URLError
from urllib.parse import urlparse
from http.client import HTTPResponse
@@ -294,14 +295,75 @@ def fix_relative_links(text, base_url):
def warning_color_string() -> str:
+ """A shade of red, adapted to darkmode if possible. Targets a minimum 7:1 contrast ratio."""
+
warningColorString = "rgb(255,0,0)"
if hasattr(QtWidgets.QApplication.instance(), "styleSheet"):
# Qt 5.9 doesn't give a QApplication instance, so can't give the stylesheet info
if "dark" in QtWidgets.QApplication.instance().styleSheet().lower():
- warningColorString = "rgb(255,50,50)"
+ warningColorString = "rgb(255,105,97)"
else:
- warningColorString = "rgb(200,0,0)"
+ warningColorString = "rgb(215,0,21)"
return warningColorString
+def bright_color_string() -> str:
+ """A shade of green, adapted to darkmode if possible. Targets a minimum 7:1 contrast ratio."""
+
+ brightColorString = "rgb(0,255,0)"
+ if hasattr(QtWidgets.QApplication.instance(), "styleSheet"):
+ # Qt 5.9 doesn't give a QApplication instance, so can't give the stylesheet info
+ if "dark" in QtWidgets.QApplication.instance().styleSheet().lower():
+ brightColorString = "rgb(48,219,91)"
+ else:
+ brightColorString = "rgb(36,138,61)"
+ return brightColorString
+
+
+def attention_color_string() -> str:
+ """A shade of orange, adapted to darkmode if possible. Targets a minimum 7:1 contrast ratio."""
+
+ attentionColorString = "rgb(255,149,0)"
+ if hasattr(QtWidgets.QApplication.instance(), "styleSheet"):
+ # Qt 5.9 doesn't give a QApplication instance, so can't give the stylesheet info
+ if "dark" in QtWidgets.QApplication.instance().styleSheet().lower():
+ attentionColorString = "rgb(255,179,64)"
+ else:
+ attentionColorString = "rgb(255,149,0)"
+ return attentionColorString
+
+
+def get_macro_version_from_file(filename: str) -> str:
+ re_version = re.compile(r"^__Version__\s*=\s*(['\"])(.*)\1", flags=re.IGNORECASE)
+ with open(filename, "r", errors="ignore") as f:
+ line_counter = 0
+ max_lines_to_scan = 50
+ while line_counter < max_lines_to_scan:
+ line_counter += 1
+ line = f.readline()
+ if line.startswith("__"):
+ match = re.match(re_version, line)
+ if match:
+ return match.group(2)
+ return ""
+
+
+def update_macro_installation_details(repo) -> None:
+ if repo is None or not hasattr(repo, "macro") or repo.macro is None:
+ FreeCAD.Console.PrintLog(f"Requested macro details for non-macro object\n")
+ return
+ test_file_one = os.path.join(FreeCAD.getUserMacroDir(True), repo.macro.filename)
+ test_file_two = os.path.join(
+ FreeCAD.getUserMacroDir(True), "Macro_" + repo.macro.filename
+ )
+ if os.path.exists(test_file_one):
+ repo.updated_timestamp = os.path.getmtime(test_file_one)
+ repo.installed_version = get_macro_version_from_file(test_file_one)
+ elif os.path.exists(test_file_two):
+ repo.updated_timestamp = os.path.getmtime(test_file_two)
+ repo.installed_version = get_macro_version_from_file(test_file_two)
+ else:
+ return
+
+
# @}
diff --git a/src/Mod/AddonManager/addonmanager_workers.py b/src/Mod/AddonManager/addonmanager_workers.py
index a75d43b355..45dd516e12 100644
--- a/src/Mod/AddonManager/addonmanager_workers.py
+++ b/src/Mod/AddonManager/addonmanager_workers.py
@@ -299,7 +299,9 @@ class LoadMacrosFromCacheWorker(QtCore.QThread):
if QtCore.QThread.currentThread().isInterruptionRequested():
return
new_macro = Macro.from_cache(item)
- self.add_macro_signal.emit(AddonManagerRepo.from_macro(new_macro))
+ repo = AddonManagerRepo.from_macro(new_macro)
+ utils.update_macro_installation_details(repo)
+ self.add_macro_signal.emit(repo)
class CheckWorkbenchesForUpdatesWorker(QtCore.QThread):
@@ -588,6 +590,7 @@ class FillMacroListWorker(QtCore.QThread):
macro.src_filename = os.path.join(dirpath, filename)
repo = AddonManagerRepo.from_macro(macro)
repo.url = "https://github.com/FreeCAD/FreeCAD-macros.git"
+ utils.update_macro_installation_details(repo)
self.add_macro_signal.emit(repo)
def retrieve_macros_from_wiki(self):
@@ -633,6 +636,7 @@ class FillMacroListWorker(QtCore.QThread):
macro.on_wiki = True
repo = AddonManagerRepo.from_macro(macro)
repo.url = "https://wiki.freecad.org/Macros_recipes"
+ utils.update_macro_installation_details(repo)
self.add_macro_signal.emit(repo)
@@ -1053,17 +1057,8 @@ class GetMacroDetailsWorker(QtCore.QThread):
mac = mac.replace("+", "%2B")
url = "https://wiki.freecad.org/Macro_" + mac
self.macro.fill_details_from_wiki(url)
- if self.macro.is_installed():
- already_installed_msg = (
- ''
- + translate("AddonsInstaller", "This macro is already installed.")
- + "
"
- )
- else:
- already_installed_msg = ""
message = (
- already_installed_msg
- + "