Libreoffice Base - how to call a control event from a macro?

Question: I need to manually call an object listener event, e.g. use a macro to simulate the pressing of a button so the “On Execute” event fires when I want it to, not just when the user presses the button. I used to do this in Access but haven’t found the documentation for it in LibreOffice Base.

Context: Having retired from software development 7 years ago, I am doing a favour for a friend by building a database in LibreOffice Base. Previously experienced in Access and vba / VB - but more with Oracle, PL/SQL, APEX, etc! I am struggling a little in getting it to do what I know can be done!

Original question: database - Libreoffice Base - how to call a control event from a macro? - Stack Overflow.

Hello,

This posed question is slightly different than that on stackoverflow. Had it been the same there it is certain @jimk would have provided a very similar answer.

Will base the answer on:

simulate the pressing of a button so the “On Execute” event fires when I want it to, not just when the user presses the button.

The basis is from → Create a macro that press “Enter” automatic once.

Now using the main code from @jimk :

Sub CauseKeyPressedEventToBeFired
    oDoc = ThisComponent
    oController = oDoc.getCurrentController()
    oVC = oController.getViewCursor()
    oForm = oDoc.getDrawpage().getForms().getByName("MainForm")
    oTextBox = oForm.getByName("PushButton")
    oControlView = oController.getControl(oTextBox)
    oControlView.setFocus()
    simulate_KeyPress_RETURN
End Sub

you can call any time to push that button.

Sample — EventSelection.odb

As stated this is as the question was asked. If other conditions, it may require entirely different direction and should be a different question with specifics.

1 Like

Interesting - the code works with control keys but not standard keys. What works: RETURN, TAB, BACKSPACE, LEFT. Keys that have no effect: A, SEMICOLON, NUM0, SPACE. In a text box, pressing “A” produces the desired letter (of course), but simulating the keypress does not.

It does not seem to be possible to set the value of oEvent.KeyChar, which I do not understand since KeyEvent is a struct. Maybe it is not necessary, or maybe that is where the problem lies.

Everything works in python. Setting oEvent.KeyChar fixes the problem, but not possible in Basic? XrayTool shows that oEvent.KeyChar = Chr(97) does not change the value in the struct.

@jimk,

May have some time later to try in Python. Would not surprise me if this is a problem in Basic.

Edit:

Further testing in basic has the event firing but the character never appears in the text box.

Probably a bug.

Do see your Python code works fine.

Digging into the Python code showed that something else is going on, as explained in my answer. Not a bug in the Basic runtime, so that’ s good.

To me this question is only partially answered. There are some events that are noted which can be ‘triggered’. However there are more than what has been covered here. Was looking for some type of mechanism to ‘execute’ an event but have not found that.

This post may be of interest → How to access the settings under the ‘Events’ tab of a form control to get / set the routines?.

Please note the sample in my answer. On Sheet2 of that sample is a matrix of controls and the events. You can see there are more events than discussed in this question.

It turns out that @librebel’s code from the old post wasn’t quite right. Setting the KeyChar property requires a byte.

Sub CauseKeyPressedEventToBeFired
    oDoc = ThisComponent
    oController = oDoc.getCurrentController()
    oForm = oDoc.getDrawpage().getForms().getByName("Form")
    oTextBox = oForm.getByName("Text Box 1")
    oControlView = oController.getControl(oTextBox)
    oControlView.setFocus()
    Dim oEvent As New com.sun.star.awt.KeyEvent
    oEvent.KeyCode = com.sun.star.awt.Key.A
    oEvent.KeyChar = CByte(97)
    simulate_KeyPress(oEvent)
End Sub

Sub simulate_KeyPress(oKeyEvent As com.sun.star.awt.KeyEvent)
    oWindow = ThisComponent.CurrentController.Frame.getContainerWindow()
    oKeyEvent.Source = oWindow      
    oToolkit = oWindow.getToolkit()
    oToolkit.keyPress(oKeyEvent)
    oToolkit.keyRelease(oKeyEvent)
End Sub

Note that this isn’t really an answer to the question as asked, so it may be more appropriate to mark @Ratslinger’s answer as the accepted one.

1 Like

@jimk,

Nice find. Testing looks good. Had not gotten into digging into the code much.

Thanks for the post.