1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 
35 import com.sun.star.uno.UnoRuntime;
36 import com.sun.star.uno.XComponentContext;
37 import com.sun.star.lang.XMultiComponentFactory;
38 import com.sun.star.beans.XPropertySet;
39 import com.sun.star.beans.PropertyValue;
40 import com.sun.star.lang.XMultiServiceFactory;
41 import com.sun.star.lang.XSingleServiceFactory;
42 import com.sun.star.util.XURLTransformer;
43 import com.sun.star.frame.XDesktop;
44 import com.sun.star.frame.XComponentLoader;
45 import com.sun.star.text.XTextDocument;
46 
47 /*
48  *
49  * @author  Carsten Driesner
50  * Provides example code how to enable/disable
51  * commands.
52  */
53 public class DisableCommandsTest extends java.lang.Object {
54 
55     /*
56      * A list of command names
57      */
58     final static private String[] aCommandURLTestSet =
59     {
60         new String( "Open" ),
61         new String( "About" ),
62         new String( "SelectAll" ),
63         new String( "Quit" ),
64     };
65 
66     private static XComponentContext xRemoteContext = null;
67     private static XMultiComponentFactory xRemoteServiceManager = null;
68     private static XURLTransformer xTransformer = null;
69     private static XMultiServiceFactory xConfigProvider = null;
70 
71     /*
72      * @param args the command line arguments
73      */
74     public static void main(String[] args) {
75 
76         try {
77             // get the remote office context. If necessary a new office
78             // process is started
79             xRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
80             System.out.println("Connected to a running office ...");
81             xRemoteServiceManager = xRemoteContext.getServiceManager();
82 
83             Object transformer = xRemoteServiceManager.createInstanceWithContext(
84                           "com.sun.star.util.URLTransformer", xRemoteContext );
85             xTransformer = (com.sun.star.util.XURLTransformer)
86                 UnoRuntime.queryInterface(com.sun.star.util.XURLTransformer.class,
87                                           transformer );
88 
89             Object configProvider = xRemoteServiceManager.createInstanceWithContext(
90                           "com.sun.star.configuration.ConfigurationProvider",
91                           xRemoteContext );
92             xConfigProvider = (com.sun.star.lang.XMultiServiceFactory)
93                 UnoRuntime.queryInterface(
94                     com.sun.star.lang.XMultiServiceFactory.class, configProvider );
95 
96             // create a new test document
97             Object oDesktop = xRemoteServiceManager.createInstanceWithContext(
98                 "com.sun.star.frame.Desktop", xRemoteContext);
99 
100             XComponentLoader xCompLoader =(XComponentLoader)
101                 UnoRuntime.queryInterface(XComponentLoader.class, oDesktop);
102 
103             com.sun.star.lang.XComponent xComponent =
104                 xCompLoader.loadComponentFromURL("private:factory/swriter",
105                     "_blank", 0, new com.sun.star.beans.PropertyValue[0]);
106             {
107             XTextDocument xDoc =(XTextDocument)
108                 UnoRuntime.queryInterface(XTextDocument.class, xComponent);
109             xDoc.getText().setString("You can now check the disabled commands. The "
110                                      +"following commands are disabled:\n\n"
111                                      +"   Open...\n   Exit\n   Select All\n   "
112                                      +"About StarOffice|OpenOffice\n\nPress "
113                                      + "\"return\" in the shell where you have "
114                                      + "started the example to enable the "
115                                      + "commands!\n\nCheck the commands again and "
116                                      + "press once more \"return\" to finish the "
117                                      + "example and close the document.");
118 
119             // ensure that the document content is optimal visible
120             com.sun.star.frame.XModel xModel =
121                 (com.sun.star.frame.XModel)UnoRuntime.queryInterface(
122                     com.sun.star.frame.XModel.class, xDoc);
123             // get the frame for later usage
124             com.sun.star.frame.XFrame xFrame =
125                 xModel.getCurrentController().getFrame();
126 
127             com.sun.star.view.XViewSettingsSupplier xViewSettings =
128                 (com.sun.star.view.XViewSettingsSupplier)UnoRuntime.queryInterface(
129                     com.sun.star.view.XViewSettingsSupplier.class,
130                     xModel.getCurrentController());
131             xViewSettings.getViewSettings().setPropertyValue(
132                 "ZoomType", new Short((short)0));
133             }
134             // test document will be closed later
135 
136             // First we need a defined starting point. So we have to remove
137             // all commands from the disabled set!
138             enableCommands();
139 
140             // Check if the commands are usable
141             testCommands( false );
142 
143             // Disable the commands
144             disableCommands();
145 
146             // Now the commands shouldn't be usable anymore
147             testCommands( true );
148 
149             // you can now check the test document and see which commands are
150             // disabled
151             System.out.println("\nYou can now check the disabled commands.\n"
152                                +"Please press 'return' to enable the commands!");
153             waitForUserInput();
154 
155             // Remove disable commands to make Office usable again
156             enableCommands();
157 
158             // you can check the test document again and see that the commands
159             // are enabled now
160             System.out.println("Check again the now enabled commands.\n"
161                                +"Please press 'return' to finish the example and "
162                                +"close the document!");
163             waitForUserInput();
164 
165             // close test document
166             com.sun.star.util.XCloseable xCloseable = (com.sun.star.util.XCloseable)
167                 UnoRuntime.queryInterface(com.sun.star.util.XCloseable.class,
168                                           xComponent );
169 
170             if (xCloseable != null ) {
171                 xCloseable.close(false);
172             } else
173             {
174                 xComponent.dispose();
175             }
176         }
177         catch (java.lang.Exception e){
178             e.printStackTrace();
179         }
180         finally {
181             System.exit(0);
182         }
183     }
184 
185     /**
186      * Wait for user input -> until the user press 'return'
187      */
188     private static void waitForUserInput() throws java.io.IOException {
189 
190         java.io.BufferedReader reader
191             = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
192 
193         reader.read();
194     }
195 
196     /**
197      * Test the commands that we enabled/disabled
198      */
199     private static void testCommands( boolean bDisabledCmds )
200         throws com.sun.star.uno.Exception
201     {
202         // We need the desktop to get access to the current frame
203         Object desktop = xRemoteServiceManager.createInstanceWithContext(
204 		                    "com.sun.star.frame.Desktop", xRemoteContext );
205         com.sun.star.frame.XDesktop xDesktop = (com.sun.star.frame.XDesktop)
206             UnoRuntime.queryInterface(com.sun.star.frame.XDesktop.class, desktop );
207         com.sun.star.frame.XFrame xFrame = xDesktop.getCurrentFrame();
208         com.sun.star.frame.XDispatchProvider xDispatchProvider = null;
209         if ( xFrame != null )
210         {
211             // We have a frame. Now we need access to the dispatch provider.
212             xDispatchProvider =
213                 (com.sun.star.frame.XDispatchProvider)UnoRuntime.queryInterface(
214 	                com.sun.star.frame.XDispatchProvider.class, xFrame );
215             if ( xDispatchProvider != null )
216             {
217                 // As we have the dispatch provider we can now check if we get
218                 // a dispatch object or not.
219                 for ( int n = 0; n < aCommandURLTestSet.length; n++ )
220                 {
221                     // Prepare the URL
222                     com.sun.star.util.URL[] aURL  = new com.sun.star.util.URL[1];
223                     aURL[0] = new com.sun.star.util.URL();
224                     com.sun.star.frame.XDispatch xDispatch = null;
225 
226                     aURL[0].Complete = ".uno:" + aCommandURLTestSet[n];
227                     xTransformer.parseSmart( aURL, ".uno:" );
228 
229                     // Try to get a dispatch object for our URL
230                     xDispatch = xDispatchProvider.queryDispatch( aURL[0], "", 0 );
231 
232                     if ( xDispatch != null )
233                     {
234                         if ( bDisabledCmds )
235                             System.out.println(
236                                 "Something is wrong, I got dispatch object for "
237                                 + aURL[0].Complete );
238                         else
239                             System.out.println( "Ok, dispatch object for "
240                                                 + aURL[0].Complete  );
241                     }
242                     else
243                     {
244                         if ( !bDisabledCmds )
245                             System.out.println("Something is wrong, I cannot get dispatch object for " + aURL[0].Complete );
246                         else
247                             System.out.println( "Ok, no dispatch object for "
248                                                 + aURL[0].Complete );
249                     }
250                     resetURL( aURL[0] );
251                 }
252             }
253             else
254                 System.out.println( "Couldn't get XDispatchProvider from Frame!" );
255         }
256         else
257             System.out.println( "Couldn't get current Frame from Desktop!" );
258     }
259 
260     /**
261      * Ensure that there are no disabled commands in the user layer. The
262      * implementation removes all commands from the disabled set!
263      */
264     private static void enableCommands() {
265         // Set the root path for our configuration access
266         com.sun.star.beans.PropertyValue[] lParams =
267             new com.sun.star.beans.PropertyValue[1];
268 
269         lParams[0] = new com.sun.star.beans.PropertyValue();
270         lParams[0].Name  = new String("nodepath");
271         lParams[0].Value = "/org.openoffice.Office.Commands/Execute/Disabled";
272 
273         try {
274             // Create configuration update access to have write access to the
275             // configuration
276             Object xAccess = xConfigProvider.createInstanceWithArguments(
277                              "com.sun.star.configuration.ConfigurationUpdateAccess",
278                              lParams );
279 
280             com.sun.star.container.XNameAccess xNameAccess =
281                 (com.sun.star.container.XNameAccess)UnoRuntime.queryInterface(
282                     com.sun.star.container.XNameAccess.class, xAccess );
283 
284             if ( xNameAccess != null ) {
285                 // We need the XNameContainer interface to remove the nodes by name
286                 com.sun.star.container.XNameContainer xNameContainer =
287                     (com.sun.star.container.XNameContainer)
288                     UnoRuntime.queryInterface(
289                         com.sun.star.container.XNameContainer.class, xAccess );
290 
291                 // Retrieves the names of all Disabled nodes
292                 String[] aCommandsSeq = xNameAccess.getElementNames();
293                 for ( int n = 0; n < aCommandsSeq.length; n++ ) {
294                     try {
295                         // remove the node
296                         xNameContainer.removeByName( aCommandsSeq[n] );
297                     }
298                     catch ( com.sun.star.lang.WrappedTargetException e ) {
299                     }
300                     catch ( com.sun.star.container.NoSuchElementException e ) {
301                     }
302                 }
303             }
304 
305             // Commit our changes
306             com.sun.star.util.XChangesBatch xFlush =
307                 (com.sun.star.util.XChangesBatch)UnoRuntime.queryInterface(
308                     com.sun.star.util.XChangesBatch.class, xAccess);
309 
310             xFlush.commitChanges();
311         }
312         catch ( com.sun.star.uno.Exception e ) {
313             System.out.println( "Exception detected!" );
314             System.out.println( e );
315         }
316     }
317 
318     /**
319      * Disable all commands defined in the aCommandURLTestSet array
320      */
321     private static void disableCommands() {
322         // Set the root path for our configuration access
323         com.sun.star.beans.PropertyValue[] lParams =
324             new com.sun.star.beans.PropertyValue[1];
325 
326         lParams[0] = new com.sun.star.beans.PropertyValue();
327         lParams[0].Name  = new String("nodepath");
328         lParams[0].Value = "/org.openoffice.Office.Commands/Execute/Disabled";
329 
330         try {
331             // Create configuration update access to have write access to the
332             // configuration
333             Object xAccess = xConfigProvider.createInstanceWithArguments(
334                              "com.sun.star.configuration.ConfigurationUpdateAccess",
335                              lParams );
336 
337             com.sun.star.lang.XSingleServiceFactory xSetElementFactory =
338                 (com.sun.star.lang.XSingleServiceFactory)UnoRuntime.queryInterface(
339                     com.sun.star.lang.XSingleServiceFactory.class, xAccess );
340 
341             com.sun.star.container.XNameContainer xNameContainer =
342                 (com.sun.star.container.XNameContainer)UnoRuntime.queryInterface(
343                     com.sun.star.container.XNameContainer.class, xAccess );
344 
345             if ( xSetElementFactory != null && xNameContainer != null ) {
346                 Object[] aArgs = new Object[0];
347 
348                 for ( int i = 0; i < aCommandURLTestSet.length; i++ ) {
349                     // Create the nodes with the XSingleServiceFactory of the
350                     // configuration
351                     Object xNewElement =
352                         xSetElementFactory.createInstanceWithArguments( aArgs );
353 
354                     if ( xNewElement != null ) {
355                         // We have a new node. To set the properties of the node
356                         // we need the XPropertySet interface.
357                         com.sun.star.beans.XPropertySet xPropertySet =
358                             (com.sun.star.beans.XPropertySet)
359                             UnoRuntime.queryInterface(
360                                 com.sun.star.beans.XPropertySet.class,
361                                 xNewElement );
362 
363                         if ( xPropertySet != null ) {
364                             // Create a unique node name.
365                             String aCmdNodeName = new String( "Command-" );
366                             aCmdNodeName += i;
367 
368                             // Insert the node into the Disabled set
369                             xPropertySet.setPropertyValue( "Command",
370                                                            aCommandURLTestSet[i] );
371                             xNameContainer.insertByName( aCmdNodeName,
372                                                          xNewElement );
373                         }
374                     }
375                 }
376 
377                 // Commit our changes
378                 com.sun.star.util.XChangesBatch xFlush =
379                     (com.sun.star.util.XChangesBatch)UnoRuntime.queryInterface(
380                         com.sun.star.util.XChangesBatch.class, xAccess);
381                 xFlush.commitChanges();
382             }
383         }
384         catch ( com.sun.star.uno.Exception e )
385         {
386             System.err.println( "Exception detected!" + e);
387             e.printStackTrace();
388         }
389     }
390 
391     /**
392      * reset URL so it can be reused
393 	 *
394      * @param aURL
395      *          the URL that should be reseted
396      */
397     private static void resetURL( com.sun.star.util.URL aURL )
398     {
399         aURL.Protocol   = "";
400         aURL.User       = "";
401         aURL.Password   = "";
402         aURL.Server     = "";
403         aURL.Port       = 0;
404         aURL.Path       = "";
405         aURL.Name       = "";
406         aURL.Arguments  = "";
407         aURL.Mark       = "";
408         aURL.Main       = "";
409         aURL.Complete   = "";
410     }
411 }
412