| View previous topic :: View next topic |
| Author |
Message |
ms777 Super User


Joined: 07 Feb 2004 Posts: 1355
|
Posted: Mon Jul 16, 2007 10:35 am Post subject: Timer in OOBasic |
|
|
Hi,
OOBasic lacks a timer functionality. This post shows, how to implement a timer functionality in OOBasic using BeanShell.
It is rather straightforward and should be self explaining. To install
- put the BeanShell code into a calc document, into the library 'timer', under the name 'timer'(.bsh)
- put the Basic code into any module in the same document.
- run the Basic code
Have fun,
ms777
Edit May 2009: Please note that the below script stopped working since OO 2.3 or OO 2.4 due to a regression in the class loader handling ( http://qa.openoffice.org/issues/show_bug.cgi?id=89978 ). Please use the new script given in one of the next posts for OO 2.4, maybe also for OO 2.3
The Basic Code: | Code: | Sub Main
oP = GenerateTimerPropertySet()
oJob1 = createUnoListener("JOB1_", "com.sun.star.task.XJobExecutor")
oP.xJob = oJob1
oP.lMaxIterations = 5
oP.lPeriodInMilliSec = 4000
oP.start()
oP2 = GenerateTimerPropertySet()
oJob2 = createUnoListener("JOB2_", "com.sun.star.task.XJobExecutor")
oP2.xJob = oJob2
oP2.lMaxIterations = 10
oP2.lPeriodInMilliSec = 2000
oP2.start()
End Sub
function GenerateTimerPropertySet() as Any
oSP = ThisComponent.getScriptProvider("")
oScript = oSP.getScript("vnd.sun.star.script:timer.timer.bsh?language=BeanShell&location=document")
GenerateTimerPropertySet = oScript.invoke(Array(), Array(), Array()
end function
sub JOB1_trigger(s as String)
oCell = ThisComponent.sheets.getByIndex(0).getCellByPosition(0,0)
oCell.Value = oCell.Value + 1
end sub
sub JOB2_trigger(s as String)
oCell = ThisComponent.sheets.getByIndex(0).getCellByPosition(1,0)
oCell.Value = oCell.Value + 1
end sub |
The beanshell code: | Code: | import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.lib.uno.helper.PropertySet;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.task.XJobExecutor;
import com.sun.star.lang.XInitialization;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertyChangeListener;
import com.sun.star.beans.PropertyChangeEvent;
import com.sun.star.lang.EventObject;
import com.sun.star.uno.AnyConverter;
import com.sun.star.xml.crypto.sax.XElementStackKeeper ; // defines a start and a stop routine
// This prevents an error message when executing the script a second time
xClassLoader = java.lang.ClassLoader.getSystemClassLoader();
try {
xClassLoader.loadClass("ms777Timer_01");
} catch (ClassNotFoundException e)
{
System.out.println( "class not found - compiling" );
public class ms777Timer_01 extends PropertySet implements XElementStackKeeper
{
// These are the properties of the PropertySet
public boolean bFixedRate = true;
public boolean bIsRunning = false;
public int lPeriodInMilliSec = 2000;
public int lDelayInMilliSec = 0;
public int lMaxIterations = 5;
public int lCurrentIteration = 0;
public XJobExecutor xJob = null;
// These are some additional properties
Task xTask =null;
Timer xTimer = null;
public ms777Timer_01() {
registerProperty("bFixedRate", (short) 0);
registerProperty("bIsRunning", (short) com.sun.star.beans.PropertyAttribute.READONLY);
registerProperty("lPeriodInMilliSec", (short) 0);
registerProperty("lDelayInMilliSec", (short) 0);
registerProperty("lMaxIterations", (short) 0);
registerProperty("lCurrentIteration", (short) 0);
registerProperty("xJob", (short) com.sun.star.beans.PropertyAttribute.MAYBEVOID);
xTimer = new Timer();
}
//XElementStackKeeper
public void start() {
stop();
if (xJob==null) {return;}
xTask = new Task();
lCurrentIteration = 1;
bIsRunning = true;
if (bFixedRate) {
xTimer.scheduleAtFixedRate( xTask, (long) lDelayInMilliSec, (long) lPeriodInMilliSec );
} else {
xTimer.schedule( xTask, (long) lDelayInMilliSec, (long) lPeriodInMilliSec );
}
}
public void stop() {
lCurrentIteration = 0;
bIsRunning = false;
if (xTask!=null) { xTask.cancel();}
}
public void retrieve(com.sun.star.xml.sax.XDocumentHandler h, boolean b) { }
class Task extends TimerTask {
public void run() {
xJob.trigger(lCurrentIteration.toString());
lCurrentIteration +=1;
if (lCurrentIteration > lMaxIterations) {
stop();
}
}
}
}
System.out.println( "ms777PropertySet generated" );
} // of if (xClass = null)
Object TA = new ms777Timer_01();
return TA; |
Last edited by ms777 on Sun May 03, 2009 5:01 am; edited 1 time in total |
|
| Back to top |
|
 |
crun General User

Joined: 13 Jul 2007 Posts: 5
|
Posted: Sat Aug 25, 2007 3:10 pm Post subject: |
|
|
I have gotten time to try this now.
Thanks for the timer code, it runs as advertised.
From within JobXX_ callback function I can call an OOBasic routine in the same module eg "IncCell"
However I cannot call any method of RT, the Realterm active X server (this has been opened already, and can be used happily from button clicks)
It appears that RT.PutString never completes, ie if any instruction follows it in the JOB3 function, then OO locks up and must be terminated.
| Code: |
Global RT As Object 'public doesn't seem to be persistent in openoffice
Public Sub Realterm_Open
Set RT = CreateObject("Realterm.RealtermIntf")
RT.HalfDuplex = True 'so you can see what we send out through the port...
RT.Caption = "Realterm Controlled from OpenOffice Calc"
RT.portopen = True 'port is always closed when starting by automation
RT.SelectTabSheet ("I2C")
End Sub
Sub StartTempUpdateTimer
oP3 = GenerateTimerPropertySet()
oJob3 = createUnoListener("JOB3_", "com.sun.star.task.XJobExecutor")
oP3.xJob = oJob3
oP3.lMaxIterations = 1
oP3.lPeriodInMilliSec = 2000
oP3.start()
End Sub
sub JOB3_trigger(s as String)
IncCell 'works OK
RT.PutString ("?") 'does not work
End Sub
sub IncCell
oCell = ThisComponent.sheets.getByIndex(0).getCellByPosition(2,38)
oCell.Value = oCell.Value + 1
End Sub
| [/list] |
|
| Back to top |
|
 |
ms777 Super User


Joined: 07 Feb 2004 Posts: 1355
|
Posted: Tue Aug 28, 2007 1:13 pm Post subject: |
|
|
Hi,
I have done a little testing. As I do not have the Realterm ActiveX installed, I tried the MSScriptControl ActiveX: | Code: | Global VBScript as Object
Sub Main
oleService = createUnoService("com.sun.star.bridge.OleObjectFactory")
VBScript= oleService.createInstance("MSScriptControl.ScriptControl")
VBScript.Language = "VBScript"
oP = GenerateTimerPropertySet()
oJob1 = createUnoListener("JOB1_", "com.sun.star.task.XJobExecutor")
oP.xJob = oJob1
oP.lMaxIterations = 10
oP.lPeriodInMilliSec = 1000
oP.start()
End Sub
function GenerateTimerPropertySet() as Any
oSP = ThisComponent.getScriptProvider("")
oScript = oSP.getScript("vnd.sun.star.script:timer.timer.bsh?language=BeanShell&location=document")
GenerateTimerPropertySet = oScript.invoke(Array(), Array(), Array()
end function
sub JOB1_trigger(s as String)
x = GetShellWindows()
oSheet = ThisComponent.sheets.getByIndex(0)
for k=0 to 20
oSheet.getCellByPosition(0,k).String = ""
next k
for k=LBound(x) to UBound(x)
if x(k).Name = "Microsoft Internet Explorer" then
oSheet.getCellByPosition(0,k).String = x(k).LocationUrl
endif
next k
end sub
function GetShellWindows() as Object
Dim oleService
Dim VBScript
Dim s as string
Dim ad
'comment these lines out, and the Basic IDE will pop up for each timer event
oleService = createUnoService("com.sun.star.bridge.OleObjectFactory")
VBScript= oleService.createInstance("MSScriptControl.ScriptControl")
VBScript.Language = "VBScript"
s = ""
s = s + "Public oIE()" + Chr(10)
s = s + "set oShell = CreateObject(""Shell.Application"")" + Chr(10)
s = s + "set oShellWindows = oShell.Windows" + Chr(10)
s = s + "if (not oShellWindows is nothing) then" + Chr(10)
s = s + " ReDim oIE(oShellWindows.count-1)" + Chr(10)
s = s + " k = 0" + Chr(10)
s = s + " for each o in oShellWindows" + Chr(10)
s = s + " set oIE(k) = o" + Chr(10)
s = s + " k = k + 1" + Chr(10)
s = s + " next" + Chr(10)
s = s + " end if" + Chr(10)
VBScript.ExecuteStatement(s)
ad = VBScript.CodeObject.oIE
GetShellWindows = ad
End function |
This code runs as it should: It lists all open InternetExplorers with their LocationUrls in sheet 0.
The funny thing is: When you comment out the marked three lines in sub GetShellWindows, which are actually not necessary due to the global variable VBScript and the redundant initialization in the main sub, the Basic IDE pops up for each iteration. Seems a bit buggy ...
Maybe you want to try to shift your sub Realterm_open into the JOB3_trigger sub, if this is compatible with the 2000 msec repetition time ...
Good luck,
ms777 |
|
| Back to top |
|
 |
ms777 Super User


Joined: 07 Feb 2004 Posts: 1355
|
Posted: Sun May 03, 2009 5:02 am Post subject: |
|
|
Here the BeanShell script which should be used from OO 2.4 onwards:
| Code: | import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.lib.uno.helper.PropertySet;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.task.XJobExecutor;
import com.sun.star.lang.XInitialization;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertyChangeListener;
import com.sun.star.beans.PropertyChangeEvent;
import com.sun.star.lang.EventObject;
import com.sun.star.uno.AnyConverter;
import com.sun.star.xml.crypto.sax.XElementStackKeeper ; // defines a start and a stop routine
// Workaround for http://qa.openoffice.org/issues/show_bug.cgi?id=89978 needed from OO 2.4 onwards
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
// This prevents an error message when executing the script a second time
try { Class.forName("ms777Timer_06");}
catch (ClassNotFoundException e) {
System.out.println( "class not found - compiling start" );
public class ms777Timer_06 extends PropertySet implements XElementStackKeeper
{
// These are the properties of the PropertySet
public boolean bFixedRate = true;
public boolean bIsRunning = false;
public int lPeriodInMilliSec = 2000;
public int lDelayInMilliSec = 0;
public int lMaxIterations = 5;
public int lCurrentIteration = 0;
public XJobExecutor xJob = null;
// These are some additional properties
Task xTask =null;
Timer xTimer = null;
public ms777Timer_06() {
registerProperty("bFixedRate", (short) 0);
registerProperty("bIsRunning", (short) com.sun.star.beans.PropertyAttribute.READONLY);
registerProperty("lPeriodInMilliSec", (short) 0);
registerProperty("lDelayInMilliSec", (short) 0);
registerProperty("lMaxIterations", (short) 0);
registerProperty("lCurrentIteration", (short) 0);
registerProperty("xJob", (short) com.sun.star.beans.PropertyAttribute.MAYBEVOID);
xTimer = new Timer();
}
//XElementStackKeeper
public void start() {
stop();
if (xJob==null) {return;}
xTask = new Task();
lCurrentIteration = 1;
bIsRunning = true;
if (bFixedRate) {
xTimer.scheduleAtFixedRate( xTask, (long) lDelayInMilliSec, (long) lPeriodInMilliSec );
} else {
xTimer.schedule( xTask, (long) lDelayInMilliSec, (long) lPeriodInMilliSec );
}
}
public void stop() {
lCurrentIteration = 0;
bIsRunning = false;
if (xTask!=null) { xTask.cancel();}
}
public void retrieve(com.sun.star.xml.sax.XDocumentHandler h, boolean b) { }
class Task extends TimerTask {
public void run() {
xJob.trigger(lCurrentIteration.toString());
lCurrentIteration +=1;
if (lCurrentIteration > lMaxIterations) {
stop();
}
}
}
}
System.out.println( "class not found - compiling end" );
} // of catch (ClassNotFoundException e)
System.out.println( "generating timer property set ... " );
return new ms777Timer_06(); |
|
|
| Back to top |
|
 |
ellebi General User

Joined: 11 Oct 2009 Posts: 13
|
Posted: Sun Oct 11, 2009 2:32 am Post subject: Beanshell error for timer.bsh |
|
|
Hi all
I try to make work this timer in my ooo calc sheet, with ooo basic macros, where i want to put the time (i.e. hours, minutes, seconds) in a TimeField of dialog, and I cannot fix the error that ooo gives me. The error exactly is
"Errore di runtime basic. Si รจ verificata un'eccezione
Type: com.sun.star.reflection.InvocationTargetException
Message: Beanshell error for timer.bsh
TargetException:
Type:
com.sun.star.script.provider.ScriptErrorRaisedException
Message: :Class cannot extends type: class.bsh.Primitive"
.
The ooo version is 3.1.1. I hope someone can help me.
Thanks. |
|
| Back to top |
|
 |
ms777 Super User


Joined: 07 Feb 2004 Posts: 1355
|
Posted: Sun Oct 11, 2009 7:17 am Post subject: |
|
|
Hi,
does my original code run on your machine as advertised ? Note that you have to take the OO2.4+ version ...
If yes, please post your complete code. If no, let me know what failure is generated
Good luck,
ms777 |
|
| Back to top |
|
 |
ellebi General User

Joined: 11 Oct 2009 Posts: 13
|
Posted: Sun Oct 11, 2009 1:27 pm Post subject: |
|
|
Thanks for your reply!
As I told, my oo version is 3.1.1 (last), so your code does not work on my laptop (with fedora 11, kernel 2.6.30) because it is for 002.4+ version! I think not so...
Anyway I try to explain my code; it's a basic macro, in a calc document, for a dialogue with (between various controls) a TimeField where I want to see the current time (that of course change every minute). That's why I want to use the timer. I put your basic "main" code in the function where this dialog is opened (not complete) and the function "GenerateTimerPropertySet":
Function setDateTimeUnitsDialog() as boolean
...
Dim oThisDialog As Object
Dim oP As Object, oJob1 As Object
oP = GenerateTimerPropertySet()
oJob1 = createUnoListener("nowJob_", "com.sun.star.task.XJobExecutor")
oP.xJob = oJob1
oP.lMaxIterations = 5
oP.lPeriodInMilliSec = 1000
oP.start()
...
oThisDialog = CreateUnoDialog(DialogLibraries.Standard.dateTimeUnitsDialog)
setDateTimeUnitsDialog = oThisDialog.execute()
...
end function
'run script in Timer.bsh
Function GenerateTimerPropertySet() as Any
Dim oSP As Object, oScript As Object
oSP = ThisComponent.getScriptProvider("")
oScript = oSP.getScript("vnd.sun.star.script:Timer.Timer.bsh?language=BeanShell&location=document")
GenerateTimerPropertySet = oScript.invoke(Array(), Array(), Array())
End function
'here I would put later the instructions for update the TimeField
sub nowJob_trigger(s as String)
...
end sub
When I run the macro (a click on the sheet...) calc gives me the error; in the basic IDE, the code is highlighted at:
GenerateTimerPropertySet = oScript.invoke(Array(), Array(), Array())
in the beanshell editor there's a red arrow at:
public class ms777Timer_06 extends PropertySet implements XElementStackKeeper
The error is:
Basic runtime error. Exception occurred (...this translated in English, from Italian)
Type: com.sun.star.reflection.InvocationTargetException
Message: Beanshell error for timer.bsh
TargetException:
Type:
com.sun.star.script.provider.ScriptErrorRaisedException
Message: :Class cannot extends type: class bsh.Primitive
That's all. I hope you understand my problem.
Thanks. |
|
| Back to top |
|
 |
ellebi General User

Joined: 11 Oct 2009 Posts: 13
|
Posted: Sun Oct 11, 2009 3:15 pm Post subject: |
|
|
Hi,
I just tried the code (2nd version of beanshell script) on xp and it works. Perhaps it does not work in linux! |
|
| Back to top |
|
 |
ellebi General User

Joined: 11 Oct 2009 Posts: 13
|
Posted: Sun Oct 18, 2009 4:04 am Post subject: |
|
|
Hi
someone tell me if it is possible and how extend a java class in a BeanShell script in Linux environment! Thanks. |
|
| Back to top |
|
 |
blabj Newbie

Joined: 27 Oct 2009 Posts: 1
|
Posted: Tue Oct 27, 2009 11:05 am Post subject: works on linux with oo3.0 |
|
|
Great solution. Just advising that this is working on ubuntu hardy with OO 2.4 and ubuntu jaunty with OO 3.0. Only trick was that "bsh" (beanshell) needed to be installed separately.
-Bob |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|