summaryrefslogtreecommitdiff
path: root/odk/examples/DevelopersGuide/Forms/ButtonOperator.java
blob: 75e10cbe4485fc68e2c0e74e6301acdb769ccd65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/*************************************************************************
 *
 *  $RCSfile: ButtonOperator.java,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-01-31 16:27:59 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  the BSD license.
 *
 *  Copyright (c) 2003 by Sun Microsystems, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *************************************************************************/

import com.sun.star.uno.*;
import com.sun.star.frame.*;
import com.sun.star.awt.*;
import com.sun.star.lang.*;
import com.sun.star.util.*;
import com.sun.star.container.*;
import com.sun.star.beans.*;
import com.sun.star.task.*;
import com.sun.star.sdbc.*;
import com.sun.star.sdbcx.*;
import com.sun.star.sdb.*;
import com.sun.star.form.*;

// java base stuff
import java.util.Vector;


/**************************************************************************/
/** a helper class for operating the buttons
*/
public class ButtonOperator implements XActionListener, XStatusListener
{
    private XComponentContext   m_xCtx;
    private DocumentHelper      m_aDocument;

    private Vector              m_aButtons;
    private Vector              m_aDispatchers;

    /* ------------------------------------------------------------------ */
    /** ctor
    */
    public ButtonOperator( XComponentContext xCtx, DocumentHelper aDocument )
    {
        m_xCtx = xCtx;
        m_aDocument = aDocument;
        m_aButtons = new Vector();
        m_aDispatchers = new Vector();
    }

    /* ------------------------------------------------------------------ */
    /** shows a message that we can't do several things due to an implementation error
    */
    private void showImplementationErrorMessage( XInterface xContext )
    {
        SQLException aBaseError = new SQLException(
            new String( "Due to a multi-threading issue, this method does not work correctly when invoked via remote java." ),
            xContext,
            new String( "S1000" ),
            0,
            null
        );
        SQLContext aError = new SQLContext(
            new String( "Unable to perform request." ),
            xContext,
            new String( "S1000" ),
            0,
            aBaseError,
            new String( "This functionallity has been disabled due to an implementation bug." )
        );

        try
        {
            // instantiate an interaction handler who can handle SQLExceptions
            XInteractionHandler xHandler = (XInteractionHandler)UnoRuntime.queryInterface(
                XInteractionHandler.class,
                m_xCtx.getServiceManager().createInstanceWithContext(
                    "com.sun.star.sdb.InteractionHandler", m_xCtx ) );

            // create a new request
            InteractionRequest aRequest = new InteractionRequest( aError );
            xHandler.handle( aRequest );
        }
        catch( com.sun.star.uno.Exception e )
        {
        }
    }

    /* ------------------------------------------------------------------ */
    /** reloads the form the given button belongs too
    */
    private void reload( Object aControlModel )
    {
        // this came from the reload button, so reload the form if the user wishes this ....
        com.sun.star.form.XLoadable xLoad = (com.sun.star.form.XLoadable)FLTools.getParent(
            aControlModel, com.sun.star.form.XLoadable.class );
        // (note that this xLoad equals our m_xMasterForm)

        // produce an error saying that we can't really do this
//      showImplementationErrorMessage( xLoad );

        // If you did neither your office nor your jave program fit with the
        // ForceSynchronous=1 parameter, the following line would result in a deadlock due
        // to an implementation bug.
        xLoad.reload();
    }

    /* ------------------------------------------------------------------ */
    private String getTag( Object aModel )
    {
        String sReturn = new String();
        try
        {
            XPropertySet xModelProps = UNO.queryPropertySet( aModel );
            sReturn = (String)xModelProps.getPropertyValue( "Tag" );
        }
        catch( com.sun.star.uno.Exception e )
        {
            // though this is a serious error, we're not interested in
        }
        return sReturn;
    }

    /* ------------------------------------------------------------------ */
    /** get's the button which we operate and which is responsible for a given URL
    */
    private int getButton( String sActionURL )
    {
        int nPos = -1;
        for ( int i=0; ( i < m_aButtons.size() ) && ( -1 == nPos ); ++i )
        {
            if ( sActionURL.equals( getTag( m_aButtons.elementAt( i ) ) ) )
                nPos = i;
        }
        return nPos;
    }

    /* ------------------------------------------------------------------ */
    /** announces a button which the operator should be responsible for
    */
    private int getButtonIndex( XPropertySet xButton )
    {
        int nPos = -1;
        for ( int i=0; ( i < m_aButtons.size() ) && ( -1 == nPos ); ++i )
        {
            if ( xButton.equals( m_aButtons.elementAt( i ) ) )
                nPos = i;
        }
        return nPos;
    }

    /* ------------------------------------------------------------------ */
    /** announces a button which the operator should be responsible for
    */
    public void addButton( XPropertySet xButtonModel, String sActionURL ) throws java.lang.Exception
    {
        // the current view to the document
        DocumentViewHelper aCurrentView = m_aDocument.getCurrentView();

        // add a listener so we get noticed if the user presses the button
        // get the control
        XButton xButtonControl = (XButton)UnoRuntime.queryInterface( XButton.class,
            aCurrentView.getControl( xButtonModel ) );

        xButtonControl.addActionListener( this );

        // remember the action URL
        xButtonModel.setPropertyValue( "Tag", sActionURL );
        // retrieve the dispatcher for the action URL
        XDispatch xActionDispatch = null;
        if ( 0 < sActionURL.length() )
        {
            // query the current document view for a dispatcher for the action URL
            URL[] aURL = new URL[] { new URL() };
            aURL[0].Complete = sActionURL;
            xActionDispatch = aCurrentView.getDispatcher( aURL );
            // and if we found one, add ourself as status listener so we get notified whenever something changes
            if ( null != xActionDispatch )
            {
                xActionDispatch.addStatusListener( this, aURL[0] );
            }
        }

        // remember the button and the dispatcher
        m_aButtons.add( xButtonModel );
        m_aDispatchers.add( xActionDispatch );
    }

    /* ------------------------------------------------------------------ */
    public void revokeButton( XPropertySet xButtonModel )
    {
        int nPos = getButtonIndex( xButtonModel );
        if ( -1 < nPos )
        {
            m_aButtons.remove( nPos );
            m_aDispatchers.remove( nPos );
        }
    }

    /* ------------------------------------------------------------------ */
    /** called when the status of an URL we operate on has changed
    */
    public void statusChanged( FeatureStateEvent aEvent ) throws com.sun.star.uno.RuntimeException
    {
        // get the button which is responsible for URL
        int nButtonPos = getButton( aEvent.FeatureURL.Complete );
        if ( -1 < nButtonPos )
        {
            XPropertySet xButton = (XPropertySet)m_aButtons.elementAt( nButtonPos );
            try
            {
                xButton.setPropertyValue( "Enabled", new Boolean( aEvent.IsEnabled ) );
            }
            catch( java.lang.Exception e )
            {
                System.out.println(e);
                e.printStackTrace();
            }
        }
    }

    /* ==================================================================
       = XActionListener
       ================================================================== */
    /* ------------------------------------------------------------------ */
    /* called when a button has been pressed
    */
    public void actionPerformed( ActionEvent aEvent ) throws com.sun.star.uno.RuntimeException
    {
        // get the model's name
        XNamed xModel = (XNamed)FLTools.getModel( aEvent.Source, XNamed.class );
        String sName = xModel.getName();

        if ( sName.equals( new String( "reload" ) ) )
            reload( xModel );
        else
        {
            // get the action URL the button is bound to
            String sActionURL = getTag( xModel );

            // get the dispatcher responsible for this action URL
            int nButtonPos = getButton( sActionURL );
            if ( -1 < nButtonPos )
            {
                XDispatch xDispatcher = (XDispatch)m_aDispatchers.elementAt( nButtonPos );
                if ( null != xDispatcher )
                {
                    PropertyValue[] aDummyArgs = new PropertyValue[] { };
                    try
                    {
                        xDispatcher.dispatch( FLTools.parseURL( sActionURL, m_xCtx ), aDummyArgs );
                    }
                    catch( java.lang.Exception e )
                    {
                    }
                }
            }

            // below is what we really would like to do - if we would not have these implementation
            // bugs
            // Though the current solution has one more advantage: we don't need to determine
            // the button state ourself. We are told by the form layer framework when the buttons
            // have to be enabled or disabled.
            // Once Issuezilla bug #TODO# is fixed (means we have a chance to reach for the form
            // controller from external components), we can get rid off the implementation specific
            // part of the URLs we use (this "#0/0" mark), and then we would have a working solution
            // which is not to be called hack .....

            // the result set to operate on
//          XResultSet xSet = (XResultSet)FLTools.getParent( xModel, XResultSet.class );
//
//          try
//          {
//              // this is what we would have liked to do
//              if ( sName.equals( new String( "first" ) ) )
//                  xSet.first();
//              else if ( sName.equals( new String( "prev" ) ) )
//                  xSet.previous();
//              else if ( sName.equals( new String( "next" ) ) )
//                  xSet.next();
//              else if ( sName.equals( new String( "last" ) ) )
//                  xSet.last();
//          }
//          catch( SQLException e )
//          {
//              System.err.println( e );
//              e.printStackTrace();
//          }
        }
    }

    /* ==================================================================
       = XEventListener
       ================================================================== */
    public void disposing( EventObject aEvent )
    {
        // not interested in
    }
};