|
|
@@ -146,81 +146,148 @@ async function libreofficeWinId(): Promise<string> {
|
|
|
return run("xdotool", ["search", "--name", "LibreOffice Impress"]);
|
|
|
}
|
|
|
|
|
|
-// Navigate via UNO PresentationController (slideshow mode)
|
|
|
-// or fall back to xdotool if not in slideshow
|
|
|
+// Navigate via UNO — separate script per action to avoid indentation issues
|
|
|
function pyUnoNav(direction: "next" | "prev" | "start" | "end"): Promise<string> {
|
|
|
- const actions: Record<string, string> = {
|
|
|
+ const scripts: Record<string, string> = {
|
|
|
next: `
|
|
|
- if hasattr(controller, 'gotoNextSlide'):
|
|
|
- controller.gotoNextSlide()
|
|
|
- elif hasattr(controller, 'gotoNextEffect'):
|
|
|
- controller.gotoNextEffect()
|
|
|
- else:
|
|
|
- raise Exception("no next method on controller")
|
|
|
- `,
|
|
|
+import sys, time
|
|
|
+try:
|
|
|
+ import uno
|
|
|
+ localCtx = uno.getComponentContext()
|
|
|
+ resolver = localCtx.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localCtx)
|
|
|
+ ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
|
|
|
+ smgr = ctx.ServiceManager
|
|
|
+ desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
|
|
|
+ comp = desktop.getCurrentComponent()
|
|
|
+ controller = comp.getCurrentController()
|
|
|
+ print(f"[nav] controller: {type(controller).__name__}", file=sys.stderr)
|
|
|
+ if hasattr(controller, 'gotoNextSlide'):
|
|
|
+ controller.gotoNextSlide()
|
|
|
+ elif hasattr(controller, 'gotoNextEffect'):
|
|
|
+ controller.gotoNextEffect()
|
|
|
+ else:
|
|
|
+ print("[nav] no next method, trying DrawController", file=sys.stderr)
|
|
|
+ controller.CurrentPage = comp.DrawPages.getByIndex(min(controller.CurrentPage.PageIndex + 1, comp.DrawPages.Count - 1))
|
|
|
+ time.sleep(0.3)
|
|
|
+ controller = comp.getCurrentController()
|
|
|
+ draw = comp.DrawPages
|
|
|
+ total = draw.Count
|
|
|
+ current = 0
|
|
|
+ if hasattr(controller, 'getCurrentSlideIndex'):
|
|
|
+ current = controller.getCurrentSlideIndex() + 1
|
|
|
+ else:
|
|
|
+ page = controller.getCurrentPage()
|
|
|
+ for i in range(draw.Count):
|
|
|
+ if draw.getByIndex(i) == page:
|
|
|
+ current = i + 1
|
|
|
+ break
|
|
|
+ print(f"[nav] next -> {current}/{total}", file=sys.stderr)
|
|
|
+ print(f"{current}/{total}")
|
|
|
+except Exception as e:
|
|
|
+ import traceback; traceback.print_exc(file=sys.stderr)
|
|
|
+ print("0/0")
|
|
|
+`,
|
|
|
prev: `
|
|
|
- if hasattr(controller, 'gotoPreviousSlide'):
|
|
|
- controller.gotoPreviousSlide()
|
|
|
- elif hasattr(controller, 'gotoPreviousEffect'):
|
|
|
- controller.gotoPreviousEffect()
|
|
|
- else:
|
|
|
- raise Exception("no prev method on controller")
|
|
|
- `,
|
|
|
- start: `
|
|
|
- pres = comp.Presentation
|
|
|
- pres.start()
|
|
|
- import time; time.sleep(1.2)
|
|
|
- # re-fetch controller after slideshow starts
|
|
|
- controller = comp.getCurrentController()
|
|
|
- `,
|
|
|
- end: `
|
|
|
- if hasattr(controller, 'deactivate'):
|
|
|
- controller.deactivate()
|
|
|
- else:
|
|
|
- pres = comp.Presentation
|
|
|
- pres.end()
|
|
|
- `,
|
|
|
- };
|
|
|
-
|
|
|
- return pyUno(`
|
|
|
import sys, time
|
|
|
try:
|
|
|
import uno
|
|
|
- from com.sun.star.beans import PropertyValue
|
|
|
localCtx = uno.getComponentContext()
|
|
|
- resolver = localCtx.ServiceManager.createInstanceWithContext(
|
|
|
- "com.sun.star.bridge.UnoUrlResolver", localCtx)
|
|
|
- ctx = resolver.resolve(
|
|
|
- "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
|
|
|
+ resolver = localCtx.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localCtx)
|
|
|
+ ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
|
|
|
smgr = ctx.ServiceManager
|
|
|
desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
|
|
|
comp = desktop.getCurrentComponent()
|
|
|
controller = comp.getCurrentController()
|
|
|
- print(f"[nav] controller type: {type(controller).__name__}", file=sys.stderr)
|
|
|
- ${actions[direction]}
|
|
|
+ print(f"[nav] controller: {type(controller).__name__}", file=sys.stderr)
|
|
|
+ if hasattr(controller, 'gotoPreviousSlide'):
|
|
|
+ controller.gotoPreviousSlide()
|
|
|
+ elif hasattr(controller, 'gotoPreviousEffect'):
|
|
|
+ controller.gotoPreviousEffect()
|
|
|
+ else:
|
|
|
+ print("[nav] no prev method, trying DrawController", file=sys.stderr)
|
|
|
+ controller.CurrentPage = comp.DrawPages.getByIndex(max(controller.CurrentPage.PageIndex - 1, 0))
|
|
|
time.sleep(0.3)
|
|
|
- # read position after nav
|
|
|
controller = comp.getCurrentController()
|
|
|
draw = comp.DrawPages
|
|
|
total = draw.Count
|
|
|
current = 0
|
|
|
if hasattr(controller, 'getCurrentSlideIndex'):
|
|
|
current = controller.getCurrentSlideIndex() + 1
|
|
|
- print(f"[nav] slideshow mode after ${direction}, index={current}", file=sys.stderr)
|
|
|
- elif hasattr(controller, 'getCurrentPage'):
|
|
|
+ else:
|
|
|
page = controller.getCurrentPage()
|
|
|
for i in range(draw.Count):
|
|
|
if draw.getByIndex(i) == page:
|
|
|
current = i + 1
|
|
|
break
|
|
|
- print(f"[nav] editor mode after ${direction}, index={current}", file=sys.stderr)
|
|
|
+ print(f"[nav] prev -> {current}/{total}", file=sys.stderr)
|
|
|
print(f"{current}/{total}")
|
|
|
except Exception as e:
|
|
|
- import traceback
|
|
|
- print(f"[nav] error: {e}", file=sys.stderr)
|
|
|
- traceback.print_exc(file=sys.stderr)
|
|
|
+ import traceback; traceback.print_exc(file=sys.stderr)
|
|
|
print("0/0")
|
|
|
-`);
|
|
|
+`,
|
|
|
+ start: `
|
|
|
+import sys, time
|
|
|
+try:
|
|
|
+ import uno
|
|
|
+ localCtx = uno.getComponentContext()
|
|
|
+ resolver = localCtx.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localCtx)
|
|
|
+ ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
|
|
|
+ smgr = ctx.ServiceManager
|
|
|
+ desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
|
|
|
+ comp = desktop.getCurrentComponent()
|
|
|
+ pres = comp.Presentation
|
|
|
+ print(f"[nav] starting presentation", file=sys.stderr)
|
|
|
+ pres.start()
|
|
|
+ time.sleep(1.5)
|
|
|
+ controller = comp.getCurrentController()
|
|
|
+ print(f"[nav] controller after start: {type(controller).__name__}", file=sys.stderr)
|
|
|
+ draw = comp.DrawPages
|
|
|
+ total = draw.Count
|
|
|
+ current = 0
|
|
|
+ if hasattr(controller, 'getCurrentSlideIndex'):
|
|
|
+ current = controller.getCurrentSlideIndex() + 1
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ page = controller.getCurrentPage()
|
|
|
+ for i in range(draw.Count):
|
|
|
+ if draw.getByIndex(i) == page:
|
|
|
+ current = i + 1
|
|
|
+ break
|
|
|
+ except:
|
|
|
+ current = 1
|
|
|
+ print(f"[nav] start -> {current}/{total}", file=sys.stderr)
|
|
|
+ print(f"{current}/{total}")
|
|
|
+except Exception as e:
|
|
|
+ import traceback; traceback.print_exc(file=sys.stderr)
|
|
|
+ print("0/0")
|
|
|
+`,
|
|
|
+ end: `
|
|
|
+import sys, time
|
|
|
+try:
|
|
|
+ import uno
|
|
|
+ localCtx = uno.getComponentContext()
|
|
|
+ resolver = localCtx.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localCtx)
|
|
|
+ ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
|
|
|
+ smgr = ctx.ServiceManager
|
|
|
+ desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
|
|
|
+ comp = desktop.getCurrentComponent()
|
|
|
+ controller = comp.getCurrentController()
|
|
|
+ print(f"[nav] ending presentation, controller: {type(controller).__name__}", file=sys.stderr)
|
|
|
+ if hasattr(controller, 'deactivate'):
|
|
|
+ controller.deactivate()
|
|
|
+ else:
|
|
|
+ comp.Presentation.end()
|
|
|
+ time.sleep(0.3)
|
|
|
+ total = comp.DrawPages.Count
|
|
|
+ print(f"[nav] end -> 0/{total}", file=sys.stderr)
|
|
|
+ print(f"0/{total}")
|
|
|
+except Exception as e:
|
|
|
+ import traceback; traceback.print_exc(file=sys.stderr)
|
|
|
+ print("0/0")
|
|
|
+`,
|
|
|
+ };
|
|
|
+
|
|
|
+ return pyUno(scripts[direction]);
|
|
|
}
|
|
|
|
|
|
const LinuxDriver: Driver = {
|