API/Samples/Groovy/Office/RuntimeDialog

    From The Document Foundation Wiki
    < API‎ | Samples‎ | Groovy

    About the Runtime Dialog Groovy Example

    This is an example demonstrates creating a UNO Dialog and features use of XMultiPropertySet via a UNOCategory API helper. It based on the code in Documentation/DevGuide/Basic/Creating_Dialogs_at_Runtime.

    The Code

    import com.sun.star.awt.ActionEvent
    import com.sun.star.awt.XButton
    import com.sun.star.awt.XControl
    import com.sun.star.awt.XControlContainer
    import com.sun.star.awt.XControlModel
    import com.sun.star.awt.XDialog
    import com.sun.star.awt.XFixedText
    import com.sun.star.awt.XToolkit
    import com.sun.star.awt.XWindow
    
    import com.sun.star.beans.XMultiPropertySet
    import com.sun.star.beans.XPropertySet
    
    import com.sun.star.container.XNameContainer
    
    import com.sun.star.lang.EventObject
    import com.sun.star.lang.XComponent
    import com.sun.star.lang.XMultiComponentFactory
    import com.sun.star.lang.XMultiServiceFactory
    
    import com.sun.star.uno.UnoRuntime
    import com.sun.star.uno.XComponentContext
    import com.sun.star.awt.Rectangle
    import com.sun.star.awt.WindowAttribute
    import com.sun.star.awt.XThrobber
    import com.sun.star.awt.XProgressBar
    import com.sun.star.container.XIndexAccess
    
    // Groovy script
    
    /** method for creating a dialog at runtime */
    
    class UnoCategory {
        public static Object uno(Object unoObj, Class clazz) { UnoRuntime.queryInterface(clazz, unoObj) }
    
        public static Object getAt(XPropertySet pset, String pname) { pset.getPropertyValue(pname) }
    
        public static void putAt(XPropertySet pset, String pname, Object newValue)
        { pset.setPropertyValue(pname, newValue) }
    
        public static Object getAt(XIndexAccess ndx, int x) { ndx.getByIndex(x) }
    
        public static void setMultiPropertySet(Object unoObj, Map properties)
        {
            XMultiPropertySet pMSet = unoObj.uno(XMultiPropertySet)
    
            // Nasty hack to workaround problem when setting Height in the same setPropertyValues
            // call as other properties.
            // You also have to set Width after PositionX, fortunately the default for a map
            // literal in Groovy happens to be LinkedHashMap so the order of the keys is preserved.
            // If that weren't the case we'd have to deal with that here too.
            
            if ((properties.size() > 1) && properties.containsKey('Height')) {
                String[] propNames = ((properties.keySet() as List) - ['Height']) as String[]
                Object[] values = new Object[propNames.length]
    
                propNames.eachWithIndex { String n, int x -> values[x] = properties.get(n) }
    
                pMSet.setPropertyValues(propNames, values)
    
                // We use setProertyValues rather than setPropertyValue because it is probably
                // more performant than making the two UNO calls that would require.
                pMSet.setPropertyValues(['Height'] as String[], [properties.get('Height')] as Object[])
    
    //            System.out.println("setMultiPropertySet-Height $propNames $values ${properties.get('Height')} ")
            } else {
                String[] propNames = properties.keySet() as String[]
                Object[] values = new Object[propNames.length]
    
                propNames.eachWithIndex { String n, int x -> values[x] = properties.get(n) }
    
                pMSet.setPropertyValues(propNames, values)
    
    //            System.out.println("setMultiPropertySet $propNames $values ${pMSet instanceof XMultiPropertySet} ")
            }
        }
    
        public static XNameContainer leftShift(XNameContainer container, Map values)
        {
    //        System.out.println "leftShifting $values"
            values.each { name, value -> container.insertByName(name, value) }
            return container
        }
    }
    
    /** action listener */
    
    public class CountActionListenerImpl implements com.sun.star.awt.XActionListener
    {
        XFixedText label
        String labelPrefix
        XProgressBar progressBar
    
        private int _nCounts = 0;
    
        // XEventListener
        public void disposing(EventObject eventObject)
        {
    //        System.out.println('CountActionListener disposing.')
            label = null
            progressBar = null
        }
    
        // XActionListener
        public void actionPerformed(ActionEvent actionEvent)
        {
            System.out.println('CountActionListener actionPerformed.')
    
            // increase click counter
            _nCounts++;
    
            label.setText(labelPrefix + _nCounts);
    
            progressBar.value = (progressBar.value + 1) % 10
        }
    }
    
    public class CancelActionListenerImpl implements com.sun.star.awt.XActionListener
    {
        private XDialog dialog;
    
        // XEventListener
        public void disposing(EventObject eventObject)
        {
    //        System.out.println('CancelActionListener disposing.')
            dialog = null;
        }
    
        // XActionListener
        public void actionPerformed(ActionEvent actionEvent)
        {
            System.out.println('CancelActionListener ending execution.')
            dialog.endExecute()
        }
    }
    
    /**
     This method creates a UNO modal dialog, fills it in, and return the object (com.sun.star.awt.UnoControlDialog).
     It must be called in the context of a use(UNOCategory).
    */
    Object createDialog(XComponentContext _xComponentContext) throws com.sun.star.uno.Exception
    {
        final String _buttonName = 'Button1'
        final String _labelName = 'Label1'
        final String _labelPrefix = 'Counts : '
        final String _cancelButtonName = 'CancelButton1'
        final String _editName = 'Edit1'
        final String _throbberName = 'Throbber1'
    
        // get the service manager from the component context
        XMultiComponentFactory xMultiComponentFactory = _xComponentContext.getServiceManager();
    
        // create the dialog model and set the properties
        Object dialogModel = xMultiComponentFactory.createInstanceWithContext(
                "com.sun.star.awt.UnoControlDialogModel", _xComponentContext);
    
        // Can't set x/y and width/height at same time.
        // Just set width/height at let OOo pick the x/y.
        // This doesn't work to make dialog window resizable (it is moveable & closeable by default).
        dialogModel.multiPropertySet = [Width:150, Height:200, Title:'Runtime Dialog Demo'
            , Closeable: true, Moveable:true, Sizeable:true]
    
        // get the service manager from the dialog model
        XMultiServiceFactory xMultiServiceFactory = dialogModel.uno(XMultiServiceFactory)
    
        // create the button model and set the properties
        // This button gets the 0th TabIndex because it is the default button.
        // But just setting TabIndex doesn't seem to do the job for the default.
        // Apparently it is the first button added to the container.
        Object cancelButtonModel = xMultiServiceFactory.createInstance('com.sun.star.awt.UnoControlButtonModel')
    
        cancelButtonModel.multiPropertySet = [PositionX:90, PositionY:10, Width:50, Height:14
            , Name:_cancelButtonName, TabIndex:0, Label:"Cancel"]
    
        // create the button model and set the properties
        Object buttonModel = xMultiServiceFactory.createInstance('com.sun.star.awt.UnoControlButtonModel')
    
        buttonModel.multiPropertySet = [PositionX:10, PositionY:10, Width:50, Height:14
                , Name:_buttonName, TabIndex:1, Label:"Stop!"]
    
        // create the label model and set the properties
        Object labelModel = xMultiServiceFactory.createInstance('com.sun.star.awt.UnoControlFixedTextModel')
    
        labelModel.multiPropertySet = [PositionX:10, PositionY:30, Width:60, Height:14
            , Name:_labelName, TabIndex:3, Label:_labelPrefix]
    
        Object editModel = xMultiServiceFactory.createInstance('com.sun.star.awt.UnoControlEditModel')
    
        editModel.multiPropertySet = [PositionX:5, PositionY:45, Width:140, Height:150, Border:2 as Short /* Simple */
            , Name:_editName, TabIndex:2
            , HScroll:true, VScroll:true, MultiLine:true
            , LineEndFormat:2 as Short /* LINE_FEED */
            , Text:'This is some initial text.\nAnother line.\nFinis.']
    
        // create the label model and set the properties
        Object throbberModel = xMultiServiceFactory.createInstance('com.sun.star.awt.UnoControlProgressBarModel')
    
        throbberModel.multiPropertySet = [PositionX:80, PositionY:30, Width:60, Height:14
            , Name:_throbberName, TabIndex:4
            , ProgressValue:0, ProgressValueMin:0, ProgressValueMax:9]
    
        // insert the control models into the dialog model
        XNameContainer xNameCont = dialogModel.uno(XNameContainer)
    
        // Add the default button (Cancel) first.
        xNameCont.insertByName(_cancelButtonName, cancelButtonModel)
        xNameCont.insertByName(_buttonName, buttonModel)
        xNameCont.insertByName(_labelName, labelModel)
        xNameCont.insertByName(_editName, editModel)
        xNameCont.insertByName(_throbberName, throbberModel)
    
        // This is another way to use UnoCategory to do the above, but the syntax is a bit odd and adds some overhead.
    //    dialogModel.uno(XNameContainer) <<
    //        [(_buttonName):buttonModel, (_labelName):labelModel, (_cancelButtonName):cancelButtonModel]
    
        // create the dialog control and set the model
        Object dialog = xMultiComponentFactory.createInstanceWithContext(
                "com.sun.star.awt.UnoControlDialog", _xComponentContext);
    
        XControl xControl = dialog.uno(XControl)
    
        xControl.setModel(dialogModel.uno(XControlModel))
    
        XDialog xDialog = dialog.uno(XDialog)
    
        // add an action listener to the button control
        XControlContainer xControlCont = dialog.uno(XControlContainer)
    
        xControlCont.getControl(_buttonName).uno(XButton).addActionListener(
                new CountActionListenerImpl(label:xControlCont.getControl(_labelName).uno(XFixedText)
                        , labelPrefix:_labelPrefix
                        , progressBar:xControlCont.getControl(_throbberName).uno(XProgressBar)));
    
        xControlCont.getControl(_cancelButtonName).uno(XButton).addActionListener(
                new CancelActionListenerImpl(dialog:xDialog));
    
        // This doesn't seem to serve any purpose...
    //    XWindow xWindow = xControl.uno(XWindow)
    //
    //    xWindow.setVisible(false);
    
    //    This doesn't work to make dialog window resizable.
    //    Short flags = (WindowAttribute.BORDER | WindowAttribute.MOVEABLE
    //        | WindowAttribute.SIZEABLE | WindowAttribute.CLOSEABLE)
    //
    //    Rectangle posSize = xWindow.getPosSize()
    //
    //    xWindow.setPosSize(posSize.X, posSize.Y, posSize.Width, posSize.Height, flags)
    
        // create a peer
        Object toolkit = xMultiComponentFactory.createInstanceWithContext(
                "com.sun.star.awt.Toolkit", _xComponentContext);
    
        XToolkit xToolkit = toolkit.uno(XToolkit)
    
        xControl.createPeer(xToolkit, null);
    
        return dialog;
    }
    
    use (UnoCategory) {
        Object dialog = createDialog(XSCRIPTCONTEXT.componentContext)
    
        // execute the dialog, which won't return until it is closed.
        dialog.uno(XDialog).execute();
    
        System.out.println('xDialog.execute has returned!')
    
        // we can put it up there again if we like.
        dialog.uno(XDialog).execute();
    
        System.out.println('xDialog.execute has returned again!')
    
        // dispose the dialog
        dialog.uno(XComponent).dispose();
    }
    
    0

    Apache Feather Logo.svg

    This work is licensed under the Apache License version 2.0