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.
|When you try the following code, you may need to adjust the location of the script being called. At the moment, it assumes a module name macro_assignment in the application-wide library named Standard.|
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).|