1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /************************************************************************* 3 * 4 * The Contents of this file are made available subject to the terms of 5 * the BSD license. 6 * 7 * Copyright 2000, 2010 Oracle and/or its affiliates. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 31 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 32 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 *************************************************************************/ 35 36 // Import everything we use 37 38 import com.sun.star.beans.XPropertySet; 39 import com.sun.star.beans.XMultiPropertySet; 40 import com.sun.star.beans.XHierarchicalPropertySet; 41 import com.sun.star.beans.XMultiHierarchicalPropertySet; 42 import com.sun.star.beans.XPropertyState; 43 import com.sun.star.beans.XMultiPropertyStates; 44 45 import com.sun.star.configuration.XTemplateInstance; 46 47 import com.sun.star.container.XNameAccess; 48 import com.sun.star.container.XNameReplace; 49 import com.sun.star.container.XNameContainer; 50 import com.sun.star.container.XNamed; 51 import com.sun.star.container.XChild; 52 import com.sun.star.container.XHierarchicalNameAccess; 53 import com.sun.star.container.XHierarchicalName; 54 55 import com.sun.star.lang.XComponent; 56 import com.sun.star.lang.XMultiComponentFactory; 57 import com.sun.star.lang.XSingleServiceFactory; 58 import com.sun.star.lang.XMultiServiceFactory; 59 import com.sun.star.lang.XServiceInfo; 60 import com.sun.star.lang.EventObject; 61 62 import com.sun.star.uno.UnoRuntime; 63 import com.sun.star.uno.XComponentContext; 64 import com.sun.star.uno.XInterface; 65 import com.sun.star.uno.AnyConverter; 66 67 import com.sun.star.util.XChangesBatch; 68 import com.sun.star.util.XChangesNotifier; 69 import com.sun.star.util.XChangesListener; 70 import com.sun.star.util.ChangesEvent; 71 // Config examples 72 73 /* These examples show how to use the following features of the Config API: 74 75 o Accessing data 76 o Updating data 77 o Updating properties in groups 78 o Adding and removing items in sets 79 o Resetting data to their defaults 80 81 Each example is in a separate method call. 82 */ 83 public class ConfigExamples 84 { 85 // The ComponentContext interface of the remote component context 86 private final XComponentContext mxContext; 87 88 // The MultiComponentFactory interface of the ServiceManager 89 private final XMultiComponentFactory mxServiceManager; 90 91 // The MultiServiceFactory interface of the ConfigurationProvider 92 private XMultiServiceFactory mxProvider = null; 93 main( String args[] )94 public static void main( String args[] ) 95 { 96 try { 97 // get the remote office component context 98 com.sun.star.uno.XComponentContext xContext = 99 com.sun.star.comp.helper.Bootstrap.bootstrap(); 100 101 if( xContext != null ) 102 System.out.println("Connected to a running office ..."); 103 else 104 System.out.println( "ERROR: Cannot connect - no remote component context available." ); 105 106 // Create an instance of the class and call its run method 107 ConfigExamples aExample = new ConfigExamples(xContext); 108 aExample.run( ); 109 110 // if you own the service manager dispose it here 111 // to ensure that the default provider is properly disposed and flushed 112 System.exit(0); 113 } 114 catch( Exception e ) 115 { 116 e.printStackTrace(); 117 System.exit(-1); 118 } 119 } 120 121 /** Create a ConfigExamples instance supplying a service factory 122 */ ConfigExamples(XComponentContext xContext)123 public ConfigExamples(XComponentContext xContext) 124 { 125 mxContext = xContext; 126 mxServiceManager = xContext.getServiceManager(); 127 } 128 129 /** Run the examples with a default ConfigurationProvider 130 */ run()131 public void run() 132 throws com.sun.star.uno.Exception 133 { 134 mxProvider = createProvider(); 135 136 runExamples( ); 137 138 // we are using the default ConfigurationProvider, so we must not dispose it 139 mxProvider = null; 140 } 141 142 /** Run the examples with a given ConfigurationProvider 143 */ runExamples( )144 public void runExamples( ) 145 { 146 if (checkProvider(mxProvider)) 147 { 148 System.out.println("\nStarting examples."); 149 150 readDataExample(); 151 152 browseDataExample(); 153 154 updateGroupExample(); 155 156 resetGroupExample(); 157 158 updateSetExample(); 159 160 System.out.println("\nAll Examples completed."); 161 } 162 else 163 System.out.println("ERROR: Cannot run examples without ConfigurationProvider."); 164 165 } 166 167 /** Do some simple checks, if there is a valid ConfigurationProvider 168 */ checkProvider(XMultiServiceFactory xProvider)169 public static boolean checkProvider(XMultiServiceFactory xProvider) 170 { 171 // check the provider we have 172 if (xProvider == null) 173 { 174 System.out.println("No provider available. Cannot access configuration data."); 175 return false; 176 177 } 178 179 try 180 { 181 // check the provider implementation 182 XServiceInfo xProviderServices = 183 UnoRuntime.queryInterface( XServiceInfo.class, xProvider ); 184 185 if (xProviderServices == null || 186 !xProviderServices.supportsService("com.sun.star.configuration.ConfigurationProvider")) 187 { 188 System.out.println("WARNING: The provider is not a com.sun.star.configuration.ConfigurationProvider"); 189 } 190 191 if (xProviderServices != null) 192 { 193 System.out.println("Using provider implementation: " + xProviderServices.getImplementationName()); 194 } 195 196 return true; 197 } 198 catch (com.sun.star.uno.RuntimeException e) 199 { 200 System.err.println("ERROR: Failure while checking the provider services."); 201 e.printStackTrace(); 202 return false; 203 } 204 } 205 206 /** Get the provider we have 207 */ getProvider( )208 public XMultiServiceFactory getProvider( ) 209 { 210 return mxProvider; 211 } 212 213 /** Create a default configuration provider 214 */ createProvider( )215 public XMultiServiceFactory createProvider( ) 216 throws com.sun.star.uno.Exception 217 { 218 final String sProviderService = "com.sun.star.configuration.ConfigurationProvider"; 219 220 // create the provider and return it as a XMultiServiceFactory 221 XMultiServiceFactory xProvider = UnoRuntime.queryInterface(XMultiServiceFactory.class, 222 mxServiceManager.createInstanceWithContext(sProviderService, 223 mxContext)); 224 225 return xProvider; 226 } 227 228 /** Create a specified read-only configuration view 229 */ createConfigurationView( String sPath )230 public Object createConfigurationView( String sPath ) 231 throws com.sun.star.uno.Exception 232 { 233 XMultiServiceFactory xProvider = getProvider(); 234 235 // The service name: Need only read access: 236 final String sReadOnlyView = "com.sun.star.configuration.ConfigurationAccess"; 237 238 // creation arguments: nodepath 239 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue(); 240 aPathArgument.Name = "nodepath"; 241 aPathArgument.Value = sPath; 242 243 Object[] aArguments = new Object[1]; 244 aArguments[0] = aPathArgument; 245 246 // create the view 247 Object xViewRoot = xProvider.createInstanceWithArguments(sReadOnlyView, aArguments); 248 249 return xViewRoot; 250 } 251 252 /** Create a specified updatable configuration view 253 */ createUpdatableView( String sPath )254 Object createUpdatableView( String sPath ) 255 throws com.sun.star.uno.Exception 256 { 257 XMultiServiceFactory xProvider = getProvider(); 258 259 // The service name: Need update access: 260 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess"; 261 262 // creation arguments: nodepath 263 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue(); 264 aPathArgument.Name = "nodepath"; 265 aPathArgument.Value = sPath; 266 267 Object[] aArguments = new Object[1]; 268 aArguments[0] = aPathArgument; 269 270 // create the view 271 Object xViewRoot = xProvider.createInstanceWithArguments(cUpdatableView, aArguments); 272 273 return xViewRoot; 274 } 275 276 /** This method demonstrates read access to data 277 */ readDataExample()278 protected void readDataExample () 279 { 280 try 281 { 282 System.out.println("\n--- starting example: read grid option settings --------------------"); 283 Object aData = readGridConfiguration( ); 284 System.out.println("Read grid options: " + aData); 285 286 } 287 catch ( Exception e ) 288 { 289 e.printStackTrace(); 290 } 291 } 292 293 /** This method demonstrates browsing access to data 294 */ browseDataExample()295 protected void browseDataExample () 296 { 297 try 298 { 299 System.out.println("\n--- starting example: browse filter configuration ------------------"); 300 printRegisteredFilters( ); 301 } 302 catch ( Exception e ) 303 { 304 e.printStackTrace(); 305 } 306 } 307 308 /** This method demonstrates update access to group data 309 */ updateGroupExample()310 protected void updateGroupExample () 311 { 312 try 313 { 314 System.out.println("\n--- starting example: update group data --------------"); 315 editGridOptions( ); 316 } 317 catch ( Exception e ) 318 { 319 e.printStackTrace(); 320 } 321 } 322 323 /** This method demonstrates resetting data to its default state 324 */ resetGroupExample()325 protected void resetGroupExample () 326 { 327 try 328 { 329 System.out.println("\n--- starting example: reset group data -----------------------------"); 330 Object aOldData = readGridConfiguration( ); 331 resetGridConfiguration( ); 332 Object aNewData = readGridConfiguration( ); 333 System.out.println("Before reset: user grid options: " + aOldData); 334 System.out.println("After reset: default grid options: " + aNewData); 335 } 336 catch ( Exception e ) 337 { 338 e.printStackTrace(); 339 } 340 } 341 342 /** This method demonstrates update access to set data 343 */ updateSetExample()344 protected void updateSetExample () 345 { 346 try 347 { 348 System.out.println("\n--- starting example: update set data ---------------"); 349 storeSampleDataSource( ); 350 } 351 catch ( Exception e ) 352 { 353 e.printStackTrace(); 354 } 355 } 356 357 // READ example 358 /// class to hold information about grid settings 359 private static class GridOptions 360 { 361 private boolean visible; 362 private int resolution_x; 363 private int resolution_y; 364 private int subdivision_x; 365 private int subdivision_y; 366 367 @Override toString()368 public String toString() { 369 StringBuffer aBuffer = new StringBuffer(); 370 aBuffer.append("[ Grid is "); aBuffer.append(visible ? "VISIBLE" : "HIDDEN"); 371 aBuffer.append("; resolution = (" + resolution_x + "," + resolution_y + ")"); 372 aBuffer.append("; subdivision = (" + subdivision_x + "," + subdivision_y + ")"); 373 aBuffer.append(" ]"); 374 return aBuffer.toString(); 375 } 376 } 377 378 /// This method reads information about grid settings readGridConfiguration()379 protected GridOptions readGridConfiguration() 380 throws com.sun.star.uno.Exception 381 { 382 // The path to the root element 383 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid"; 384 385 // create the view 386 Object xViewRoot = createConfigurationView(cGridOptionsPath); 387 388 // the result structure 389 GridOptions options = new GridOptions(); 390 391 // accessing a single nested value 392 XHierarchicalPropertySet xProperties = 393 UnoRuntime.queryInterface(XHierarchicalPropertySet.class, xViewRoot); 394 395 Object aVisible = xProperties.getHierarchicalPropertyValue("Option/VisibleGrid"); 396 options.visible = ((Boolean) aVisible).booleanValue(); 397 398 // accessing a nested object and its subproperties 399 Object xSubdivision = xProperties.getHierarchicalPropertyValue("Subdivision"); 400 401 XMultiPropertySet xSubdivProperties = 402 UnoRuntime.queryInterface(XMultiPropertySet.class, xSubdivision); 403 404 // variables for multi-element access 405 String[] aElementNames = new String[] { "XAxis", "YAxis" }; 406 407 Object[] aElementValues = xSubdivProperties.getPropertyValues(aElementNames); 408 409 options.subdivision_x = ((Integer) aElementValues[0]).intValue(); 410 options.subdivision_y = ((Integer) aElementValues[1]).intValue(); 411 412 // accessing deeply nested subproperties 413 Object xResolution = xProperties.getHierarchicalPropertyValue("Resolution"); 414 415 XMultiHierarchicalPropertySet xResolutionProperties = 416 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xResolution); 417 418 aElementNames[0] = "XAxis/Metric"; 419 aElementNames[1] = "YAxis/Metric"; 420 421 aElementValues = xResolutionProperties.getHierarchicalPropertyValues(aElementNames); 422 423 options.resolution_x = ((Integer) aElementValues[0]).intValue(); 424 options.resolution_y = ((Integer) aElementValues[1]).intValue(); 425 426 // all options have been retrieved - clean up and return 427 // we are done with the view - dispose it 428 429 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose(); 430 431 return options; 432 } 433 434 // BROWSE example 435 /// Interface to process information when browsing the configuration tree 436 public interface IConfigurationProcessor 437 { 438 /// process a value item processValueElement( String sPath_, Object aValue_ )439 void processValueElement( String sPath_, Object aValue_ ); 440 /// process a structural item processStructuralElement( String sPath_, XInterface xElement_)441 void processStructuralElement( String sPath_, XInterface xElement_); 442 } 443 444 /// Internal method to recursively browse a structural element in preorder browseElementRecursively( XInterface xElement, IConfigurationProcessor aProcessor )445 public void browseElementRecursively( XInterface xElement, IConfigurationProcessor aProcessor ) 446 throws com.sun.star.uno.Exception 447 { 448 // First process this as an element (preorder traversal) 449 XHierarchicalName xElementPath = 450 UnoRuntime.queryInterface(XHierarchicalName.class, xElement); 451 452 String sPath = xElementPath.getHierarchicalName(); 453 454 aProcessor.processStructuralElement( sPath, xElement); 455 456 // now process this as a container 457 XNameAccess xChildAccess = 458 UnoRuntime.queryInterface(XNameAccess.class, xElement); 459 460 // get a list of child elements 461 String[] aElementNames = xChildAccess.getElementNames(); 462 463 // and process them one by one 464 for(int i=0; i< aElementNames.length; ++i) 465 { 466 Object aChild = xChildAccess.getByName( aElementNames[i] ); 467 // is it a structural element (object) ... 468 if ( AnyConverter.isObject(aChild) && !AnyConverter.isArray(aChild) ) 469 { 470 // then get an interface 471 XInterface xChildElement = UnoRuntime.queryInterface(XInterface.class, aChild); 472 473 // and continue processing child elements recursively 474 browseElementRecursively( xChildElement, aProcessor ); 475 } 476 // ... or is it a simple value 477 else 478 { 479 // Build the path to it from the path of 480 // the element and the name of the child 481 String sChildPath; 482 sChildPath = 483 xElementPath.composeHierarchicalName(aElementNames[i]); 484 485 // and process the value 486 aProcessor.processValueElement( sChildPath, aChild ); 487 } 488 } 489 } 490 491 /** Method to browse the part rooted at sRootPath 492 of the configuration that the Provider provides. 493 494 All nodes will be processed by the IConfigurationProcessor passed. 495 */ browseConfiguration( String sRootPath, IConfigurationProcessor aProcessor )496 public void browseConfiguration( String sRootPath, IConfigurationProcessor aProcessor ) 497 throws com.sun.star.uno.Exception 498 { 499 // create the root element 500 XInterface xViewRoot = (XInterface)createConfigurationView( sRootPath ); 501 502 // now do the processing 503 browseElementRecursively( xViewRoot, aProcessor ); 504 505 // we are done with the view - dispose it 506 // This assumes that the processor 507 // does not keep a reference to the elements in processStructuralElement 508 509 UnoRuntime.queryInterface(XComponent.class,xViewRoot).dispose(); 510 xViewRoot = null; 511 } 512 513 /** Method to browse the filter configuration. 514 515 Information about installed filters will be printed. 516 */ printRegisteredFilters()517 public void printRegisteredFilters() 518 throws com.sun.star.uno.Exception 519 { 520 final String sFilterKey = "/org.openoffice.TypeDetection.Filter/Filters"; 521 522 // browse the configuration, dumping filter information 523 browseConfiguration( sFilterKey, 524 new IConfigurationProcessor () { 525 /// prints Path and Value of properties 526 public void processValueElement( String sPath_, Object aValue_ ) { 527 if (AnyConverter.isArray(aValue_)) 528 { 529 final Object [] aArray = (Object [])aValue_; 530 531 System.out.print("\tValue: " + sPath_ + " = { "); 532 for (int i=0; i<aArray.length; ++i) 533 { 534 if (i != 0) System.out.print(", "); 535 System.out.print(aArray[i]); 536 } 537 System.out.println(" }"); 538 } 539 else 540 System.out.println("\tValue: " + sPath_ + " = " + aValue_); 541 } 542 543 /// prints the Filter entries 544 public void processStructuralElement( String sPath_, XInterface xElement_) { 545 // get template information, to detect instances of the 'Filter' template 546 XTemplateInstance xInstance = 547 UnoRuntime.queryInterface( XTemplateInstance .class,xElement_); 548 549 // only select the Filter entries 550 if (xInstance != null && xInstance.getTemplateName().endsWith("Filter")) { 551 XNamed xNamed = UnoRuntime.queryInterface(XNamed.class,xElement_); 552 System.out.println("Filter " + xNamed.getName() + " (" + sPath_ + ")"); 553 } 554 } 555 } ); 556 } 557 558 // GROUP UPDATE example 559 560 /** This method simulates editing configuration data using a GridEditor dialog class 561 */ editGridOptions( )562 public void editGridOptions( ) 563 throws com.sun.star.uno.Exception 564 { 565 // The path to the root element 566 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid"; 567 568 // create the view 569 Object xViewRoot = createUpdatableView( cGridOptionsPath ); 570 571 // the 'editor' 572 GridOptionsEditor dialog = new GridOptionsEditor(); 573 574 // set up the initial values and register listeners 575 // get a data access interface, to supply the view with a model 576 XMultiHierarchicalPropertySet xProperties = 577 UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, xViewRoot); 578 579 dialog.setModel( xProperties ); 580 581 // get a listener object (probably an adapter) that notifies 582 // the dialog of external changes to its model 583 XChangesListener xListener = dialog.createChangesListener( ); 584 585 XChangesNotifier xNotifier = 586 UnoRuntime.queryInterface(XChangesNotifier.class, xViewRoot); 587 588 xNotifier.addChangesListener( xListener ); 589 590 // trigger the listener 591 changeSomeData( cGridOptionsPath + "/Subdivision" ); 592 593 if (dialog.execute() == GridOptionsEditor.SAVE_SETTINGS) 594 { 595 // changes have been applied to the view here 596 XChangesBatch xUpdateControl = 597 UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot); 598 599 try 600 { 601 xUpdateControl.commitChanges(); 602 } 603 catch (Exception e) 604 { 605 dialog.informUserOfError( e ); 606 } 607 } 608 609 // all changes have been handled - clean up and return 610 // listener is done now 611 xNotifier.removeChangesListener( xListener ); 612 613 // we are done with the view - dispose it 614 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose(); 615 } 616 617 /** A class that changes some grid options settings 618 619 The interface of this class is chose to resemble a possible UI dialog class 620 */ 621 private class GridOptionsEditor { 622 /// the data this editor edits 623 XMultiHierarchicalPropertySet mxModel; 624 625 public static final int CANCELED = 0; 626 public static final int SAVE_SETTINGS = 1; 627 628 // sets a model and updates the display setModel(XMultiHierarchicalPropertySet xModel)629 public void setModel(XMultiHierarchicalPropertySet xModel) { 630 mxModel = xModel; 631 updateDisplay(); 632 } 633 634 // this method 'runs' the 'dialog' execute()635 public int execute() { 636 try 637 { 638 System.out.println("-- GridEditor executing --"); 639 // simulate a user action changing some data 640 toggleVisibility(); 641 System.out.println("-- GridEditor done --"); 642 return SAVE_SETTINGS; 643 } 644 catch (Exception e) 645 { 646 informUserOfError(e); 647 return CANCELED; 648 } 649 } 650 651 // this method is called to report an error during dialog execution to the user informUserOfError(Exception e)652 public void informUserOfError(Exception e) { 653 System.err.println("ERROR in GridEditor:"); 654 e.printStackTrace(); 655 } 656 657 /// this method is called to allow the dialog to get feedback about changes occurring elsewhere createChangesListener()658 public XChangesListener createChangesListener() { 659 if (mxModel == null) return null; 660 661 return (new XChangesListener () { 662 public void changesOccurred( ChangesEvent event ) { 663 System.out.println("GridEditor - Listener received changes event containing " + 664 event.Changes.length + " change(s)."); 665 updateDisplay(); 666 } 667 668 public void disposing(EventObject event) { 669 System.out.println("GridEditor - Listener received disposed event: releasing model"); 670 setModel(null); 671 } 672 }); 673 } 674 /// this method is called when data has changed to display the updated data updateDisplay()675 private void updateDisplay() { 676 if (mxModel != null) 677 System.out.println("Grid options editor: data=" + readModel()); 678 else 679 System.out.println("Grid options editor: no model set"); 680 } 681 682 // this method is used to read all relevant data from the model readModel()683 private GridOptions readModel() 684 { 685 try 686 { 687 String [] aOptionNames = new String [5]; 688 aOptionNames[0] = "Option/VisibleGrid"; 689 aOptionNames[1] = "Subdivision/XAxis"; 690 aOptionNames[2] = "Subdivision/YAxis"; 691 aOptionNames[3] = "Resolution/XAxis/Metric"; 692 aOptionNames[4] = "Resolution/YAxis/Metric"; 693 694 Object [] aValues = mxModel.getHierarchicalPropertyValues(aOptionNames); 695 696 GridOptions result = new GridOptions(); 697 result.visible = ((Boolean)aValues[0]).booleanValue(); 698 result.subdivision_x = ((Integer)aValues[1]).intValue(); 699 result.subdivision_y = ((Integer)aValues[2]).intValue(); 700 result.resolution_x = ((Integer)aValues[3]).intValue(); 701 result.resolution_y = ((Integer)aValues[4]).intValue(); 702 703 return result; 704 } 705 catch (Exception e) 706 { 707 informUserOfError(e); 708 return null; 709 } 710 } 711 712 // this method executes an edit toggleVisibility()713 private void toggleVisibility() 714 { 715 try 716 { 717 XHierarchicalPropertySet xHPS = 718 UnoRuntime.queryInterface(XHierarchicalPropertySet.class, mxModel); 719 720 final String sSetting = "Option/VisibleGrid"; 721 722 System.out.println("GridEditor: toggling Visibility"); 723 724 Boolean bOldValue = (Boolean)xHPS.getHierarchicalPropertyValue(sSetting); 725 726 Boolean bNewValue = Boolean.valueOf( ! bOldValue.booleanValue() ); 727 728 xHPS.setHierarchicalPropertyValue(sSetting,bNewValue); 729 } 730 catch (Exception e) 731 { 732 informUserOfError(e); 733 } 734 } 735 } 736 737 /** This method creates an extra updatable view to change some data 738 and trigger the listener of the GridEditor 739 */ 740 void changeSomeData(String xKey) 741 { 742 try 743 { 744 Object xOtherViewRoot = createUpdatableView(xKey); 745 746 XNameReplace aReplace = UnoRuntime.queryInterface(XNameReplace.class, xOtherViewRoot); 747 748 String aItemNames [] = aReplace.getElementNames(); 749 for (int i=0; i < aItemNames.length; ++i) { 750 Object aItem = aReplace.getByName( aItemNames [i] ); 751 // replace integers by a 'complement' value 752 if ( AnyConverter.isInt(aItem) ) 753 { 754 int nOld = AnyConverter.toInt(aItem); 755 int nNew = 9999 - nOld; 756 757 System.out.println("Replacing integer value: " + aItemNames [i]); 758 aReplace.replaceByName( aItemNames [i], Integer.valueOf( nNew ) ); 759 } 760 761 // and booleans by their negated value 762 else if ( AnyConverter.isBoolean(aItem) ) 763 { 764 boolean bOld = AnyConverter.toBoolean(aItem); 765 boolean bNew = ! bOld; 766 767 System.out.println("Replacing boolean value: " + aItemNames [i]); 768 aReplace.replaceByName( aItemNames [i], Boolean.valueOf( bNew ) ); 769 } 770 } 771 772 // commit the changes 773 XChangesBatch xUpdateControl = 774 UnoRuntime.queryInterface(XChangesBatch.class,xOtherViewRoot); 775 776 xUpdateControl.commitChanges(); 777 778 // we are done with the view - dispose it 779 UnoRuntime.queryInterface(XComponent.class, xOtherViewRoot).dispose(); 780 } 781 catch (Exception e) 782 { 783 System.err.println("Could not change some data in a different view. An exception occurred:"); 784 e.printStackTrace(); 785 } 786 } 787 788 // GROUP RESET EXAMPLE 789 /// This method resets the grid settings to their default values 790 protected void resetGridConfiguration() 791 throws com.sun.star.uno.Exception 792 { 793 // The path to the root element 794 final String cGridOptionsPath = "/org.openoffice.Office.Calc/Grid"; 795 796 // create the view 797 Object xViewRoot = createUpdatableView(cGridOptionsPath); 798 799 // resetting a single nested value 800 XHierarchicalNameAccess xHierarchicalAccess = 801 UnoRuntime.queryInterface(XHierarchicalNameAccess.class, xViewRoot); 802 803 // get using absolute name 804 Object xOptions = xHierarchicalAccess.getByHierarchicalName(cGridOptionsPath + "/Option"); 805 806 XPropertyState xOptionState = 807 UnoRuntime.queryInterface(XPropertyState.class, xOptions); 808 809 xOptionState.setPropertyToDefault("VisibleGrid"); 810 811 // resetting more deeply nested values 812 Object xResolutionX = xHierarchicalAccess.getByHierarchicalName("Resolution/XAxis"); 813 Object xResolutionY = xHierarchicalAccess.getByHierarchicalName("Resolution/YAxis"); 814 815 XPropertyState xResolutionStateX = 816 UnoRuntime.queryInterface(XPropertyState.class, xResolutionX); 817 XPropertyState xResolutionStateY = 818 UnoRuntime.queryInterface(XPropertyState.class, xResolutionY); 819 820 xResolutionStateX.setPropertyToDefault("Metric"); 821 xResolutionStateY.setPropertyToDefault("Metric"); 822 823 // resetting multiple sibling values 824 Object xSubdivision = xHierarchicalAccess.getByHierarchicalName("Subdivision"); 825 826 XMultiPropertyStates xSubdivisionStates = 827 UnoRuntime.queryInterface(XMultiPropertyStates.class, xSubdivision); 828 829 xSubdivisionStates.setAllPropertiesToDefault(); 830 831 // commit the changes 832 XChangesBatch xUpdateControl = 833 UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot); 834 835 xUpdateControl.commitChanges(); 836 837 // we are done with the view - dispose it 838 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose(); 839 } 840 841 842 // SET UPDATE EXAMPLE 843 private static boolean SET_EXAMPLE_BROKEN_IN_THIS_RELEASE = true; 844 845 /** This method stores a sample data source given some connection data. 846 847 ATTENTION: This example requires an older version of the 848 org.openoffice.Office.DataAccess schema. 849 It does not work with the current schema. 850 Because of this, the method currently does nothing. 851 You can still use the techniques shown in the example code. 852 */ 853 void storeSampleDataSource() 854 throws com.sun.star.uno.Exception 855 { 856 if (SET_EXAMPLE_BROKEN_IN_THIS_RELEASE) 857 { 858 System.out.println("- DISABLED: (the existing example does not work with this version) -"); 859 return; // this function does not work 860 } 861 862 String sSampleDataSourceName = "SampleTextDatabase"; 863 864 String sSampleDataSourceURL = "sdbc:flat:$(userurl)/database/SampleTextDatabase"; 865 866 com.sun.star.beans.NamedValue [] aSettings = new com.sun.star.beans.NamedValue [2]; 867 aSettings[0] = new com.sun.star.beans.NamedValue("HeaderLine",Boolean.TRUE); 868 aSettings[1] = new com.sun.star.beans.NamedValue("FieldDelimiter",";"); 869 870 String [] aTableFilter = new String[] { "table.txt", "othertable.txt" }; 871 872 storeDataSource(sSampleDataSourceName,sSampleDataSourceURL,"",false,0,aSettings,aTableFilter); 873 } 874 875 /// This method stores a data source given some connection data 876 void storeDataSource( 877 String sDataSourceName, 878 String sDataSourceURL, 879 String sUser, 880 boolean bNeedsPassword, 881 int nTimeout, 882 com.sun.star.beans.NamedValue [] aDriverSettings, 883 String [] aTableFilter 884 ) 885 throws com.sun.star.uno.Exception 886 { 887 // create the view and get the data source element 888 Object xDataSource = createDataSourceDescription(getProvider(),sDataSourceName); 889 890 // set the values 891 XPropertySet xDataSourceProperties = 892 UnoRuntime.queryInterface(XPropertySet.class, xDataSource); 893 894 xDataSourceProperties.setPropertyValue("URL", sDataSourceURL ); 895 xDataSourceProperties.setPropertyValue("User", sUser ); 896 xDataSourceProperties.setPropertyValue("IsPasswordRequired", Boolean.valueOf( bNeedsPassword ) ); 897 xDataSourceProperties.setPropertyValue("LoginTimeout", Integer.valueOf( nTimeout ) ); 898 899 if ( aTableFilter != null ) 900 xDataSourceProperties.setPropertyValue("TableFilter", aTableFilter ); 901 902 // store the driver-specific settings 903 if (aDriverSettings != null) 904 { 905 Object xSettingsSet = xDataSourceProperties.getPropertyValue("DataSourceSettings"); 906 storeSettings( xSettingsSet, aDriverSettings); 907 } 908 909 // save the data and dispose the view 910 // recover the view root 911 Object xViewRoot = getViewRoot(xDataSource); 912 913 // commit the changes 914 XChangesBatch xUpdateControl = 915 UnoRuntime.queryInterface(XChangesBatch.class,xViewRoot); 916 917 xUpdateControl.commitChanges(); 918 919 // now clean up 920 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose(); 921 } 922 923 /** This method gets the DataSourceDescription for a data source. 924 It either gets the existing entry or creates a new instance. 925 */ 926 Object createDataSourceDescription(XMultiServiceFactory xProvider, String sDataSourceName ) 927 throws com.sun.star.uno.Exception 928 { 929 // The service name: Need an update access: 930 final String cUpdatableView = "com.sun.star.configuration.ConfigurationUpdateAccess"; 931 932 // The path to the DataSources set node 933 final String cDataSourcesPath = "/org.openoffice.Office.DataAccess/DataSources"; 934 935 // creation arguments: nodepath 936 com.sun.star.beans.PropertyValue aPathArgument = new com.sun.star.beans.PropertyValue(); 937 aPathArgument.Name = "nodepath"; 938 aPathArgument.Value = cDataSourcesPath ; 939 940 Object[] aArguments = new Object[1]; 941 aArguments[0] = aPathArgument; 942 943 // create the view 944 Object xViewRoot = 945 xProvider.createInstanceWithArguments(cUpdatableView, aArguments); 946 947 XNameAccess xSetOfDataSources = 948 UnoRuntime.queryInterface(XNameAccess.class,xViewRoot); 949 950 Object xDataSourceDescriptor = null; // the result 951 if ( xSetOfDataSources .hasByName( sDataSourceName )) 952 { 953 // the element is there 954 try 955 { 956 // the view should point to the element directly, so we need to extend the path 957 XHierarchicalName xComposePath = UnoRuntime.queryInterface(XHierarchicalName.class, xSetOfDataSources ); 958 959 String sElementPath = xComposePath.composeHierarchicalName( sDataSourceName ); 960 961 // use the name of the element now 962 aPathArgument.Value = sElementPath; 963 964 // create another view now 965 Object[] aDeepArguments = new Object[1]; 966 aDeepArguments[0] = aPathArgument; 967 968 // create the view 969 xDataSourceDescriptor = 970 xProvider.createInstanceWithArguments(cUpdatableView, aDeepArguments); 971 972 if ( xDataSourceDescriptor != null) // all went fine 973 { 974 // dispose the other view 975 UnoRuntime.queryInterface(XComponent.class, xViewRoot).dispose(); 976 xViewRoot = null; 977 } 978 } 979 catch (Exception e) 980 { 981 // something went wrong, we retry with a new element 982 System.err.println("WARNING: An exception occurred while creating a view for an existing data source: " + e); 983 xDataSourceDescriptor = null; 984 } 985 } 986 987 // do we have a result element yet ? 988 if ( xDataSourceDescriptor == null) 989 { 990 // get the container 991 XNameContainer xSetUpdate = 992 UnoRuntime.queryInterface(XNameContainer.class, xViewRoot); 993 994 // create a new detached set element (instance of DataSourceDescription) 995 XSingleServiceFactory xElementFactory = 996 UnoRuntime.queryInterface(XSingleServiceFactory.class, xSetUpdate); 997 998 // the new element is the result ! 999 xDataSourceDescriptor = xElementFactory.createInstance(); 1000 1001 // insert it - this also names the element 1002 xSetUpdate.insertByName( sDataSourceName , xDataSourceDescriptor ); 1003 } 1004 1005 return xDataSourceDescriptor ; 1006 } 1007 1008 /// this method stores a number of settings in a set node containing DataSourceSetting objects 1009 void storeSettings(Object xSettingsSet, com.sun.star.beans.NamedValue [] aSettings ) 1010 throws com.sun.star.uno.Exception 1011 { 1012 if (aSettings == null) 1013 return; 1014 1015 // get the settings set as a container 1016 XNameContainer xSettingsContainer = 1017 UnoRuntime.queryInterface( XNameContainer.class, xSettingsSet); 1018 1019 // and get a factory interface for creating the entries 1020 XSingleServiceFactory xSettingsFactory = 1021 UnoRuntime.queryInterface(XSingleServiceFactory.class, xSettingsSet); 1022 1023 // now insert the individual settings 1024 for (int i = 0; i < aSettings.length; ++i) { 1025 // create a DataSourceSetting object 1026 XPropertySet xSetting = UnoRuntime.queryInterface( XPropertySet.class, xSettingsFactory.createInstance() ); 1027 1028 // can set the value before inserting 1029 xSetting.setPropertyValue( "Value", aSettings[i].Value ); 1030 1031 // and now insert or replace as appropriate 1032 if (xSettingsContainer.hasByName( aSettings[i].Name )) 1033 xSettingsContainer.replaceByName( aSettings[i].Name, xSetting ); 1034 else 1035 xSettingsContainer.insertByName( aSettings[i].Name, xSetting ); 1036 } 1037 } 1038 1039 // HELPER FUNCTIONS 1040 1041 /// This method get the view root node given an interface to any node in the view 1042 public static Object getViewRoot(Object xElement) 1043 { 1044 Object xResult = xElement; 1045 1046 // set the result to its parent until that would be null 1047 Object xParent; 1048 do 1049 { 1050 XChild xParentAccess = 1051 UnoRuntime.queryInterface(XChild.class,xResult); 1052 1053 if (xParentAccess != null) 1054 xParent = xParentAccess.getParent(); 1055 else 1056 xParent = null; 1057 1058 if (xParent != null) 1059 xResult = xParent; 1060 } 1061 while (xParent != null); 1062 1063 return xResult; 1064 } 1065 1066 // workaround methods for unimplemented functionality 1067 1068 /// WORKAROUND: does the same as xNamedItem.setName(sNewName) should do 1069 void renameSetItem(XNamed xNamedItem, String sNewName) 1070 throws com.sun.star.uno.Exception 1071 { 1072 XChild xChildItem = UnoRuntime.queryInterface(XChild.class, xNamedItem); 1073 1074 XNameContainer xParentSet = UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() ); 1075 1076 String sOldName = xNamedItem.getName(); 1077 1078 // now rename the item 1079 xParentSet.removeByName(sOldName); 1080 xParentSet.insertByName(sNewName,xNamedItem); 1081 } 1082 1083 /// WORKAROUND: does the same as xChildItem.setParent( xNewParent ) should do 1084 void moveSetItem(XChild xChildItem, XNameContainer xNewParent) 1085 throws com.sun.star.uno.Exception 1086 { 1087 XNamed xNamedItem = UnoRuntime.queryInterface(XNamed.class, xChildItem); 1088 1089 XNameContainer xOldParent = UnoRuntime.queryInterface( XNameContainer.class, xChildItem.getParent() ); 1090 1091 String sItemName = xNamedItem.getName(); 1092 1093 // now rename the item 1094 xOldParent.removeByName(sItemName); 1095 xNewParent.insertByName(sItemName,xChildItem); 1096 } 1097 1098 1099 // ------- the end ----------- 1100 } 1101 1102 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 1103