Here is a python macro that calls a Basic routine every 10th of a second. For illustration, it stops itself after 20 seconds.
import threading
def do_call():
desktop = XSCRIPTCONTEXT.getDesktop()
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.ServiceManager
oMasterScriptProviderFactory = smgr.createInstanceWithContext(
"com.sun.star.script.provider.MasterScriptProviderFactory", ctx)
oScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
oScript = oScriptProvider.getScript(
"vnd.sun.star.script:Standard.Calc1.IncrementValue?"
"language=Basic&location=application")
oScript.invoke((), (), ())
class BasicScriptCaller:
def __init__(self):
self.timer = None
def call_basic_script(self):
do_call()
self.timer = threading.Timer(0.1, self.call_basic_script)
self.timer.start()
def stop_basic_script(self):
if self.timer is not None:
self.timer.cancel()
def start(self):
self.call_basic_script()
threading.Timer(20, self.stop_basic_script).start()
def start():
caller = BasicScriptCaller()
caller.start()
g_exportedScripts = (start,)
This routine increments cell A1, making something that looks like a timer.
Sub IncrementValue
oSheet = ThisComponent.getSheets().getByIndex(0)
oCell = oSheet.getCellByPosition(0, 0)
iOldVal = oCell.getValue()
oCell.setValue(iOldVal + 1)
End Sub
To turn off, the thread could stop itself if a cell, say B1, has a non-zero value. Then you could make a button or checkbox to automatically set B1 to 1 instead of 0. Also, stop if the document is no longer open.
Update
Here are the code changes you requested in the comment. It runs until cell B1 has a value. Also, it allows start() to optionally accept the button event parameter.
class BasicScriptCaller:
def __init__(self):
self.timer = None
def stop_condition(self):
"""Return true if the condition to stop is met."""
oSheet = XSCRIPTCONTEXT.getDocument().getSheets().getByIndex(0)
oCell = oSheet.getCellByPosition(1, 0) # B1
return bool(oCell.getString()) and oCell.getString().strip()
def next_call(self):
do_call()
if not self.stop_condition():
self.timer = threading.Timer(0.1, self.next_call)
self.timer.start()
def start(button_evt=None):
caller = BasicScriptCaller()
caller.next_call()
g_exportedScripts = (start,)