Programmatic Assignment of Scripts to Events
Sometimes, you want to create a document programmatically, including form controls, and assigning certain scripts to certain events for those controls. In the userinterface, this is done by using the property browser. Programmatically, this is somewhat more difficult.
As an example, if you want to programmatically create a document containing radio buttons. When those radio buttons change their state (i.e. are selected), a certain Basic script should be called.
One possibility is to make use of the OnLoad event of the document as a whole. Using this event, you can create a listener of the desired type (in our sample case: com.sun.star.awt.XItemListener), and register it at the control in question.
This approach has three disadvantages: First, it is expensive. The scripting environment is loaded every time the document is loaded, which is too early. It should be loaded as late as possible, which is when the radio buttons really change their state.
Second, it is error prone. There are certain circumstances where Apache OpenOffice Basic listeners are automatically revoked, without the document being closed. In those cases, you need to manually reload the document, or re-run your OnLoad script for re-creating the listener.
Third, it is complex. You would, in your OnLoad initialization script, need to manually obtain the control in questions, which can involve a large amount of code.
A better solution is to use the event attacher manager mechanism described in Scripting and Events.
The following example creates a text document with three radio buttons, all three calling the same script when being selected.
REM ***** BASIC *****
Option Explicit
Sub Main
' create a new writer document
Dim oDocument as Object
Dim oEmptyArgs() as new com.sun.star.beans.PropertyValue
oDocument = StarDesktop.LoadComponentFromURL( "private:factory/swriter", "_blank", 0,
oEmptyArgs )
Erase oEmptyArgs
' create a new logical form
Dim oFormsCollection as Object
oFormsCollection = oDocument.DrawPage.Forms
Dim oSampleForm as Object
oSampleForm = createUnoService( "com.sun.star.form.component.DataForm" )
oFormsCollection.insertByName( "sample form", oSampleForm )
' create three radio buttons associated with three colors
Dim oControlShape as Object
Dim oControlModel as Object
' we want to add the equivalent of an com.sun.star.awt.XItemListener
Dim sListenerInterfaceName as String
sListenerInterfaceName = "com.sun.star.awt.XItemListener"
Dim sListenerMethodName as String
sListenerMethodName = "itemStateChanged"
' we want the onColorChange function in this module to be called
Dim sMacroLocation as String
sMacroLocation = "application:Standard.macro_assignment.onColorChange"
' note that this assumes that the module is called macro_assignment, and
' resides in the "Standard" library of the application-wide Basic macros
Dim sColors(2) as String
sColors(0) = "red"
sColors(1) = "green"
sColors(2) = "blue"
Dim i as Integer
For i = 0 To 2
' a shape
oControlShape = oDocument.createInstance( "com.sun.star.drawing.ControlShape" )
positionShape( oControlShape, 1000, 1000 + i * 800, 5000, 600 )
' a control model
oControlModel = createUnoService( "com.sun.star.form.component.RadioButton" )
oControlModel.Name = "colors"
oControlModel.Label = "make it " & UCase( sColors( i ) )
oControlModel.Tag = sColors( i )
oSampleForm.insertByIndex( i, oControlModel )
' knit both
oControlShape.Control = oControlModel
' yes, unfortunately the terminology is inconsistent here ...
' add the shape to the DrawPage
oDocument.DrawPage.add( oControlShape )
' bind a macro to the "stateChanged" event
Dim oEvent as new com.sun.star.script.ScriptEventDescriptor
oEvent.ListenerType = sListenerInterfaceName
oEvent.EventMethod = sListenerMethodName
oEvent.ScriptType = "StarBasic"
oEvent.ScriptCode = sMacroLocation
oSampleForm.registerScriptEvent( i, oEvent )
Next i
' switch the document (view) to alive mode
Dim oURL as new com.sun.star.util.URL
oURL.Complete = ".uno:SwitchControlDesignMode"
createUnoService( "com.sun.star.util.URLTransformer" ).parseStrict( oURL )
Dim oDispatcher as Object
oDispatcher = oDocument.CurrentController.Frame.queryDispatch( oURL, "", 63 )
oDispatcher.dispatch( oURL, oEmptyArgs() )
Erase oURL
' set the focus to the first control
oDocument.CurrentController.getControl( oSampleForm.getByIndex( 0 ) ).setFocus
End Sub
' this sets the size and position of a given shape
' Additionally, it anchors this shape at a paragraph
Sub positionShape( oShape as Object, X as Integer, Y as Integer, Width as Integer, Height as Integer )
oShape.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PARAGRAPH
' Not that this implies that you can use it for text documents only.
' The rest of the function also works for shapes in other documents
Dim oPos as new com.sun.star.awt.Point
oPos.X = X
oPos.Y = Y
oShape.setPosition( oPos )
Erase oPos
Dim oSize as new com.sun.star.awt.Size
oSize.Width = Width
oSize.Height = Height
oShape.setSize( oSize )
Erase oSize
End Sub
' This will be bound to the radio button's state changes
' At the moment, it simply changes their text color, but of course
' you could do more than this here ...
Sub onColorChange( oClickEvent as Object )
If ( oClickEvent.Selected > 0 ) Then
Dim nColor as Long
Select Case oClickEvent.Source.Model.Tag
Case "red"
nColor = CLng( "&HFF0000" )
case "green"
nColor = CLng( "&H00FF00" )
case "blue"
nColor = CLng( "&H0000FF" )
End Select
Dim oControlParent as Object
oControlParent = oClickEvent.Source.Model.Parent
Dim i as Integer
For i = 0 to oControlParent.getCount() - 1
oControlParent.getByIndex( i ).TextColor = nColor
Next i
End If
End Sub
Content on this page is licensed under the Public Documentation License (PDL). |