merge the formfield patch from ooo-build
[ooovba.git] / odk / examples / DevelopersGuide / Config / ConfigExamples.java
blob90172c51893999d6bf655f392df69546a5113c67
1 /*************************************************************************
3 * $RCSfile: ConfigExamples.java,v $
5 * $Revision: 1.6 $
7 * last change: $Author: obo $ $Date: 2005-03-18 10:38:48 $
9 * The Contents of this file are made available subject to the terms of
10 * the BSD license.
12 * Copyright (c) 2003 by Sun Microsystems, Inc.
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *************************************************************************/
41 // Import everything we use
43 import com.sun.star.beans.XPropertySet;
44 import com.sun.star.beans.XMultiPropertySet;
45 import com.sun.star.beans.XHierarchicalPropertySet;
46 import com.sun.star.beans.XMultiHierarchicalPropertySet;
47 import com.sun.star.beans.XPropertyState;
48 import com.sun.star.beans.XMultiPropertyStates;
50 import com.sun.star.bridge.XUnoUrlResolver;
52 import com.sun.star.configuration.XTemplateInstance;
54 import com.sun.star.container.XNameAccess;
55 import com.sun.star.container.XNameReplace;
56 import com.sun.star.container.XNameContainer;
57 import com.sun.star.container.XNamed;
58 import com.sun.star.container.XChild;
59 import com.sun.star.container.XHierarchicalNameAccess;
60 import com.sun.star.container.XHierarchicalName;
62 import com.sun.star.lang.XComponent;
63 import com.sun.star.lang.XMultiComponentFactory;
64 import com.sun.star.lang.XSingleServiceFactory;
65 import com.sun.star.lang.XMultiServiceFactory;
66 import com.sun.star.lang.XMultiComponentFactory;
67 import com.sun.star.lang.XServiceInfo;
68 import com.sun.star.lang.EventObject;
70 import com.sun.star.uno.UnoRuntime;
71 import com.sun.star.uno.XComponentContext;
72 import com.sun.star.uno.XInterface;
73 import com.sun.star.uno.XNamingService;
74 import com.sun.star.uno.AnyConverter;
76 import com.sun.star.util.XChangesBatch;
77 import com.sun.star.util.XChangesNotifier;
78 import com.sun.star.util.XChangesListener;
79 import com.sun.star.util.ChangesEvent;
80 /** Config examples
81 @author Joerg Barfurth
84 /* These examples show how to use the following features of the Config API:
86 o Accessing data
87 o Updating data synchronously and asynchronously
88 o Updating properties in groups
89 o Adding and removing items in sets
90 o Resetting data to their defaults
92 Each example is in a separate method call.
93 */
94 public class ConfigExamples
96 // The ComponentContext interface of the remote component context
97 private XComponentContext mxContext = null;
99 // The MultiComponentFactory interface of the ServiceManager
100 private XMultiComponentFactory mxServiceManager = null;
102 // The MultiServiceFactory interface of the ConfigurationProvider
103 private XMultiServiceFactory mxProvider = null;
105 public static void main( String args[] )
107 try {
108 // get the remote office component context
109 com.sun.star.uno.XComponentContext xContext =
110 com.sun.star.comp.helper.Bootstrap.bootstrap();
112 if( xContext != null )
113 System.out.println("Connected to a running office ...");
114 else
115 System.out.println( "ERROR: Cannot connect - no remote component context available." );
117 // Create an instance of the class and call it's run method
118 ConfigExamples aExample = new ConfigExamples(xContext);
119 aExample.run( );
121 // if you own the service manager dispose it here
122 // to ensure that the default provider is properly disposed and flushed
123 System.exit(0);
125 catch( Exception e )
127 e.printStackTrace();
128 System.exit(-1);
132 /** Create a ConfigExamples instance supplying a service factory
134 public ConfigExamples(XComponentContext xContext)
136 mxContext = xContext;
137 mxServiceManager = xContext.getServiceManager();
140 /** Run the examples with a default ConfigurationProvider
142 public void run()
143 throws com.sun.star.uno.Exception
145 mxProvider = createProvider();
147 runExamples( );
149 // we are using the default ConfigurationProvider, so we must not dispose it
150 mxProvider = null;
153 /** Run the examples with an AdministrationProvider
155 public void runForAdmin(Object [] aAdminArgs)
156 throws com.sun.star.uno.Exception
158 mxProvider = createAdminProvider(aAdminArgs);
160 runExamples( );
162 // this is not the default ConfigurationProvider, so we can dispose it
163 ((XComponent)UnoRuntime.queryInterface( XComponent.class, mxProvider )).dispose();
164 mxProvider = null;
167 /** Run the examples with a given ConfigurationProvider
169 public void runExamples( )
171 if (checkProvider(mxProvider))
173 System.out.println("\nStarting examples.");
175 readDataExample();
177 browseDataExample();
179 updateGroupSyncExample();
181 resetGroupExample();
183 updateSetAsyncExample();
185 System.out.println("\nAll Examples completed.");
187 else
188 System.out.println("ERROR: Cannot run examples without ConfigurationProvider.");
192 /** Do some simple checks, if tehre is a valid ConfigurationProvider
194 public static boolean checkProvider(XMultiServiceFactory xProvider)
196 // check the provider we have
197 if (xProvider == null)
199 System.out.println("No provider available. Cannot access configuration data.");
200 return false;
206 // check the provider implementation
207 XServiceInfo xProviderServices =
208 (XServiceInfo) UnoRuntime.queryInterface( XServiceInfo.class, xProvider );
210 if (xProviderServices == null ||
211 !xProviderServices.supportsService("com.sun.star.configuration.ConfigurationProvider"))
213 System.out.println("WARNING: The provider is not a com.sun.star.configuration.ConfigurationProvider");
216 if (xProviderServices != null)
218 System.out.println("Using provider implementation: " + xProviderServices.getImplementationName());
221 return true;
223 catch (com.sun.star.uno.RuntimeException e)
225 System.err.println("ERROR: Failure while checking the provider services.");
226 e.printStackTrace();
227 return false;
231 /** Get the provider we have
233 public XMultiServiceFactory getProvider( )
235 return mxProvider;
238 /** Create a default configuration provider
240 public XMultiServiceFactory createProvider( )
241 throws com.sun.star.uno.Exception
243 final String sProviderService = "com.sun.star.configuration.ConfigurationProvider";
245 // create the provider and return it as a XMultiServiceFactory
246 XMultiServiceFactory xProvider = (XMultiServiceFactory)
247 UnoRuntime.queryInterface(XMultiServiceFactory.class,
248 mxServiceManager.createInstanceWithContext(sProviderService,
249 mxContext));
251 return xProvider;
254 /** Create an administration provider
256 @param aAdminArguments
257 An array of extra arguments to be used to create the provider
259 public XMultiServiceFactory createAdminProvider(Object[] aAdminArguments)
260 throws com.sun.star.uno.Exception
262 final String sAdminService = "com.sun.star.configuration.AdministrationProvider";
264 // create the provider and remember it as a XMultiServiceFactory
265 XMultiServiceFactory xAdminProvider = (XMultiServiceFactory)
266 UnoRuntime.queryInterface(XMultiServiceFactory.class,
267 mxServiceManager.createInstanceWithArgumentsAndContext(
268 sAdminService, aAdminArguments, mxContext));
270 return xAdminProvider;
273 /** Create a specified read-only configuration view
275 public Object createConfigurationView( String sPath )
276 throws com.sun.star.uno.Exception
278 XMultiServiceFactory xProvider = getProvider();
280 // The service name: Need only read access:
281 final String sReadOnlyView = "com.sun.star.configuration.ConfigurationAccess";
283 // creation arguments: nodepath
284 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
285 aPathArgument.Name = "nodepath";
286 aPathArgument.Value = sPath;
288 Object[] aArguments = new Object[1];
289 aArguments[0] = aPathArgument;
291 // create the view
292 Object xViewRoot = xProvider.createInstanceWithArguments(sReadOnlyView, aArguments);
294 return xViewRoot;
297 /** Create a specified updatable configuration view using default synchronicity
299 Object createUpdatableView( String sPath )
300 throws com.sun.star.uno.Exception
302 XMultiServiceFactory xProvider = getProvider();
304 // The service name: Need update access:
305 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
307 // creation arguments: nodepath
308 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
309 aPathArgument.Name = "nodepath";
310 aPathArgument.Value = sPath;
312 Object[] aArguments = new Object[1];
313 aArguments[0] = aPathArgument;
315 // create the view
316 Object xViewRoot = xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
318 return xViewRoot;
321 /** Create a specified updatable configuration view
323 Object createUpdatableView( String sPath, boolean bAsync )
324 throws com.sun.star.uno.Exception
326 XMultiServiceFactory xProvider = getProvider();
328 // The service name: Need update access:
329 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
331 // creation arguments: nodepath
332 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
333 aPathArgument.Name = "nodepath";
334 aPathArgument.Value = sPath;
336 // creation arguments: commit mode - write-through or write-back
337 com.sun.star.beans.PropertyValue aModeArgument = new com.sun.star.beans.PropertyValue();
338 aModeArgument.Name = "lazywrite";
339 aModeArgument.Value = new Boolean(bAsync);
341 Object[] aArguments = new Object[2];
342 aArguments[0] = aPathArgument;
343 aArguments[1] = aModeArgument;
345 // create the view
346 Object xViewRoot = xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
348 return xViewRoot;
351 /** This method demonstrates read access to data
353 protected void readDataExample ()
357 System.out.println("\n--- starting example: read grid option settings --------------------");
358 Object aData = readGridConfiguration( );
359 System.out.println("Read grid options: " + aData);
362 catch ( Exception e )
364 e.printStackTrace();
368 /** This method demonstrates browsing access to data
370 protected void browseDataExample ()
374 System.out.println("\n--- starting example: browse filter configuration ------------------");
375 printRegisteredFilters( );
377 catch ( Exception e )
379 e.printStackTrace();
383 /** This method demonstrates synchronous update access to group data
385 protected void updateGroupSyncExample ()
389 System.out.println("\n--- starting example: update group data synchronously --------------");
390 editGridOptions( );
392 catch ( Exception e )
394 e.printStackTrace();
398 /** This method demonstrates resetting data to its default state
400 protected void resetGroupExample ()
404 System.out.println("\n--- starting example: reset group data -----------------------------");
405 Object aOldData = readGridConfiguration( );
406 resetGridConfiguration( );
407 Object aNewData = readGridConfiguration( );
408 System.out.println("Before reset: user grid options: " + aOldData);
409 System.out.println("After reset: default grid options: " + aNewData);
411 catch ( Exception e )
413 e.printStackTrace();
417 /** This method demonstrates asynchronous update access to set data
419 protected void updateSetAsyncExample ()
423 System.out.println("\n--- starting example: update set data asynchronously ---------------");
424 storeSampleDataSource( );
426 catch ( Exception e )
428 e.printStackTrace();
432 // READ example
433 /// class to hold information about grid settings
434 public static class GridOptions
436 public boolean visible;
437 public int resolution_x;
438 public int resolution_y;
439 public int subdivision_x;
440 public int subdivision_y;
442 public String toString() {
443 StringBuffer aBuffer = new StringBuffer();
444 aBuffer.append("[ Grid is "); aBuffer.append(visible ? "VISIBLE" : "HIDDEN");
445 aBuffer.append("; resolution = (" + resolution_x + "," + resolution_y + ")");
446 aBuffer.append("; subdivision = (" + subdivision_x + "," + subdivision_y + ")");
447 aBuffer.append(" ]");
448 return aBuffer.toString();
452 /// This method reads information about grid settings
453 protected GridOptions readGridConfiguration()
454 throws com.sun.star.uno.Exception
456 // The path to the root element
457 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
459 // create the view
460 Object xViewRoot = createConfigurationView(cGridOptionsPath);
462 // the result structure
463 GridOptions options = new GridOptions();
465 // accessing a single nested value
466 XHierarchicalPropertySet xProperties =
467 (XHierarchicalPropertySet)UnoRuntime.queryInterface(XHierarchicalPropertySet.class, xViewRoot);
469 Object aVisible = xProperties.getHierarchicalPropertyValue("Option/VisibleGrid");
470 options.visible = ((Boolean) aVisible).booleanValue();
472 // accessing a nested object and its subproperties
473 Object xSubdivision = xProperties.getHierarchicalPropertyValue("Subdivision");
475 XMultiPropertySet xSubdivProperties =
476 (XMultiPropertySet)UnoRuntime.queryInterface(XMultiPropertySet.class, xSubdivision);
478 // variables for multi-element access
479 String[] aElementNames = new String[2];
481 aElementNames[0] = "XAxis";
482 aElementNames[1] = "YAxis";
484 Object[] aElementValues = xSubdivProperties.getPropertyValues(aElementNames);
486 options.subdivision_x = ((Integer) aElementValues[0]).intValue();
487 options.subdivision_y = ((Integer) aElementValues[1]).intValue();
489 // accessing deeply nested subproperties
490 Object xResolution = xProperties.getHierarchicalPropertyValue("Resolution");
492 XMultiHierarchicalPropertySet xResolutionProperties =
493 (XMultiHierarchicalPropertySet)
494 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xResolution);
496 aElementNames[0] = "XAxis/Metric";
497 aElementNames[1] = "YAxis/Metric";
499 aElementValues = xResolutionProperties.getHierarchicalPropertyValues(aElementNames);
501 options.resolution_x = ((Integer) aElementValues[0]).intValue();
502 options.resolution_y = ((Integer) aElementValues[1]).intValue();
504 // all options have been retrieved - clean up and return
505 // we are done with the view - dispose it
507 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
509 return options;
512 // BROWSE example
513 /// Interface to procees information when browsing the configuration tree
514 public static interface IConfigurationProcessor
516 /// process a value item
517 public abstract void processValueElement( String sPath_, Object aValue_ );
518 /// process a structural item
519 public abstract void processStructuralElement( String sPath_, XInterface xElement_);
522 /// Internal method to recursively browse a structural element in preorder
523 public void browseElementRecursively( XInterface xElement, IConfigurationProcessor aProcessor )
524 throws com.sun.star.uno.Exception
526 // First process this as an element (preorder traversal)
527 XHierarchicalName xElementPath =
528 (XHierarchicalName) UnoRuntime.queryInterface(XHierarchicalName.class, xElement);
530 String sPath = xElementPath.getHierarchicalName();
532 aProcessor.processStructuralElement( sPath, xElement);
534 // now process this as a container
535 XNameAccess xChildAccess =
536 (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, xElement);
538 // get a list of child elements
539 String[] aElementNames = xChildAccess.getElementNames();
541 // and process them one by one
542 for(int i=0; i< aElementNames.length; ++i)
544 Object aChild = xChildAccess.getByName( aElementNames[i] );
545 AnyConverter aAnyConv = new AnyConverter();
546 // is it a structural element (object) ...
547 if ( aAnyConv.isObject(aChild) && !aAnyConv.isArray(aChild) )
549 // then get an interface
550 XInterface xChildElement = (XInterface)UnoRuntime.queryInterface(XInterface.class, aChild);
552 // and continue processing child elements recursively
553 browseElementRecursively( xChildElement, aProcessor );
555 // ... or is it a simple value
556 else
558 // Build the path to it from the path of
559 // the element and the name of the child
560 String sChildPath;
561 sChildPath =
562 xElementPath.composeHierarchicalName(aElementNames[i]);
564 // and process the value
565 aProcessor.processValueElement( sChildPath, aChild );
570 /** Method to browse the part rooted at sRootPath
571 of the configuration that the Provider provides.
573 All nodes will be processed by the IConfigurationProcessor passed.
575 public void browseConfiguration( String sRootPath, IConfigurationProcessor aProcessor )
576 throws com.sun.star.uno.Exception
578 // create the root element
579 XInterface xViewRoot = (XInterface)createConfigurationView( sRootPath );
581 // now do the processing
582 browseElementRecursively( xViewRoot, aProcessor );
584 // we are done with the view - dispose it
585 // This assumes that the processor
586 // does not keep a reference to the elements in processStructuralElement
588 ((XComponent) UnoRuntime.queryInterface(XComponent.class,xViewRoot)).dispose();
589 xViewRoot = null;
592 /** Method to browse the filter configuration.
594 Information about installed filters will be printed.
596 public void printRegisteredFilters()
597 throws com.sun.star.uno.Exception
599 final String sProviderService = "com.sun.star.configuration.ConfigurationProvider";
600 final String sFilterKey = "/org.openoffice.TypeDetection.Filter/Filters";
602 // browse the configuration, dumping filter information
603 browseConfiguration( sFilterKey,
604 new IConfigurationProcessor () {
605 /// prints Path and Value of properties
606 public void processValueElement( String sPath_, Object aValue_ ) {
607 if (new AnyConverter().isArray(aValue_))
609 final Object [] aArray = (Object [])aValue_;
611 System.out.print("\tValue: " + sPath_ + " = { ");
612 for (int i=0; i<aArray.length; ++i)
614 if (i != 0) System.out.print(", ");
615 System.out.print(aArray[i]);
617 System.out.println(" }");
619 else
620 System.out.println("\tValue: " + sPath_ + " = " + aValue_);
623 /// prints the Filter entries
624 public void processStructuralElement( String sPath_, XInterface xElement_) {
625 // get template information, to detect instances of the 'Filter' template
626 XTemplateInstance xInstance =
627 ( XTemplateInstance )UnoRuntime.queryInterface( XTemplateInstance .class,xElement_);
629 // only select the Filter entries
630 if (xInstance != null && xInstance.getTemplateName().endsWith("Filter")) {
631 XNamed xNamed = (XNamed)UnoRuntime.queryInterface(XNamed.class,xElement_);
632 System.out.println("Filter " + xNamed.getName() + " (" + sPath_ + ")");
635 } );
638 // GROUP UPDATE example
640 /** This method simulates editing configuration data using a GridEditor dialog class
642 public void editGridOptions( )
643 throws com.sun.star.uno.Exception
645 // The path to the root element
646 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
648 // create the SYNCHRONOUS view for better error handling
649 Object xViewRoot = createUpdatableView( cGridOptionsPath, false);
651 // the 'editor'
652 GridOptionsEditor dialog = new GridOptionsEditor();
654 // set up the initial values and register listeners
655 // get a data access interface, to supply the view with a model
656 XMultiHierarchicalPropertySet xProperties =
657 (XMultiHierarchicalPropertySet)
658 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xViewRoot);
660 dialog.setModel( xProperties );
662 // get a listener object (probably an adapter) that notifies
663 // the dialog of external changes to its model
664 XChangesListener xListener = dialog.createChangesListener( );
666 XChangesNotifier xNotifier =
667 (XChangesNotifier)UnoRuntime.queryInterface(XChangesNotifier.class, xViewRoot);
669 xNotifier.addChangesListener( xListener );
671 // trigger the listener
672 changeSomeData( cGridOptionsPath + "/Subdivision" );
674 if (dialog.execute() == GridOptionsEditor.SAVE_SETTINGS)
676 // changes have been applied to the view here
677 XChangesBatch xUpdateControl =
678 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
682 xUpdateControl.commitChanges();
684 catch (Exception e)
686 dialog.informUserOfError( e );
690 // all changes have been handled - clean up and return
691 // listener is done now
692 xNotifier.removeChangesListener( xListener );
694 // we are done with the view - dispose it
695 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
698 /** A class that changes some grid options settings
700 The interface of this class is chose to resemble a possible UI dialog class
702 private class GridOptionsEditor {
703 /// the data this editor edits
704 XMultiHierarchicalPropertySet mxModel;
706 public static final int CANCELED = 0;
707 public static final int SAVE_SETTINGS = 1;
709 // sets a model and updates the display
710 public void setModel(XMultiHierarchicalPropertySet xModel) {
711 mxModel = xModel;
712 updateDisplay();
715 // this method 'runs' the 'dialog'
716 public int execute() {
719 System.out.println("-- GridEditor executing --");
720 // simulate a user action changing some data
721 toggleVisibility();
722 System.out.println("-- GridEditor done --");
723 return SAVE_SETTINGS;
725 catch (Exception e)
727 informUserOfError(e);
728 return CANCELED;
732 /// this method is called to report an error during dialog execution to the zuser
733 public void informUserOfError(Exception e) {
734 System.err.println("ERROR in GridEditor:");
735 e.printStackTrace();
738 /// this method is called to allow the dialog to get feedback about changes occurring elsewhere
739 public XChangesListener createChangesListener() {
740 if (mxModel == null) return null;
742 return (new XChangesListener () {
743 public void changesOccurred( ChangesEvent event ) {
744 System.out.println("GridEditor - Listener received changes event containing " +
745 event.Changes.length + " change(s).");
746 updateDisplay();
749 public void disposing(EventObject event) {
750 System.out.println("GridEditor - Listener received disposed event: releasing model");
751 setModel(null);
755 /// this method is called when data has changed to display the updated data
756 private void updateDisplay() {
757 if (mxModel != null)
758 System.out.println("Grid options editor: data=" + readModel());
759 else
760 System.out.println("Grid options editor: no model set");
763 // this method is used to read all relevant data from the model
764 private GridOptions readModel()
768 String [] aOptionNames = new String [5];
769 aOptionNames[0] = "Option/VisibleGrid";
770 aOptionNames[1] = "Subdivision/XAxis";
771 aOptionNames[2] = "Subdivision/YAxis";
772 aOptionNames[3] = "Resolution/XAxis/Metric";
773 aOptionNames[4] = "Resolution/YAxis/Metric";
775 Object [] aValues = mxModel.getHierarchicalPropertyValues(aOptionNames);
777 GridOptions result = new GridOptions();
778 result.visible = ((Boolean)aValues[0]).booleanValue();
779 result.subdivision_x = ((Integer)aValues[1]).intValue();
780 result.subdivision_y = ((Integer)aValues[2]).intValue();
781 result.resolution_x = ((Integer)aValues[3]).intValue();
782 result.resolution_y = ((Integer)aValues[4]).intValue();
784 return result;
786 catch (Exception e)
788 informUserOfError(e);
789 return null;
793 // this method executes an edit
794 private void toggleVisibility()
798 XHierarchicalPropertySet xHPS =
799 (XHierarchicalPropertySet)UnoRuntime.queryInterface(XHierarchicalPropertySet.class, mxModel);
801 final String sSetting = "Option/VisibleGrid";
803 System.out.println("GridEditor: toggling Visibility");
805 Boolean bOldValue = (Boolean)xHPS.getHierarchicalPropertyValue(sSetting);
807 Boolean bNewValue = new Boolean( ! bOldValue.booleanValue() );
809 xHPS.setHierarchicalPropertyValue(sSetting,bNewValue);
811 catch (Exception e)
813 informUserOfError(e);
818 /** This method creates an extra updatable view to change some data
819 and trigger the listener of the GridEditor
821 void changeSomeData(String xKey)
825 Object xOtherViewRoot = createUpdatableView(xKey, false);
827 XNameReplace aReplace = (XNameReplace)UnoRuntime.queryInterface(XNameReplace.class, xOtherViewRoot);
829 String aItemNames [] = aReplace.getElementNames();
830 for (int i=0; i < aItemNames.length; ++i) {
831 Object aItem = aReplace.getByName( aItemNames [i] );
832 AnyConverter aAnyConv = new AnyConverter();
833 // replace integers by a 'complement' value
834 if ( aAnyConv.isInt(aItem) )
836 int nOld = aAnyConv.toInt(aItem);
837 int nNew = 9999 - nOld;
839 System.out.println("Replacing integer value: " + aItemNames [i]);
840 aReplace.replaceByName( aItemNames [i], new Integer( nNew ) );
843 // and booleans by their negated value
844 else if ( aAnyConv.isBoolean(aItem) )
846 boolean bOld = aAnyConv.toBoolean(aItem);
847 boolean bNew = ! bOld;
849 System.out.println("Replacing boolean value: " + aItemNames [i]);
850 aReplace.replaceByName( aItemNames [i], new Boolean( bNew ) );
854 // commit the changes
855 XChangesBatch xUpdateControl =
856 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xOtherViewRoot);
858 xUpdateControl.commitChanges();
860 // we are done with the view - dispose it
861 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xOtherViewRoot)).dispose();
863 catch (Exception e)
865 System.err.println("Could not change some data in a different view. An exception occurred:");
866 e.printStackTrace();
870 // GROUP RESET EXAMPLE
871 /// This method resets the grid settings to their default values
872 protected void resetGridConfiguration()
873 throws com.sun.star.uno.Exception
875 // The path to the root element
876 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid";
878 // create the view
879 Object xViewRoot = createUpdatableView(cGridOptionsPath);
881 // resetting a single nested value
882 XHierarchicalNameAccess xHierarchicalAccess =
883 (XHierarchicalNameAccess)UnoRuntime.queryInterface(XHierarchicalNameAccess.class, xViewRoot);
885 // get using absolute name
886 Object xOptions = xHierarchicalAccess.getByHierarchicalName(cGridOptionsPath + "/Option");
888 XPropertyState xOptionState =
889 (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xOptions);
891 xOptionState.setPropertyToDefault("VisibleGrid");
893 // resetting more deeply nested values
894 Object xResolutionX = xHierarchicalAccess.getByHierarchicalName("Resolution/XAxis");
895 Object xResolutionY = xHierarchicalAccess.getByHierarchicalName("Resolution/YAxis");
897 XPropertyState xResolutionStateX =
898 (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xResolutionX);
899 XPropertyState xResolutionStateY =
900 (XPropertyState)UnoRuntime.queryInterface(XPropertyState.class, xResolutionY);
902 xResolutionStateX.setPropertyToDefault("Metric");
903 xResolutionStateY.setPropertyToDefault("Metric");
905 // resetting multiple sibling values
906 Object xSubdivision = xHierarchicalAccess.getByHierarchicalName("Subdivision");
908 XMultiPropertyStates xSubdivisionStates =
909 (XMultiPropertyStates)UnoRuntime.queryInterface(XMultiPropertyStates.class, xSubdivision);
911 xSubdivisionStates.setAllPropertiesToDefault();
913 // commit the changes
914 XChangesBatch xUpdateControl =
915 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
917 xUpdateControl.commitChanges();
919 // we are done with the view - dispose it
920 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
924 // SET UPDATE EXAMPLE
925 private static boolean SET_EXAMPLE_BROKEN_IN_THIS_RELEASE = true;
927 /** This method stores a sample data source given some connection data.
929 ATTENTION: This example requires an older version of the
930 org.openoffice.Office.DataAccess schema.
931 It does not work with the current schema.
932 Because of this, the method currenty does nothing.
933 You can still use the techniques shown in the example code.
935 void storeSampleDataSource()
936 throws com.sun.star.uno.Exception
938 if (SET_EXAMPLE_BROKEN_IN_THIS_RELEASE)
940 System.out.println("- DISABLED: (the existing example does not work with this version) -");
941 return; // this function does not work
944 String sSampleDataSourceName = "SampleTextDatabase";
946 String sSampleDataSourceURL = "sdbc:flat:$(userurl)/database/SampleTextDatabase";
947 // String sSampleDataSourceURL = "sdbc:flat:file:///usr/local/database/SampleTextDatabase";
948 // String sSampleDataSourceURL = "sdbc:flat:file:///C:/data/database/SampleTextDatabase";
950 com.sun.star.beans.NamedValue [] aSettings = new com.sun.star.beans.NamedValue [2];
951 aSettings[0] = new com.sun.star.beans.NamedValue("HeaderLine",new Boolean(true));
952 aSettings[1] = new com.sun.star.beans.NamedValue("FieldDelimiter",";");
954 String [] aTableFilter = new String[2];
955 aTableFilter[0] = "table.txt";
956 aTableFilter[1] = "othertable.txt";
958 storeDataSource(sSampleDataSourceName,sSampleDataSourceURL,"",false,0,aSettings,aTableFilter);
961 /// This method stores a data source given some connection data
962 void storeDataSource(
963 String sDataSourceName,
964 String sDataSourceURL,
965 String sUser,
966 boolean bNeedsPassword,
967 int nTimeout,
968 com.sun.star.beans.NamedValue [] aDriverSettings,
969 String [] aTableFilter
971 throws com.sun.star.uno.Exception
973 // create the view and get the data source element
974 Object xDataSource = createDataSourceDescription(getProvider(),sDataSourceName);
976 // set the values
977 XPropertySet xDataSourceProperties =
978 (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xDataSource);
980 xDataSourceProperties.setPropertyValue("URL", sDataSourceURL );
981 xDataSourceProperties.setPropertyValue("User", sUser );
982 xDataSourceProperties.setPropertyValue("IsPasswordRequired", new Boolean( bNeedsPassword ) );
983 xDataSourceProperties.setPropertyValue("LoginTimeout", new Integer( nTimeout ) );
985 if ( aTableFilter != null )
986 xDataSourceProperties.setPropertyValue("TableFilter", aTableFilter );
988 // store the driver-specific settings
989 if (aDriverSettings != null)
991 Object xSettingsSet = xDataSourceProperties.getPropertyValue("DataSourceSettings");
992 storeSettings( xSettingsSet, aDriverSettings);
995 // save the data and dispose the view
996 // recover the view root
997 Object xViewRoot = getViewRoot(xDataSource);
999 // commit the changes
1000 XChangesBatch xUpdateControl =
1001 (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot);
1003 xUpdateControl.commitChanges();
1005 // now clean up
1006 ((XComponent) UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
1009 /** This method gets the DataSourceDescription for a data source.
1010 It either gets the existing entry or creates a new instance.
1012 The method attempts to keep the view used as small as possible. In particular there
1013 is no view created, that contains data for all data source that are registered.
1015 Object createDataSourceDescription(XMultiServiceFactory xProvider, String sDataSourceName )
1016 throws com.sun.star.uno.Exception
1018 // The service name: Need an update access:
1019 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess";
1021 // The path to the DataSources set node
1022 final String cDataSourcesPath = "/org.openoffice.Office.DataAccess/DataSources";
1024 // creation arguments: nodepath
1025 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue();
1026 aPathArgument.Name = "nodepath";
1027 aPathArgument.Value = cDataSourcesPath ;
1029 // creation arguments: commit mode
1030 com.sun.star.beans.PropertyValue aModeArgument = new com.sun.star.beans.PropertyValue();
1031 aModeArgument.Name = "lazywrite";
1032 aModeArgument.Value = new Boolean( true );
1034 // creation arguments: depth
1035 com.sun.star.beans.PropertyValue aDepthArgument = new com.sun.star.beans.PropertyValue();
1036 aDepthArgument.Name = "depth";
1037 aDepthArgument.Value = new Integer( 1 );
1039 Object[] aArguments = new Object[3];
1040 aArguments[0] = aPathArgument;
1041 aArguments[1] = aModeArgument;
1042 aArguments[2] = aDepthArgument;
1044 // create the view: asynchronously updatable, with depth 1
1045 Object xViewRoot =
1046 xProvider.createInstanceWithArguments(cUpdatableView, aArguments);
1048 XNameAccess xSetOfDataSources =
1049 (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class,xViewRoot);
1051 Object xDataSourceDescriptor = null; // the result
1052 if ( xSetOfDataSources .hasByName( sDataSourceName ))
1054 // the element is there, but it is loaded only with depth zero !
1055 try
1057 // the view should point to the element directly, so we need to extend the path
1058 XHierarchicalName xComposePath = (XHierarchicalName)
1059 UnoRuntime.queryInterface(XHierarchicalName.class, xSetOfDataSources );
1061 String sElementPath = xComposePath.composeHierarchicalName( sDataSourceName );
1063 // use the name of the element now
1064 aPathArgument.Value = sElementPath;
1066 // create another view now (without depth limit)
1067 Object[] aDeepArguments = new Object[2];
1068 aDeepArguments[0] = aPathArgument;
1069 aDeepArguments[1] = aModeArgument;
1071 // create the view: asynchronously updatable, with unlimited depth
1072 xDataSourceDescriptor =
1073 xProvider.createInstanceWithArguments(cUpdatableView, aDeepArguments);
1075 if ( xDataSourceDescriptor != null) // all went fine
1077 // dispose the other view
1078 ((XComponent)UnoRuntime.queryInterface(XComponent.class, xViewRoot)).dispose();
1079 xViewRoot = null;
1082 catch (Exception e)
1084 // something went wrong, we retry with a new element
1085 System.err.println("WARNING: An exception occurred while creating a view for an existing data source: " + e);
1086 xDataSourceDescriptor = null;
1090 // do we have a result element yet ?
1091 if ( xDataSourceDescriptor == null)
1093 // get the container
1094 XNameContainer xSetUpdate =
1095 (XNameContainer)UnoRuntime.queryInterface(XNameContainer.class, xViewRoot);
1097 // create a new detached set element (instance of DataSourceDescription)
1098 XSingleServiceFactory xElementFactory =
1099 (XSingleServiceFactory)UnoRuntime.queryInterface(XSingleServiceFactory.class, xSetUpdate);
1101 // the new element is the result !
1102 xDataSourceDescriptor = xElementFactory.createInstance();
1104 // insert it - this also names the element
1105 xSetUpdate.insertByName( sDataSourceName , xDataSourceDescriptor );
1108 return xDataSourceDescriptor ;
1111 /// this method stores a number of settings in a set node containing DataSourceSetting objects
1112 void storeSettings(Object xSettingsSet, com.sun.star.beans.NamedValue [] aSettings )
1113 throws com.sun.star.uno.Exception
1115 if (aSettings == null)
1116 return;
1118 // get the settings set as a container
1119 XNameContainer xSettingsContainer =
1120 (XNameContainer) UnoRuntime.queryInterface( XNameContainer.class, xSettingsSet);
1122 // and get a factory interface for creating the entries
1123 XSingleServiceFactory xSettingsFactory =
1124 (XSingleServiceFactory) UnoRuntime.queryInterface(XSingleServiceFactory.class, xSettingsSet);
1126 // now insert the individual settings
1127 for (int i = 0; i < aSettings.length; ++i) {
1128 // create a DataSourceSetting object
1129 XPropertySet xSetting = (XPropertySet)
1130 UnoRuntime.queryInterface( XPropertySet.class, xSettingsFactory.createInstance() );
1132 // can set the value before inserting
1133 xSetting.setPropertyValue( "Value", aSettings[i].Value );
1135 // and now insert or replace as appropriate
1136 if (xSettingsContainer.hasByName( aSettings[i].Name ))
1137 xSettingsContainer.replaceByName( aSettings[i].Name, xSetting );
1138 else
1139 xSettingsContainer.insertByName( aSettings[i].Name, xSetting );
1143 // HELPER FUNCTIONS
1145 /// This method get the view root node given an interface to any node in the view
1146 public static Object getViewRoot(Object xElement)
1148 Object xResult = xElement;
1150 // set the result to its parent until that would be null
1151 Object xParent;
1154 XChild xParentAccess =
1155 (XChild) UnoRuntime.queryInterface(XChild.class,xResult);
1157 if (xParentAccess != null)
1158 xParent = xParentAccess.getParent();
1159 else
1160 xParent = null;
1162 if (xParent != null)
1163 xResult = xParent;
1165 while (xParent != null);
1167 return xResult;
1170 // workaround methods for unimplemented functionality
1172 /// WORKAROUND: does the same as xNamedItem.setName(sNewName) should do
1173 void renameSetItem(XNamed xNamedItem, String sNewName)
1174 throws com.sun.star.uno.Exception
1176 XChild xChildItem = (XChild)
1177 UnoRuntime.queryInterface(XChild.class, xNamedItem);
1179 XNameContainer xParentSet = (XNameContainer)
1180 UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() );
1182 String sOldName = xNamedItem.getName();
1184 // now rename the item
1185 xParentSet.removeByName(sOldName);
1186 xParentSet.insertByName(sNewName,xNamedItem);
1189 /// WORKAROUND: does the same as xChildItem.setParent( xNewParent ) should do
1190 void moveSetItem(XChild xChildItem, XNameContainer xNewParent)
1191 throws com.sun.star.uno.Exception
1193 XNamed xNamedItem = (XNamed)
1194 UnoRuntime.queryInterface(XNamed.class, xChildItem);
1196 XNameContainer xOldParent = (XNameContainer)
1197 UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() );
1199 String sItemName = xNamedItem.getName();
1201 // now rename the item
1202 xOldParent.removeByName(sItemName);
1203 xNewParent.insertByName(sItemName,xChildItem);
1207 // ------- the end -----------