Forum at OOoForum.orgThe Forum
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

improved approach to event listeners for dialog controls

Post new topic   Reply to topic Forum Index -> Code Snippets
View previous topic :: View next topic  
Author Message
General User
General User

Joined: 06 Mar 2006
Posts: 26
Location: Victoria, B.C., Canada

PostPosted: Thu Mar 16, 2006 2:30 pm    Post subject: improved approach to event listeners for dialog controls Reply with quote

This is a continuation of my earlier post in this forum on the same subject:

I recently discovered by chance (actually, from the slides for a presentation by Andrew Pitonyak) that it is possible to define structs in OOo Basic. That is what is required to do an elegant job of making the routines for assigning event listeners to dialog controls fully general. I couldn't resist.

What follows is in 3 parts:
    library elements
    example application

Comments in the code below, especially at the head of the library routines, should explain the purpose and usage of each element.

Library Elements

(Actually, a the contents of a module.) Install this somewhere all your macros can access it (i.e., My Macros & Dialogs).
' Utilities to support event listener assignment for controls in dialogs
' Author: Rod Glover
' Date: March 2006

' Structure for holding a record of an event listener assignment to a control
Type ControlEventListenerAssignment
   Control as Variant
   ListenerType as String
   Listener as Variant
End Type

' Return a list (implemented as a 0-based array) of empty event listener assignments
Function newEventListenerAssignmentList (n as Integer)
   Dim newArray(0 to n-1) as ControlEventListenerAssignment
   Dim i as Integer
   For i = 0 to n-1
      With newArray(i)
         .Control = Null
         .ListenerType = ""
         .Listener = Null
      End With
   newEventListenerAssignmentList = newArray()
End Function

' Add an event listener of specified type to a control in a dialog, recording the assignment in the list of
' event listener assignments
' Arguments
'   oDialog               Dialog containing control
'   sNamePrefix            Prefix for event handler names; see below
'   sControlName         Name of control in dialog
'   sListenerType         Type of listener to be created and added to control, in standard form
'                     "<type>Listener"; see below
'   oListenerAssignments   List of event listener assignments in which the requested assignment will be
'                     recorded (for later removal)
' Each listener requires one or more specially named event handler routines to be created.
' Generically, each event handler name is composed of:
' - listener identifier (usually the control name + "_") specified when the listener is created +
' - a listener-specific handler name, as noted below for selected listeners
' In this routine, event handler names for a control are constructed using a listener identifier =
' sNamePrefix + sControlName.
' sNamePrefix is most useful when the caller sets it to the dotted qualifier for the library and
' module in which the event handler routines are stored, e.g., "My_Library.My_Module.".
' See the SDK documentation for each listener interface (e.g., XActionListener) for details
' about the event specifier object passed to each type of handler routine. Briefly, the handlers
' required for selected event listeners are:
' Listener         Handler names
' --------         -------------
' XActionListener   actionPerformed
' XItemListener      itemStateChanged
' XTextListener      textChanged
' XFocusListener   focusGained
'               focusLost
Sub addListenerToControlInDialog ( _
      oDialog as Variant, sNamePrefix as String, sControlName as String, sListenerType as String, _
      oListenerAssignments() as ControlEventListenerAssignment)

   Dim oDialogModel as Variant
   Dim oControl as Variant
   Dim oControlModel as Variant

   Dim sListenerName as String
   oDialogModel = oDialog.getModel()
   oControl = oDialog.getControl(sControlName)

   sListenerName = sNamePrefix + oControl.Model.Name + "_"
   addListenerToControl (oControl, sListenerName, sListenerType, oListenerAssignments() )
End Sub

' Create a listener of the specified type and name, and add it to the control.
' Record the listener in the oListenerAssignments list so that it can later be removed.
' Return the created listener.
' The Select Case statement below determines the listener types supported. If additional
' types are required, add them there, and correspondingly in routine removeListenersFromControls.
Function addListenerToControl ( _
      oControl as Variant, sListenerName as String, sListenerType as String, _
      oListenerAssignments() as ControlEventListenerAssignment)
   Dim free as Integer
   Dim oListener as Variant
   ' Extend listener assignments array by 1
'   Dim L as Integer, U as Integer
'   L = LBound(oListenerAssignments())
'   U = UBound(oListenerAssignments()) + 1
'   ReDim Preserve oListenerAssignments (L to U) as ControlEventListenerAssignment
'   Dim oNewListenerAssignments (L to U) as ControlEventListenerAssignment
'   For i = L to U-1
'      oNewListenerAssignments(i) = oListenerAssignments(i)
'   Next
'   oListenerAssignments() = oNewListenerAssignments()

   ' Locate a free listener assignment, denoted by empty string for ListenerType
   free = LBound(oListenerAssignments())
   Do While free <= UBound(oListenerAssignments())
      If oListenerAssignments(free).ListenerType = "" Then
         Exit Do
      End If
      free = free + 1
   If free > UBound(oListenerAssignments()) Then
      MsgBox ("No free listener assignments when attempting to add listener ", sListenerName)
      Exit Function
   End If

   ' Create listener, record it in the free listener assignment slot, and add it to the control.
   oListener = CreateUnoListener(sListenerName, sListenerType)
   With oListenerAssignments(free)
      .Control = oControl
      .ListenerType = sListenerType
      .Listener = oListener
   End With
   Select Case sListenerType
   Case "":
   Case "":
   Case "":
   Case "":
   Case Else:
      MsgBox ("addListenerToControl: " + sListenerType + " not supported")
   End Select
   addListenerToControl = oListener
End Function

' Remove action listeners from controls.
' This appears to be required to prevent errors after the dialog is closed.
Sub removeListenersFromControls (oListenerAssignments() as ControlEventListenerAssignment)

   Dim c as Integer
   for c = LBound(oListenerAssignments) to UBound(oListenerAssignments)
      With oListenerAssignments(c)
         Select Case .ListenerType
         Case "":
            ' Already removed
         Case "":
         Case "":
         Case "":
         Case "":
         Case Else:
            MsgBox ("removeListenersFromControls: " + .ListenerType + " not supported")
         End Select
'         .Control = Null      ' For some reason mysterious to me, this causes an error
         .ListenerType = ""
         .Listener = Null
      End With

End Sub

Example Application

To run the following example, you need to create a dialog named "TestDialog" in a library named "TestLibrary". It must include the following controls:
    Button named CommandButton1
    Textbox named TextField1
    Label named Label1

With the example code below, this dialog will pop up a message box when the button is clicked, and will set the text in the label to the text entered in the textbox. Woo-hoo.

Install the following code in a module "TestLibrary.Test" (or change the addListenerToControlInDialog calls to refer to wherever you put it).
Dim oTestDialog as Variant
Dim oTestListenerAssignments

Sub StartTestDialog

   oTestDialog = CreateUnoDialog (DialogLibraries.TestLibrary.TestDialog)

   oTestListenerAssignments = newEventListenerAssignmentList(3)
   addListenerToControlInDialog (oTestDialog, "TestLibrary.Test.", _
      "CommandButton1", "", oTestListenerAssignments)
   addListenerToControlInDialog (oTestDialog, "TestLibrary.Test.", _
      "TextField1", "", oTestListenerAssignments)


   removeListenersFromControls (oTestListenerAssignments)
End Sub

Sub CommandButton1_actionPerformed (oEvent as Variant)
End Sub

Sub TextField1_textChanged (oEvent as Variant)
   oTestDialog.Model.Label1.Label = oTestDialog.Model.TextField1.Text
End Sub


As you may discover in the code, I initially wanted to automatically extend the list (array) of event listener records as each listener was added. But OOo Basic wasn't cooperating, and I had to fall back on pre-allocating an array and finding and using the first empty slot in it. (I couldn't be bothered to implement this as a linked list.) Hence the routine newEventListenerAssignmentList(), which you must call first to allocate a sufficiently long list to hold your listener assignments. It will complain if you exceed its size. Imperfect, but quite usable.

I invite comments or improvements to this.
Rod Glover
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic Forum Index -> Code Snippets All times are GMT - 8 Hours
Page 1 of 1

Jump to:  
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