1

Question: I need to manually call an object listener event (e.g. key pressed) to trigger a function. I used to do it 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 - but more with Oracle, PL/SQL, APEX, etc! I am struggling a little in getting it to do what I know can be done!

Pᴇʜ
  • 56,719
  • 10
  • 49
  • 73
Hippy Steve
  • 111
  • 1
  • 2
  • Is the "function" (more likely a method or subroutine) an event listener that you have written, or the built-in object listener of a control? What kind of control: button, text field, table control? One more question: Is this about LO Basic? Event listeners in other LibreOffice languages such as Python or Java are quite a bit different, and they are generally easier to work with in my opinion. But what you want can probably be done in Basic. Normally I would also ask what Base engine as well - firebird, hsqldb, MySQL, or even Oracle. However, that's not important for this question. – Jim K May 20 '20 at 19:01
  • OK, apologies for nto being more specific... Method is the current terminology for what use to be called a function (i.e. a procedure that returns a value). The current control is a table in a subform but it could easily be a button or textbox on a form. I'm using LO basic on an embedded firebird engine. – Hippy Steve May 21 '20 at 09:27
  • And I need to access the built-in object listener from a macro. – Hippy Steve May 21 '20 at 09:33
  • This is my go to on this type of question: https://www.pitonyak.org/OOME_3_0.pdf I haven't gotten into the listener stuff too much, but hope this might help. It's the best reference I know of for this stuff. – Elliptical view May 22 '20 at 16:46

1 Answers1

0

Here is the code I've tried so far.

Sub CauseKeyPressedEventToBeFired
    oDoc = ThisComponent
    oController = oDoc.getCurrentController()
    oVC = oController.getViewCursor()
    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.Source = oControlView
    oEvent.KeyCode = com.sun.star.awt.Key.A
    oControlView.keyPressed(oEvent) 
End Sub

However, it doesn't seem to work on my system (LibreOffice 6.4.3.2 on Windows). I also found this post, but that code doesn't seem to work for me either.

I searched for com.sun.star.awt.XToolkitRobot, but it's not in the API documentation, perhaps because the functionality is not fully supported. Presumably, it can be obtained from com.sun.star.awt.Toolkit.

For more help, post a question on ask.libreoffice.org. I'd suggest explaining why you want to do this, because there may be a different kind of solution. Ratslinger has a lot of experience solving various database problems, and he'll probably direct you toward a simpler solution that doesn't involve this kind of event hacking.

a function (i.e. a procedure that returns a value)

Yes, that is what a function is. But "an object listener event" implies, correctly I think, that we're talking about the method of an object instead. That's what LibreOffice event listeners are in Python or Java, although in Basic, they're a little strange, using the object name as some kind of magic to determine what they apply to. Anyway, that's getting off track, because your question isn't about listening for events, but rather about triggering them.

EDIT:

The following Python code works. The problem with my earlier attempts was that oEvent.KeyChar needs to be set, and that doesn't seem to work in Basic. I can't imagine why, unless I am ignoring some obvious mistake in the Basic code.

def causeKeyPressedEventToBeFired(oEvent=None):
    oDoc = XSCRIPTCONTEXT.getDocument()
    oController = oDoc.getCurrentController()
    oForm = oDoc.getDrawPage().getForms().getByName("Form")
    oTextBox = oForm.getByName("Text Box 1")
    oControlView = oController.getControl(oTextBox)
    oControlView.setFocus()
    oEvent = uno.createUnoStruct("com.sun.star.awt.KeyEvent")
    oEvent.Source = oControlView
    from com.sun.star.awt.Key import A
    oEvent.KeyCode = A
    oEvent.KeyChar = "a"       # works in Python but strangely not in Basic
    simulate_KeyPress(oEvent)

def simulate_KeyPress(oKeyEvent):
    oDoc = XSCRIPTCONTEXT.getDocument()
    oWindow = oDoc.CurrentController.Frame.getContainerWindow()
    oKeyEvent.Source = oWindow      
    oToolkit = oWindow.getToolkit()
    oToolkit.keyPress(oKeyEvent)
    oToolkit.keyRelease(oKeyEvent)

EDIT 2:

Finally, here is working Basic code. In the earlier attempt, the type was wrong.

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
Jim K
  • 12,824
  • 2
  • 22
  • 51
  • Thanks Jim, you've clearly taken some time over this, I appreciate it. I've played with your code a little with, so far, the same results as you... I'll follow your suggestion of posting a (clear!) question on the other forum then post a link here once we know the answer. – Hippy Steve May 22 '20 at 09:03