feat: Add toolbar icon configuration and update handling for Agravity
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
This commit is contained in:
parent
eab1009d8c
commit
df76cb9b36
8 changed files with 112 additions and 15 deletions
|
|
@ -14,5 +14,9 @@
|
|||
"icon_icns": "resources/icons/app.icns",
|
||||
"dialog_bmp": "resources/icons/background.bmp",
|
||||
"banner_bmp": "resources/icons/banner.bmp",
|
||||
"license_rtf": "resources/license.rtf"
|
||||
"license_rtf": "resources/license.rtf",
|
||||
"toolbar_icon_home": "resources/icons/home.ico",
|
||||
"toolbar_icon_reload": "resources/icons/reload.ico",
|
||||
"toolbar_icon_open": "resources/icons/open.ico",
|
||||
"toolbar_icon_openwith": "resources/icons/openwith.ico"
|
||||
}
|
||||
|
|
@ -16,5 +16,9 @@
|
|||
"icon_icns": "resources/icons/app.icns",
|
||||
"dialog_bmp": "resources/icons/background.bmp",
|
||||
"banner_bmp": "resources/icons/banner.bmp",
|
||||
"license_rtf": "resources/license.rtf"
|
||||
"license_rtf": "resources/license.rtf",
|
||||
"toolbar_icon_home": "resources/icons/home.ico",
|
||||
"toolbar_icon_reload": "resources/icons/reload.ico",
|
||||
"toolbar_icon_open": "resources/icons/open.ico",
|
||||
"toolbar_icon_openwith": "resources/icons/openwith.ico"
|
||||
}
|
||||
|
|
@ -29,6 +29,10 @@ class BrandConfig:
|
|||
dialog_bmp: Path
|
||||
banner_bmp: Path
|
||||
license_rtf: Path
|
||||
toolbar_icon_home: str
|
||||
toolbar_icon_reload: str
|
||||
toolbar_icon_open: str
|
||||
toolbar_icon_openwith: str
|
||||
|
||||
def windows_installer_name(self, version: str) -> str:
|
||||
return f"{self.asset_prefix}-{version}-win-x64.msi"
|
||||
|
|
@ -58,6 +62,10 @@ DEFAULT_BRAND_VALUES: dict[str, Any] = {
|
|||
"dialog_bmp": "resources/icons/background.bmp",
|
||||
"banner_bmp": "resources/icons/banner.bmp",
|
||||
"license_rtf": "resources/license.rtf",
|
||||
"toolbar_icon_home": "resources/icons/home.ico",
|
||||
"toolbar_icon_reload": "resources/icons/reload.ico",
|
||||
"toolbar_icon_open": "resources/icons/open.ico",
|
||||
"toolbar_icon_openwith": "resources/icons/openwith.ico",
|
||||
}
|
||||
|
||||
DEFAULT_BRAND_ID = str(DEFAULT_BRAND_VALUES["brand_id"])
|
||||
|
|
@ -125,6 +133,18 @@ def load_brand_config(
|
|||
dialog_bmp=resolve_asset("dialog_bmp"),
|
||||
banner_bmp=resolve_asset("banner_bmp"),
|
||||
license_rtf=resolve_asset("license_rtf"),
|
||||
toolbar_icon_home=str(
|
||||
values.get("toolbar_icon_home", DEFAULT_BRAND_VALUES["toolbar_icon_home"])
|
||||
),
|
||||
toolbar_icon_reload=str(
|
||||
values.get("toolbar_icon_reload", DEFAULT_BRAND_VALUES["toolbar_icon_reload"])
|
||||
),
|
||||
toolbar_icon_open=str(
|
||||
values.get("toolbar_icon_open", DEFAULT_BRAND_VALUES["toolbar_icon_open"])
|
||||
),
|
||||
toolbar_icon_openwith=str(
|
||||
values.get("toolbar_icon_openwith", DEFAULT_BRAND_VALUES["toolbar_icon_openwith"])
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -272,6 +292,10 @@ def cli_env(args: argparse.Namespace) -> int:
|
|||
"WEBDROP_UPDATE_CHANNEL": brand.update_channel,
|
||||
"WEBDROP_ICON_ICO": str(brand.icon_ico),
|
||||
"WEBDROP_ICON_ICNS": str(brand.icon_icns),
|
||||
"WEBDROP_TOOLBAR_ICON_HOME": brand.toolbar_icon_home,
|
||||
"WEBDROP_TOOLBAR_ICON_RELOAD": brand.toolbar_icon_reload,
|
||||
"WEBDROP_TOOLBAR_ICON_OPEN": brand.toolbar_icon_open,
|
||||
"WEBDROP_TOOLBAR_ICON_OPENWITH": brand.toolbar_icon_openwith,
|
||||
}
|
||||
for key, value in assignments.items():
|
||||
print(f'export {key}="{value}"')
|
||||
|
|
@ -324,6 +348,10 @@ def cli_show(args: argparse.Namespace) -> int:
|
|||
"config_dir_name": brand.config_dir_name,
|
||||
"msi_upgrade_code": brand.msi_upgrade_code,
|
||||
"update_channel": brand.update_channel,
|
||||
"toolbar_icon_home": brand.toolbar_icon_home,
|
||||
"toolbar_icon_reload": brand.toolbar_icon_reload,
|
||||
"toolbar_icon_open": brand.toolbar_icon_open,
|
||||
"toolbar_icon_openwith": brand.toolbar_icon_openwith,
|
||||
},
|
||||
indent=2,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -211,6 +211,10 @@ build_executable() {
|
|||
echo "BRAND_ID=\"$WEBDROP_BRAND_ID\""
|
||||
echo "APP_CONFIG_DIR_NAME=\"$WEBDROP_CONFIG_DIR_NAME\""
|
||||
echo "UPDATE_CHANNEL=\"$WEBDROP_UPDATE_CHANNEL\""
|
||||
echo "TOOLBAR_ICON_HOME=\"$WEBDROP_TOOLBAR_ICON_HOME\""
|
||||
echo "TOOLBAR_ICON_RELOAD=\"$WEBDROP_TOOLBAR_ICON_RELOAD\""
|
||||
echo "TOOLBAR_ICON_OPEN=\"$WEBDROP_TOOLBAR_ICON_OPEN\""
|
||||
echo "TOOLBAR_ICON_OPENWITH=\"$WEBDROP_TOOLBAR_ICON_OPENWITH\""
|
||||
} >> "$BUNDLED_ENV_FILE"
|
||||
|
||||
# Export env file for spec file to pick up
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ class WindowsBuilder:
|
|||
"BRAND_ID": self.brand.brand_id,
|
||||
"APP_CONFIG_DIR_NAME": self.brand.config_dir_name,
|
||||
"UPDATE_CHANNEL": self.brand.update_channel,
|
||||
"TOOLBAR_ICON_HOME": self.brand.toolbar_icon_home,
|
||||
"TOOLBAR_ICON_RELOAD": self.brand.toolbar_icon_reload,
|
||||
"TOOLBAR_ICON_OPEN": self.brand.toolbar_icon_open,
|
||||
"TOOLBAR_ICON_OPENWITH": self.brand.toolbar_icon_openwith,
|
||||
}
|
||||
|
||||
output_env = self.temp_dir / ".env"
|
||||
|
|
|
|||
|
|
@ -106,8 +106,20 @@ These can point at brand-specific files or default shared files:
|
|||
- `banner_bmp`
|
||||
- `license_rtf`
|
||||
|
||||
Optional toolbar icon overrides:
|
||||
|
||||
- `toolbar_icon_home`
|
||||
- `toolbar_icon_reload`
|
||||
- `toolbar_icon_open`
|
||||
- `toolbar_icon_openwith`
|
||||
|
||||
If a referenced asset path does not exist, the helper falls back to the default asset defined in `build/scripts/brand_config.py`.
|
||||
|
||||
For toolbar icons, the runtime looks for the configured paths in packaged and development layouts. If an icon is missing:
|
||||
|
||||
- Home falls back to a standard Qt home icon
|
||||
- Reload/Open/OpenWith keep their existing icon behavior
|
||||
|
||||
### Identity Rules
|
||||
|
||||
Treat these values as long-lived product identity once a brand has shipped:
|
||||
|
|
@ -163,6 +175,13 @@ Relevant runtime config keys include:
|
|||
- `update_channel`
|
||||
- `update_manifest_name`
|
||||
|
||||
Toolbar icon env overrides (useful for packaged branding):
|
||||
|
||||
- `TOOLBAR_ICON_HOME`
|
||||
- `TOOLBAR_ICON_RELOAD`
|
||||
- `TOOLBAR_ICON_OPEN`
|
||||
- `TOOLBAR_ICON_OPENWITH`
|
||||
|
||||
The current example in `config.example.json` shows the Agravity runtime setup.
|
||||
|
||||
When adding a new brand, make sure the runtime config matches the packaging manifest at least for:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
|
@ -1386,16 +1387,13 @@ class MainWindow(QMainWindow):
|
|||
# Separator
|
||||
toolbar.addSeparator()
|
||||
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
icons_dir = Path(sys._MEIPASS) / "resources" / "icons" # type: ignore[attr-defined]
|
||||
else:
|
||||
icons_dir = Path(__file__).parent.parent.parent.parent / "resources" / "icons"
|
||||
|
||||
# Home button
|
||||
home_icon_path = icons_dir / "home.ico"
|
||||
home_icon_path = self._resolve_toolbar_icon_path(
|
||||
os.getenv("TOOLBAR_ICON_HOME", "resources/icons/home.ico")
|
||||
)
|
||||
home_icon = (
|
||||
QIcon(str(home_icon_path))
|
||||
if home_icon_path.exists()
|
||||
if home_icon_path is not None
|
||||
else self.style().standardIcon(self.style().StandardPixmap.SP_DirHomeIcon)
|
||||
)
|
||||
home_action = toolbar.addAction(home_icon, "")
|
||||
|
|
@ -1404,15 +1402,19 @@ class MainWindow(QMainWindow):
|
|||
|
||||
# Refresh button
|
||||
refresh_action = self.web_view.pageAction(self.web_view.page().WebAction.Reload)
|
||||
reload_icon_path = icons_dir / "reload.ico"
|
||||
if reload_icon_path.exists():
|
||||
reload_icon_path = self._resolve_toolbar_icon_path(
|
||||
os.getenv("TOOLBAR_ICON_RELOAD", "resources/icons/reload.ico")
|
||||
)
|
||||
if reload_icon_path is not None:
|
||||
refresh_action.setIcon(QIcon(str(reload_icon_path)))
|
||||
toolbar.addAction(refresh_action)
|
||||
|
||||
# Open-with-default-app drop zone (right of Reload)
|
||||
self._open_drop_zone = OpenDropZone()
|
||||
open_icon_path = icons_dir / "open.ico"
|
||||
if open_icon_path.exists():
|
||||
open_icon_path = self._resolve_toolbar_icon_path(
|
||||
os.getenv("TOOLBAR_ICON_OPEN", "resources/icons/open.ico")
|
||||
)
|
||||
if open_icon_path is not None:
|
||||
self._open_drop_zone.set_icon(QIcon(str(open_icon_path)))
|
||||
self._open_drop_zone.file_opened.connect(self._on_file_opened_via_drop)
|
||||
self._open_drop_zone.file_open_failed.connect(self._on_file_open_failed_via_drop)
|
||||
|
|
@ -1422,8 +1424,10 @@ class MainWindow(QMainWindow):
|
|||
|
||||
# Open-with chooser drop zone (right of Open-with-default-app)
|
||||
self._open_with_drop_zone = OpenWithDropZone()
|
||||
open_with_icon_path = icons_dir / "openwith.ico"
|
||||
if open_with_icon_path.exists():
|
||||
open_with_icon_path = self._resolve_toolbar_icon_path(
|
||||
os.getenv("TOOLBAR_ICON_OPENWITH", "resources/icons/openwith.ico")
|
||||
)
|
||||
if open_with_icon_path is not None:
|
||||
self._open_with_drop_zone.set_icon(QIcon(str(open_with_icon_path)))
|
||||
self._open_with_drop_zone.file_open_with_requested.connect(
|
||||
self._on_file_open_with_requested
|
||||
|
|
@ -1467,6 +1471,32 @@ class MainWindow(QMainWindow):
|
|||
dev_tools_action.setToolTip(tr("toolbar.tooltip.dev_tools"))
|
||||
dev_tools_action.triggered.connect(self._open_developer_tools)
|
||||
|
||||
def _resolve_toolbar_icon_path(self, configured_path: str) -> Path | None:
|
||||
"""Resolve configured toolbar icon path in both dev and packaged layouts."""
|
||||
icon_path = Path(configured_path)
|
||||
|
||||
candidates: list[Path] = []
|
||||
if icon_path.is_absolute():
|
||||
candidates.append(icon_path)
|
||||
else:
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
meipass = Path(sys._MEIPASS) # type: ignore[attr-defined]
|
||||
candidates.append(meipass / icon_path)
|
||||
|
||||
exe_dir = Path(sys.executable).resolve().parent
|
||||
candidates.append(exe_dir / icon_path)
|
||||
candidates.append(exe_dir / "_internal" / icon_path)
|
||||
|
||||
project_root = Path(__file__).parent.parent.parent.parent
|
||||
candidates.append(project_root / icon_path)
|
||||
|
||||
for candidate in candidates:
|
||||
if candidate.exists():
|
||||
return candidate
|
||||
|
||||
logger.warning(f"Toolbar icon not found for configured path: {configured_path}")
|
||||
return None
|
||||
|
||||
def _open_log_file(self) -> None:
|
||||
"""Open the application log file in the system default text editor.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ def test_load_agravity_brand_config():
|
|||
assert brand.display_name == "Agravity Bridge"
|
||||
assert brand.asset_prefix == "AgravityBridge"
|
||||
assert brand.exe_name == "AgravityBridge"
|
||||
assert brand.toolbar_icon_home == "resources/icons/home.ico"
|
||||
assert brand.toolbar_icon_reload == "resources/icons/reload.ico"
|
||||
assert brand.toolbar_icon_open == "resources/icons/open.ico"
|
||||
assert brand.toolbar_icon_openwith == "resources/icons/openwith.ico"
|
||||
assert brand.windows_installer_name("0.8.4") == "AgravityBridge-0.8.4-win-x64.msi"
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue