UNO Listeners


A UNO listener is the paradigm used by OOo to inform external programs what it is doing. Consider a hospital worker as an analogy: Before I (the hospital worker) do anything interesting to treat patient Paolo, a 16-year-old boy from Argentina, I am required first to call his parents and ask permission. I don't have to call for everything, such as the most routine questions and physical examinations or some acute critical-care procedures. For some things, I must make the effort to speak to his parents, and for some things his parents may say "No, you cannot do it." In other circumstances, I may call only to provide status information. This is very similar to the UNO listeners. The code that you write is called the listener, and the thing to which you listen is called the broadcaster. In the previous example, the hospital worker is the broadcaster and Paolo's parents are the listeners.

If some portion of OOo supports listeners, you can listen to what it is doing. The routines required to listen to a specific OOo interface are specific to that interface. In other words, the set of subroutines and functions that can act as a listener to printing events is different from the set of subroutines and functions that can listen to keystroke events.

The first step in writing a listener is to determine what interface you must implement. The interface defines the subroutines and functions that you must write. Two different listener interfaces will have at least one required subroutine or function in common. To avoid the problems that this may cause, OOo Basic requires you to choose a string that prefixes each subroutine and function that you write for the listener.

Your First Listener

All listeners are derived from the com.sun.star.lang.XEventListener. This means that all listeners must implement all of the routines required for the XEventListener. The XEventListener interface is simple because it defines only one subroutine: disposing(EventObject).

The disposing method is called when the broadcaster is about to become unavailable. In other words, the broadcaster will no longer exist and you should not use it. For example, a print job is finished so it is no longer required or a document is closing. To write the simplest listener possible, I will write an XEventListener. In Listing 15 I'll use the string prefix "first_listen_" for my first listener because it is descriptive.

Listing 15: first_listen_disposing is found in the UNO module in this chapter's source code files as SC09. sxw.
start example
 Sub first_listen_disposing( vArgument )     MsgBox "Disposing In First Listener" End Sub 
end example
 

Listing 15 is all that is required for this simple listener. Use the CreateUNOListener to create a UNO listener that is associated with the macro in Listing 15. The first argument is the string prefix and the second argument is the name of the service to create.

The routine in Listing 16 creates the UNO listener and associates it with the routine in Listing 15. When the disposing method is called on vListener, it calls the routine in Listing 15.

Listing 16: MyFirstListener is found in the UNO module in this chapter's source code files as SC09.sxw.
start example
 Sub MyFirstListener   Dim vListener   Dim vEventObj As New com.sun.star.lang.EventObject   Dim sPrefix$   Dim sService$   sPrefix = "first_listen_"   sService = "com.sun.star.lang.XEventListener"   vListener = CreateUnoListener(sPrefix, sService)   vListener.disposing(vEventObj) End Sub 
end example
 

A Complete Listener: Selection Change Listener

The two most difficult parts of creating a listener are determining which broadcaster and which listener interface to use. The rest of the steps are easier.

  1. Determine the broadcaster to use.

  2. Determine the listener interface to implement.

  3. Create global variables for the listener and maybe the broadcaster.

  4. Determine the prefix that you will use; make it descriptive.

  5. Write all of the subroutines and functions that implement the listener.

  6. Create the UNO listener and save it in the global variable.

  7. Register the listener with the broadcaster.

  8. When finished, remove the listener from the broadcaster.

Knowing which broadcaster to use is not always an easy task. It requires understanding how OOo is designed; this comes with experience. There is usually an obvious place to start looking-the current document, available from the variable ThisComponent, contains the document data. Start looking here for broadcasters that pertain to the document's data. For example, the document accepts an XPrintJobListener to monitor how printing is progressing. Most tasks related to user interactions-such as selecting text, moving the mouse, and entering keystrokes-all go through the document's controller.

Related to determining the broadcaster is choosing the correct listener to implement. If you think that you know which broadcaster to use, inspect the "add listener" methods on the broadcaster object. I was recently asked how to prevent a dialog from closing when the user clicks on the little X icon in the upper-right corner of a dialog. I reasoned that the dialog is probably the correct broadcaster to use, so I created a dialog and inspected the "dbg_methods" property to see which listeners it supports (each supported listener has "set" and "remove" methods). Another option is to determine the event type that is produced and then search to see which broadcasters support this event type. I usually do this by searching the OOo Developer's Guide and the Internet. (I'll discuss effective methods for finding information in Chapter 18, "Sources of Information.")

To listen for a selection change event, I need to implement an XSelectionChangeListener and register it with the current controller. This interface defines only one subroutine that must be implemented-selectionChanged (ObjectEvent). All events are derived from the XEventListener so the disposing(ObjectEvent) method must also be implemented. The fastest way to determe which subroutines and functions must be implemented is to create an instance of the listener by using the function CreateUNOListener and then inspect the dbg_methods property (see Listing 17 and Figure 5 ).

click to expand
Figure 5: Ignore the queryInterface method.
Listing 17: InspectListenerMethods is found in the UNO module in this chapter's source code files as SC09.sxw.
start example
 Sub InspectListenerMethods   Dim sPrefix$   Dim sService$   Dim vService   sPrefix = "sel_change_"   sService = "com.sun.star.view.XSelectionChangeListener"   vService = CreateUnoListener(sPrefix, sService)   DisplayDbgInfoStr(vService.dbg_methods, ";", 35, "Methods") End Sub 
end example
 

The queryInterface method is from the interface com.sun.star.uno.XInterface, which is inherited from the XEventListener. You can ignore this method. However, you must implement the rest of the routines. Choose a descriptive prefix so that the code can contain more than one listener. See Listing 18 .

Listing 18: sel_change_disposing and sel_change_selectionChanged are found in the UNO module in this chapter's source code files as SC09.sxw.
start example
 'All listeners must support this event Sub sel_change_disposing(vEvent)   msgbox "disposing the selection change listener" End Sub Sub sel_change_selectionChanged(vEvent)   Dim vCurrentSelection As Object    vCurrentSelection = vEvent.source    Print "Number of selected areas = " &_           vCurrentSelection.getSelection().getCount() End Sub 
end example
 

The routine in Listing 19 creates a listener by calling the function CreateUnoListener. When I tested this listener, I ran the macro and then the macro stopped running. The listener is still active and called by the broadcaster even though the macro is no longer running. In other words, the routine in Listing 19 registers a listener, and then it is finished. The broadcaster calls the listener when things occur. The listener must be stored in a global variable so that it's available later-for example, when it's time to remove the listener from the object or when one of the methods is called.

Listing 19: StartListeningToSelChangeEvents is found in the UNO module in this chapter's source code files as SC09.sxw.
start example
 Global vSelChangeListener 'Must be global Global vSelChangeBroadCast 'Run this macro to start event intercepting Sub StartListeningToSelChangeEvents   Dim sPrefix$   Dim sService$   sPrefix = "sel_change_"   sService = "com.sun.star.view.XSelectionChangeListener"   REM to register for a selection change, you must register with the   REM current controller   vSelChangeBroadCast = ThisComponent.getCurrentController   'Create a listener to intercept the selection change events   vSelChangeListener = CreateUnoListener(sPrefix, sService)   'Register the listener to the document controller   vSelChangeBroadCast.addSelectionChangeListener(vSelChangeListener) End Sub 
end example
 

The behavior of the code in Listing 19 is annoying. Every time a new selection is made, the code is called and it opens a dialog on the screen. This interferes with selecting text. To remove the listener, use the code in Listing 20 .

Listing 20: StopListeningToSelChangeEvents is found in the UNO module in this chapter's source code files as SC09.sxw.
start example
 Sub StopListeningToSelChangeEvents   ' removes the listener   vSelChangeBroadCast.removeSelectionChangeListener(vSelChangeListener) End Sub 
end example
 
Tip  

Store a copy of the listener in a global variable. If you use any other type, it won't work.




OpenOffice.org Macros Explained
OpenOffice.org Macros Explained
ISBN: 1930919514
EAN: 2147483647
Year: 2004
Pages: 203

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net