Ask Your Question
1

How to properly code a broadcaster and listener in LO Basic

asked 2016-04-14 19:16:47 +0100

docbda gravatar image

I have read Pitonyak's section on listeners in OOo Macros Explained, and it left me bewildered and confused (but bless his heart for taking the time to write such a comprehensive document on OOo Basic). Unfortunately, I'm quite new at coding in OOo Basic (and coding in general) and I'm trying to learn on the fly (by doing). Therefore, much of his explanation went zinging over my head.

That said, here's what I'm trying to accomplish:

I'm writing a macro contained within in a Base form. In this macro, I have several image buttons that when clicked pass a text string to a textbox via a short sub routine that is triggered when the mouse button is pressed on the image button. Each of these image buttons have their own unique text string. At times, I will need to concatinate two of these text strings together (originating from different buttons).

The problem is that I don't know in what order the buttons will be pushed, so I need the macro to detect when a second (or third, fourth, fifth, etc) is pushed and add the string associated with that button to the growing text string. Therefore, I need the macro to "listen" for one of the image buttons to be pushed (I'm assuming the image button would be the broadcaster), and when detected by the listener, pass the detected button's associated text string to the subroutine that is building the concatinated text string.

When I read Pitonyak's statement, "Knowing which broadcaster to use is not always an easy task. It requires understanding how OOo is designed; this comes with experience." I knew i was in trouble.

If someone would be kind enough to show me some example code that is a possible solution for the above, or point me toward a tutorial regarding this topic that is slanted more toward the beginner, I would be most appreciative.

Cheers.

docbda

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2016-04-14 19:53:28 +0100

Ratslinger gravatar image

updated 2016-04-14 23:59:20 +0100

OK. I've limited experience with this but have some info for you. First is the code from Pitonyak. This gets you the methods you need to code. Copy this code:

   Sub InspectListenerMethods
      Dim sPrefix$
      Dim sService$
      Dim vService
      sPrefix = "sel_change_"
  ' sService = "com.sun.star.view.XSelectionChangeListener"
  ' sService = "com.sun.star.lang.XEventListener"
  ' sService = "com.sun.star.awt.XMenuListener"
   sService = "com.sun.star.awt.XKeyHandler"
  ' sService = "com.sun.star.awt.XButton"
   vService = CreateUnoListener(sPrefix, sService)
   DisplayDbgInfoStr(vService.dbg_methods, ";", 35, "Methods")
  End Sub
Sub DisplayDbgInfoStr(sInfo$, sSep$, nChunks, sHeading$)
Dim aInfo()
 'Array to hold each string
Dim i As Integer
 'Index variable
Dim j As Integer
'Junk integer variable for temporary values
Dim s As String
'holds the portion that is not completed
s = sInfo$
j = InStr(s, ":")
'Initial colon
If j > 0 Then Mid(s, 1, j, "") 'Remove portion up to the initial colon
    Do
        aInfo() = Split(s, sSep$, nChunks)
'Split string based on delimiter.
        s = aInfo(UBound(aInfo()))
 'Grab the last piece. Contains
        If InStr(s, sSep$) < 1 Then
 'the rest if there were too many.
            s = ""
 'If there were not, then clear s.
        Else
'If there was a delimiter then
            ReDim Preserve aInfo(nChunks - 2)
'change array dimension to
        End If
'remove the extra last piece.
        For i = LBound(aInfo()) To UBound(aInfo())'Look at each piece to remove
            aInfo(i) = Trim(aInfo(i))
'leading and trailing spaces.
            j = InStr(aInfo(i), CHR$(10))
'Some have an extra
            If j > 0 Then Mid(aInfo(i), j, 1, "") 'new line that should be removed.
        Next
        MsgBox Join(aInfo(), CHR$(10)), 0, sHeading$
    Loop Until Len(s) = 0
  End Sub

Running the macro InspectListenerMethods will display the methods you need to incorporate into your code. sService is the the only thing you need to modify. It is currently set for XKeyHandler with others commented out. Easier for later examination. So if you run this three items need definition even if they don't do anything (queryInterface can be ignored)- disposing, keyPressed and keyReleased. Knowing that, here is my key handler(working model):

   global oXKeyHandler as object
   sub sStartXKeyHandler
       if isNull(oXKeyHandler) then 'only if not jet running
           oXKeyHandler = CreateUnoListener("KeyHandler_", "com.sun.star.awt.XKeyHandler")
           ThisComponent.CurrentController.AddKeyHandler(oXKeyHandler)
       endif
   end sub

sub sStopXKeyHandler
    if not IsNull(oXKeyHandler) then 'only if still running
        ThisComponent.CurrentController.removeKeyHandler(oXKeyHandler)
        oXKeyHandler = Nothing 'To know later this handler has stopped.
    end if
end sub

sub XKeyHandler_Disposing(oEvent)
end sub

function KeyHandler_KeyPressed(oEvent) as boolean
 'The entire objective of the key handler:
 'On the menu, when the 'Enter' key is pressed
 'don't move to the next field(cancel)
    If (oEvent.KeyCode = 1280) Or (oEvent.KeyCode = 1284) Then
        KeyHandler_KeyPressed = True 'cancel KeyPressed
    Else
        KeyHandler_KeyPressed = False 'cancel KeyPressed
    End If
End function

function KeyHandler_KeyReleased(oEvent) as boolean
 'but when the 'Enter' key is released,
 'execute the 'Key Released' event assigned in the control
    If oEvent.KeyCode = 1280 Then
        KeyHandler_KeyReleased = False 'cancel KeyReleased
    Else
        KeyHandler_KeyReleased = True 'cancel KeyReleased
    End If
end function

This was ... (more)

edit flag offensive delete link more

Comments

Whoa!!! Thanks a ton. Let me digest this, and I'll get back to you with the questions I'm sure to have. docbda

docbda gravatar imagedocbda ( 2016-04-14 20:04:42 +0100 )edit

Ratslinger, Here's what I've done so far: 1) copied both pieces of code into the same module. 2) identified where sService is set for XKeyHandler. I'm not sure how I need to modify this. 3) I identified _Disposing (which was an empty sub routine), _KeyPressed (function that stated if keys 1280 or 1284 were pressed, then KeyHandler_KeyPressed was True), and _KeyRealeased (function that says if oEvent.KeyCode = 1280 then _KeyReleased is false. You state that these items need definitions.

docbda gravatar imagedocbda ( 2016-04-14 20:51:41 +0100 )edit

I'm guessing that I need to add some dummy code to disposing, and replace your If Then Else statements in KeyPressed and KeyReleased with more dummy code, but I'm not sure how to go about this. I apologize for my ignorance.

docbda gravatar imagedocbda ( 2016-04-14 20:53:23 +0100 )edit

I see where you commented out sService = XButton. Not sure how I "start there and try Pitonayak's book again." Remember ... super noob here...

docbda gravatar imagedocbda ( 2016-04-14 21:02:47 +0100 )edit

By running InspectListenerMethods exactly as presented will display what methods were needed for my key handler (less of course the starting & stopping of the handler itself). This explains just what methods I needed to code as can be seen in my KeyHandler section. Now the harder part. Comment out the sService XKeyHandler line and remove the comment from the XButton line & run InspectListenerMethods again. These are probably the methods you will need for your handler.

Ratslinger gravatar imageRatslinger ( 2016-04-14 21:26:17 +0100 )edit

I say probably because it is not always clear cut as to which service to use. That's why I have various commented lines. Looking at different services to find ones I need. Disposing is empty because my stop handler does all I need. Disposing can do additional but not needed here. However, it is a required method thus it is empty. That is why I say go through all this then go back to the book. It should add some clarity.

Ratslinger gravatar imageRatslinger ( 2016-04-14 21:32:06 +0100 )edit

When I first tried to run this I had a run-time error. I just tried it again, and it worked fine. The methods you needed to code were: SbxEMPTY queryInterface ( SbxOBJECT ) SbxVOID disposing ( SbxOBJECT ) SbxBOOL keyPressed ( SbxOBJECT ) SbxBOOL keyReleased ( SbxOBJECT )

Now for step 2...

docbda gravatar imagedocbda ( 2016-04-14 21:37:16 +0100 )edit

Result: SbxEMPTY queryInterface ( SbxOBJECT ) SbxVOID addActionListener ( SbxOBJECT ) SbxVOID removeActionListener ( SbxOBJECT ) SbxVOID setLabel ( SbxSTRING ) SbxVOID setActionCommand ( SbxSTRING ) ...OK, back to Pitonyak I'll be in touch

docbda gravatar imagedocbda ( 2016-04-14 21:40:55 +0100 )edit

Please see additional info in my answer!!!

Ratslinger gravatar imageRatslinger ( 2016-04-14 21:57:30 +0100 )edit

That is a much easier solution!!! Although, at some point I need to learn how to code the listener too. I might give it a try anyway just to complete this post for the next guy that comes along that needs some help in this regard. Thanks, as always.

docbda gravatar imagedocbda ( 2016-04-15 04:12:50 +0100 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2016-04-14 19:16:47 +0100

Seen: 251 times

Last updated: Apr 14 '16