[Solved] Reach a form control from timer-triggered event

Creating and using forms
Post Reply
zeke99
Posts: 24
Joined: Fri Jun 29, 2012 4:05 pm

[Solved] Reach a form control from timer-triggered event

Post by zeke99 »

I have Base connected to a MySQL-database. In Base I have only one form called Levlista. The form is refreshed on interval with some beanshell and starbasic code.
Beanshell:

Code: Select all

    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();
Basic:

Code: Select all

REM ***** Basiccode for timer-macro              *****

Sub Timermakro

oP = GenerateTimerPropertySet()
oJob1 = createUnoListener("JOB1_", "com.sun.star.task.XJobExecutor")
oP.xJob = oJob1
oP.lMaxIterations    = 5
oP.lPeriodInMilliSec = 25000
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)
dim document   as object
dim dispatcher as object
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:Refresh", "", 0, Array())
end sub
When the timer trigger the sub JOB1_trigger I would like to put some text in a textbox called TextBox1.
But since the sub is triggered from the timer and not from something inside the form I can't find how to reach the TextBox1-control.
I have tried to xray every possible way of ThisComponent.... but even if I can find the form "Levlista" I cannot reach the controls inside the form.
Models, views, frames, my head is boiling now so I will go and put it in the freezer and cool down. In the meantime if anyone know where I get it all wrong please share it with me.
Last edited by zeke99 on Thu Aug 27, 2015 8:11 am, edited 1 time in total.
OpenOffice 4.1 LinuxMint 17
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: How to reach a form control from timer-triggered event

Post by Villeroy »

Store a reference to the form or to the form control with your timer object?
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
MTP
Volunteer
Posts: 1620
Joined: Mon Sep 10, 2012 7:31 pm
Location: Midwest USA

Re: How to reach a form control from timer-triggered event

Post by MTP »

To get your form document you're probably doing something like this?

Code: Select all

oFormDoc = ThisDatabaseDocument.FormDocuments.getByName("Levlista") 
Then to get the controls you'll need to know the names of the forms (and subforms, if applicable) that are inside the form document. (Forms inside form documents... what a confusing naming scheme!) You can see the form names and hierarchy in the form navigator window. To open the form navigator, make sure the toolbar "Form Design" is visible. The icon for form navigator is sixth from the left or top, looks like a rectangle with a compass in the upper right corner. Say your form name is MainForm, and your textbox is part of MainForm (i.e. no subforms), then you'd get the control like this (note that form names and control names are case sensitive):

Code: Select all

oTextBox = oFormDoc.MainForm.TextBox1
oTextBox.text = "Your text"
OpenOffice 4.1.1 on Windows 10, HSQLDB 1.8 split database
zeke99
Posts: 24
Joined: Fri Jun 29, 2012 4:05 pm

Re: How to reach a form control from timer-triggered event

Post by zeke99 »

Thank you MTP. It's amazing what a good nights sleep and a helping hand can do.

You have to go a little bit deeper to get the control. Here's the code:

Code: Select all

odoc=ThisDatabaseDocument.FormDocuments.getByName("Levlista1").Component.DrawPage.Forms

oTextBox = odoc.MainForm.TextBox1
oTextBox.text = s
OpenOffice 4.1 LinuxMint 17
zeke99
Posts: 24
Joined: Fri Jun 29, 2012 4:05 pm

Re: [Solved]How to reach a form control from timer-triggered

Post by zeke99 »

Some details and changes ..

The row "oP.lMaxIterations = 5" in the sub Timermakro gives the number of times the macro JOB1_trigger is executed. I have changed it to 20000. Will see if I can find a way to give an infinite number of times executed.

In order to get the form updated properly i change the macro JOB1-trigger to:

Code: Select all

sub JOB1_trigger(s as String)
dim doc as object
dim odoc as object
dim oTextBox as object 
dim tid as date

odoc=ThisDatabaseDocument.FormDocuments.getByName("Levlista1").Component.DrawPage.Forms

' Gives a time stamp of the latest update in the textbox TextBox1
tid=now
oTextBox = odoc.MainForm.TextBox1
oTextBox.text = tid

' Reload the form Levlista1
doc=odoc.MainForm
doc.reload
end sub
OpenOffice 4.1 LinuxMint 17
Post Reply