/** * ToolBarManager — builds a ToolBox from uiconfig toolbar XML and binds its * items to UNO commands (framework/source/uielement/toolbarmanager.cxx). * Commands with a registered controller (font boxes, colour pickers — see * Controller.xcu upstream) render that controller instead of a button. */ import type { ComponentType } from "react"; import { commandLabel } from "../../../officecfg/registry/data/org/openoffice/Office/UI/GenericCommands"; import { shortcutFor } from "../../../officecfg/registry/data/org/openoffice/Office/Accelerators"; import { useDispatcher } from "../../../sfx2/source/control/dispatch"; import { CommandImage, hasCommandImage } from "../../../vcl/source/image/ImplImageTree"; import { ToolBox, ToolBoxButton, ToolBoxSeparator } from "../../../vcl/source/window/toolbox"; export type ToolBarConfigEntry = { kind: "separator" } | { kind: "item"; command: string }; export function parseToolBarXml(xml: string): ToolBarConfigEntry[] { const doc = new DOMParser().parseFromString(xml, "application/xml"); return Array.from(doc.documentElement.children).flatMap((el): ToolBarConfigEntry[] => { if (el.localName === "toolbarseparator") return [{ kind: "separator" }]; if (el.localName === "toolbaritem") { const command = el.getAttributeNS("http://www.w3.org/1999/xlink", "href") ?? el.getAttribute("xlink:href"); return command ? [{ kind: "item", command }] : []; } return []; }); } export interface ToolBoxControllerProps { command: string; } /** Toolbar controller factory (framework/source/uifactories/toolbarcontrollerfactory.cxx). */ const controllers = new Map>(); export function registerToolBoxController( command: string, controller: ComponentType, ): void { controllers.set(command, controller); } export function tooltipFor(command: string): string { const shortcut = shortcutFor(command); return shortcut ? `${commandLabel(command, true)} (${shortcut})` : commandLabel(command, true); } /** A plain command button (the generic ToolBox item). */ export function CommandButton({ command }: ToolBoxControllerProps) { const dispatcher = useDispatcher(); const state = dispatcher.queryState(command); return ( } text={hasCommandImage(command) ? undefined : commandLabel(command)} tooltip={tooltipFor(command)} checked={state.checked} disabled={!state.enabled} onClick={() => dispatcher.execute(command)} /> ); } export function ToolBarItems({ entries }: { entries: ToolBarConfigEntry[] }) { return ( <> {entries.map((e, i) => { if (e.kind === "separator") return ; const Controller = controllers.get(e.command) ?? CommandButton; return ; })} ); } export function ToolBarManager({ config, label }: { config: ToolBarConfigEntry[]; label: string }) { return ( ); }