This is an automated email from the ASF dual-hosted git repository.

leginee pushed a commit to branch bazel-migration
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 9d89ef9c87eb9ec72415791be87ed43ccece60f3
Author: Peter Kovacs <[email protected]>
AuthorDate: Wed Jun 17 05:48:30 2026 +0200

    fixed decoration nameing and icon.
---
 MODULE.bazel                         | 12 ++++++
 MODULE.bazel.lock                    | 17 ++++++++
 build/product.bzl                    | 77 ++++++++++++++++++++++++++++++++++++
 main/desktop/BUILD.bazel             | 38 ++++++++++++++++++
 main/desktop/util/fix_icon_rc.pl     | 58 +++++++++++++++++++++++++++
 main/postprocess/BUILD.bazel         | 41 ++++++++++++++++++-
 main/sysui/desktop/icons/BUILD.bazel |  9 +++++
 7 files changed, 251 insertions(+), 1 deletion(-)

diff --git a/MODULE.bazel b/MODULE.bazel
index 6fc581620f..b629940e74 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -4,6 +4,18 @@ module(
     version = "4.5.0",
 )
 
+# --------------- product branding (single source of truth) ---------------
+# The product VERSION is module(version=...) above.  The human-readable product
+# NAME and FULL NAME live here (a module() name can't hold spaces/caps).  These
+# feed the window title, About box and %PRODUCTNAME tokens via @product_info →
+# //main/postprocess brand Setup.xcu substitution.
+product = use_extension("//build:product.bzl", "product")
+product.info(
+    name = "Apache OpenOffice",
+    full_name = "Apache OpenOffice",
+)
+use_repo(product, "product_info")
+
 # --------------- bazel dependencies ---------------
 bazel_dep(name = "platforms",        version = "1.0.0")
 bazel_dep(name = "rules_cc",         version = "0.2.17")
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index f2547c9948..68b4d0de2c 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -195,6 +195,23 @@
   },
   "selectedYankedVersions": {},
   "moduleExtensions": {
+    "//build:product.bzl%product": {
+      "general": {
+        "bzlTransitiveDigest": "8ojzhp1NoC+WNzpqqBck3bVfIdWcrL4ZoXWRSz56Vxk=",
+        "usagesDigest": "mOSBQDxn/VOkkcBKT0VS43WJKNUbheKjaifCtm+HPes=",
+        "recordedInputs": [],
+        "generatedRepoSpecs": {
+          "product_info": {
+            "repoRuleId": "@@//build:product.bzl%_product_info_repo",
+            "attributes": {
+              "product_name": "Apache OpenOffice",
+              "product_fullname": "Apache OpenOffice",
+              "product_version": "4.5.0"
+            }
+          }
+        }
+      }
+    },
     "@@pybind11_bazel+//:internal_configure.bzl%internal_configure_extension": 
{
       "general": {
         "bzlTransitiveDigest": "06cynZ1bCvvy8zHPrrDlXq+Z68xmjctHpfFxi+zEpJY=",
diff --git a/build/product.bzl b/build/product.bzl
new file mode 100644
index 0000000000..6a0915ef76
--- /dev/null
+++ b/build/product.bzl
@@ -0,0 +1,77 @@
+"""Product branding propagated from MODULE.bazel.
+
+MODULE.bazel is the single source of truth for the product identity:
+
+  * version  → the root module's `module(version = "...")`
+  * name / full name → a `product.info(...)` tag (a bzlmod module() name is
+    restricted to lowercase letters/digits/`._-` with no spaces, so the
+    human-readable product name cannot be the module name itself)
+
+A generated `@product_info` repo exposes these to BUILD files:
+
+    load("@product_info//:defs.bzl",
+         "PRODUCT_NAME", "PRODUCT_FULLNAME", "PRODUCT_VERSION")
+
+Consumers: //main/postprocess (brand Setup.xcu placeholder substitution →
+ooName/ooSetupVersion → window title, About box, %PRODUCTNAME runtime tokens).
+"""
+
+def _product_info_repo_impl(rctx):
+    rctx.file("BUILD.bazel", "exports_files([\"defs.bzl\"])\n")
+    rctx.file("defs.bzl", "\n".join([
+        "# Generated from MODULE.bazel by //build:product.bzl — do not edit.",
+        "PRODUCT_NAME = \"{}\"".format(rctx.attr.product_name),
+        "PRODUCT_FULLNAME = \"{}\"".format(rctx.attr.product_fullname),
+        "PRODUCT_VERSION = \"{}\"".format(rctx.attr.product_version),
+        "",
+    ]))
+
+_product_info_repo = repository_rule(
+    implementation = _product_info_repo_impl,
+    attrs = {
+        "product_name": attr.string(mandatory = True),
+        "product_fullname": attr.string(mandatory = True),
+        "product_version": attr.string(mandatory = True),
+    },
+)
+
+def _product_impl(module_ctx):
+    name = ""
+    full_name = ""
+    version = ""
+    for mod in module_ctx.modules:
+        if mod.is_root:
+            version = mod.version
+            for info in mod.tags.info:
+                name = info.name
+                full_name = info.full_name
+
+    if not name:
+        fail("MODULE.bazel must declare product.info(name = ..., full_name = 
...) " +
+             "for the //build:product.bzl 'product' extension.")
+    if not version:
+        fail("The root module() must declare a version = \"...\" — it is the " 
+
+             "product version source for //build:product.bzl.")
+
+    _product_info_repo(
+        name = "product_info",
+        product_name = name,
+        product_fullname = full_name,
+        product_version = version,
+    )
+
+_info = tag_class(attrs = {
+    "name": attr.string(
+        mandatory = True,
+        doc = "Human-readable product name (window title / %PRODUCTNAME), e.g. 
'Apache OpenOffice'.",
+    ),
+    "full_name": attr.string(
+        mandatory = True,
+        doc = "Full product name shown in the About box (ooFullname), e.g. 
'Apache OpenOffice'.",
+    ),
+})
+
+product = module_extension(
+    implementation = _product_impl,
+    tag_classes = {"info": _info},
+)
diff --git a/main/desktop/BUILD.bazel b/main/desktop/BUILD.bazel
index 25b2bd89c9..0eba26c475 100644
--- a/main/desktop/BUILD.bazel
+++ b/main/desktop/BUILD.bazel
@@ -713,6 +713,42 @@ filegroup(
 )
 
 # ── soffice.exe 
───────────────────────────────────────────────────────────────
+# ── soffice.exe Windows icon resource ────────────────────────────────────────
+# soffice.exe (built from main.c) carried no resources, so the window/taskbar
+# showed the generic Windows icon and framework's per-module SetIcon() loaded
+# nothing (VCL ImplLoadSalIcon tries the app exe first).  This embeds id 1 (the
+# app/default icon) + the OOo document-window icons (ids 2..39 — Writer=2,
+# Calc=4, Draw=6, Impress=8, Math=15, ...), and links the .res into :soffice.
+# This is dmake's APP5 resource (solenv/inc/_tg_app.mk: "1 ICON <APP5ICON>" +
+# #include ooverinfo2.rc).
+#
+# fix_icon_rc.pl regenerates ooverinfo2.rc's entries with MS rc's required
+# "<id> ICON" token order (the upstream "ICON <id>" form makes the strict v7.0
+# rc.exe treat the .ico as RT_BITMAP -> RC2170) and skips its stale references 
to
+# renamed app icons (now ooo3_*_app.ico) that no longer exist.  Original icons,
+# no frame stripping — compiles on the configured v7.0 SDK.  Icon 
"icons/<f>.ico"
+# paths resolve via rc /I main/sysui/desktop.  RC path mirrors crashrep.
+genrule(
+    name = "soffice_icon_res",
+    srcs = [
+        "util/ooverinfo2.rc",
+        "util/fix_icon_rc.pl",
+        "//main/sysui/desktop/icons:app_icons",
+    ],
+    outs = ["soffice_icon.res"],
+    cmd_bat = (
+        "perl \"$(execpath util/fix_icon_rc.pl)\"" +
+        " main/sysui/desktop/icons" +
+        " \"$(execpath util/ooverinfo2.rc)\"" +
+        " soffice_icons.rc&&" +
+        "set \"_RC=C:\\Program Files\\Microsoft 
SDKs\\Windows\\v7.0\\Bin\\RC.Exe\"&&" +
+        "\"!_RC!\" /nologo /DWIN32" +
+        " /I \"main/sysui/desktop\"" +
+        " /fo \"$(OUTS)\"" +
+        " soffice_icons.rc"
+    ),
+)
+
 # Main office executable: calls soffice_main() from sofficeapp.dll
 cc_binary(
     name = "soffice",
@@ -734,10 +770,12 @@ cc_binary(
     additional_linker_inputs = [
         "//main/sal:sal_implib",
         ":sofficeapp_implib",
+        ":soffice_icon_res",
     ],
     linkopts = [
         "$(execpath //main/sal:sal_implib)",
         "$(execpath :sofficeapp_implib)",
+        "$(execpath :soffice_icon_res)",
         "/SUBSYSTEM:WINDOWS",
         "/MANIFEST:NO",
     ],
diff --git a/main/desktop/util/fix_icon_rc.pl b/main/desktop/util/fix_icon_rc.pl
new file mode 100644
index 0000000000..004de8a263
--- /dev/null
+++ b/main/desktop/util/fix_icon_rc.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+#**************************************************************
+#
+# fix_icon_rc.pl <icondir> <ooverinfo2.rc> <out.rc>
+#
+# Emits a Windows .rc that binds the soffice.exe window-icon ids to the OOo
+# icon set, compilable by the project's configured Windows SDK v7.0 rc.exe.
+#
+# Two reasons the upstream ooverinfo2.rc can't be fed to rc.exe directly:
+#
+#  1. Token order.  ooverinfo2.rc uses "ICON <id> \"file\"" (keyword first).
+#     MS rc.exe requires "<id> ICON \"file\"" (single-line resource syntax is
+#     nameID typeID file).  "ICON 2 \"x.ico\"" is parsed as name=ICON,
+#     type=2 (RT_BITMAP) and rc tries to load the .ico as a bitmap ->
+#     "RC2170 ... not in 3.00 format".  dmake's PATH rc tolerated the reversed
+#     order; the strict v7.0 rc does not.  We swap the tokens.
+#
+#  2. Stale entries.  ooverinfo2.rc still references per-module *application*
+#     icons under their old dash names (ooo-writer-app.ico, ...) that were
+#     renamed to ooo3_*_app.ico and are no longer delivered (sysui d.lst ships
+#     misc/*.ico verbatim).  rc would fail "RC2135 file not found".  Those are
+#     NOT window-title icons (framework's titlebarupdate uses the *document*
+#     icon ids 2..15, which all exist), so entries whose file is absent are
+#     skipped.
+#
+# Mirrors dmake's APP5 resource (solenv/inc/_tg_app.mk: "1 ICON <APP5ICON>" +
+# #include ooverinfo2.rc), corrected for the strict v7.0 rc.  Icon paths stay
+# "icons/<f>.ico" and resolve via rc /I <icondir-parent>.
+#
+#**************************************************************
+use strict;
+use warnings;
+
+my ($icondir, $rc, $out) = @ARGV;
+die "usage: $0 <icondir> <ooverinfo2.rc> <out.rc>\n" unless defined $out;
+
+open(my $in,  '<', $rc)  or die "open $rc: $!";
+open(my $ofh, '>', $out) or die "write $out: $!";
+
+# id 1 = SAL_RESID_ICON_DEFAULT: window-class default / taskbar / .exe icon
+# and Start Center (framework DEFAULT_ICON_ID fallback).
+print $ofh "1 ICON \"icons/ooo3_main_app.ico\"\n"
+    if -e "$icondir/ooo3_main_app.ico";
+
+# ids 2..39 = per-module document-window icons (Writer=2, Calc=4, Draw=6,
+# Impress=8, Math=15, ...), token-order-corrected, skipping absent files.
+while (my $line = <$in>) {
+    next unless $line =~ /^\s*ICON\s+(\d+)\s+"([^"]+)"/;
+    my ($id, $file) = ($1, $2);
+    (my $base = $file) =~ s#.*/##;
+    if (-e "$icondir/$base") {
+        print $ofh "$id ICON \"$file\"\n";
+    } else {
+        print $ofh "// missing icon, skipped: $file\n";
+    }
+}
+close $ofh;
+close $in;
diff --git a/main/postprocess/BUILD.bazel b/main/postprocess/BUILD.bazel
index 86d8629cc1..2355f7c8b9 100644
--- a/main/postprocess/BUILD.bazel
+++ b/main/postprocess/BUILD.bazel
@@ -20,6 +20,7 @@
 load(":postprocess.bzl", "services_rdb", "uiconfig_zip", "uiconfig_tree", 
"pack_registry",
      "oc_xcs", "oc_xcu", "oc_mod", "fcfg",
      "basis_native", "basis_java", "ure_java", "pymodule")
+load("@product_info//:defs.bzl", "PRODUCT_NAME", "PRODUCT_FULLNAME", 
"PRODUCT_VERSION")
 
 # ── Component files — Windows build ──────────────────────────────────────────
 # Mirrors packcomponents/makefile.mk my_components for OS=WNT.
@@ -971,7 +972,9 @@ _MAIN_XCU = [
     oc_mod("Office/Common.xcu",          "wnt"),
     oc_mod("Office/Embedding.xcu",       "chart"),
     oc_mod("Office/UI.xcu",              "brand"),
-    oc_mod("Setup.xcu",                  "brand"),
+    # Setup.xcu brand props carry ${PRODUCTNAME}/${PRODUCTVERSION}/... 
installer
+    # placeholders; :brand_setup_xcu substitutes them from MODULE.bazel before 
pack.
+    ":brand_setup_xcu",
     oc_mod("Setup.xcu",                  "start"),
     oc_mod("Inet.xcu",                   "wnt"),
     oc_mod("Office/Accelerators.xcu",    "unxwnt"),
@@ -1005,6 +1008,42 @@ genrule(
     ),
 )
 
+# ── Brand Setup.xcu — product-name/version substitution ──────────────────────
+# The brand spool of Setup.xcu carries installer placeholders in ooName /
+# ooFullname / ooSetupVersion / ooSetupVersionAboutBox / ooSetupExtension / 
... .
+# The MSI installer normally substitutes them (from instsetoo openoffice.lst);
+# our staging never runs the MSI, so configmgr reads the literal 
"${PRODUCTNAME}"
+# into Product/ooName → the window title shows "${PRODUCTNAME} 
${PRODUCTEXTENSION}"
+# and every runtime %PRODUCTNAME token (menus, About box) resolves to it.
+# Substitute here, sourcing name/full-name/version from MODULE.bazel via
+# @product_info.  Same .Replace genrule pattern as forcedefault_linguistic_xcu.
+# Note: $$ escapes the genrule '$' so the shell sees a literal "${...}".
+_BRAND_SUBST = [
+    ("$${FULLPRODUCTNAME}", PRODUCT_FULLNAME),
+    ("$${ABOUTBOXPRODUCTVERSION}", PRODUCT_VERSION),
+    ("$${PRODUCTNAME}", PRODUCT_NAME),
+    ("$${PRODUCTVERSION}", PRODUCT_VERSION),
+    ("$${PRODUCTEXTENSION}", ""),
+    ("$${OOOVENDOR}", "Apache Software Foundation"),
+    ("$${OOOXMLFILEFORMATNAME}", "OpenOffice.org XML"),
+    ("$${OOOXMLFILEFORMATVERSION}", "1.0"),
+    ("$${OPENSOURCE}", "1"),
+]
+
+genrule(
+    name = "brand_setup_xcu",
+    srcs = [oc_mod("Setup.xcu", "brand")],
+    outs = ["BrandSetup/Setup.xcu"],
+    cmd_bat = (
+        "powershell -NoProfile -Command " +
+        "\"(Get-Content -Raw '$(location " +
+        oc_mod("Setup.xcu", "brand") +
+        ")')" +
+        "".join([".Replace('{}','{}')".format(k, v) for k, v in _BRAND_SUBST]) 
+
+        " | Set-Content -Encoding UTF8 '$(OUTS)'\""
+    ),
+)
+
 pack_registry(
     name = "main_xcd",
     out  = "main.xcd",
diff --git a/main/sysui/desktop/icons/BUILD.bazel 
b/main/sysui/desktop/icons/BUILD.bazel
new file mode 100644
index 0000000000..7a964d8270
--- /dev/null
+++ b/main/sysui/desktop/icons/BUILD.bazel
@@ -0,0 +1,9 @@
+# Application / document-type icons (.ico) consumed by the Windows resource
+# compiled into soffice.exe (//main/desktop:soffice_icon_res via 
ooverinfo2.rc).
+# sysui itself is not yet migrated; this only exports the existing icon assets.
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+    name = "app_icons",
+    srcs = glob(["*.ico"]),
+)

Reply via email to