| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| package com.sun.star.comp.extensionoptions; |
| |
| import com.sun.star.lib.uno.helper.Factory; |
| import com.sun.star.lib.uno.helper.WeakBase; |
| import com.sun.star.lang.XMultiComponentFactory; |
| import com.sun.star.lang.XSingleComponentFactory; |
| import com.sun.star.lang.XMultiServiceFactory; |
| import com.sun.star.lang.WrappedTargetException; |
| import com.sun.star.lang.IllegalArgumentException; |
| import com.sun.star.lang.XInitialization; |
| import com.sun.star.lang.XTypeProvider; |
| import com.sun.star.lang.XServiceInfo; |
| import com.sun.star.lang.WrappedTargetException; |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.uno.Any; |
| import com.sun.star.uno.AnyConverter; |
| import com.sun.star.uno.XComponentContext; |
| import com.sun.star.uno.Exception; |
| import com.sun.star.registry.XRegistryKey; |
| import com.sun.star.awt.XContainerWindowEventHandler; |
| import com.sun.star.awt.XControl; |
| import com.sun.star.awt.XControlModel; |
| import com.sun.star.awt.XControlContainer; |
| import com.sun.star.container.XNameAccess; |
| import com.sun.star.container.NoSuchElementException; |
| import com.sun.star.beans.PropertyValue; |
| import com.sun.star.beans.PropertyState; |
| import com.sun.star.beans.XPropertySet; |
| import com.sun.star.beans.UnknownPropertyException; |
| import com.sun.star.beans.PropertyVetoException; |
| import com.sun.star.util.XChangesBatch; |
| |
| /** A handler which supports multiple options pages which all |
| * have the same controls. |
| */ |
| public class OptionsEventHandler { |
| |
| public static class _OptionsEventHandler extends WeakBase |
| implements XServiceInfo, XContainerWindowEventHandler { |
| |
| static private final String __serviceName = |
| "com.sun.star.comp.extensionoptions.OptionsEventHandler"; |
| |
| private XComponentContext m_cmpCtx; |
| |
| private XMultiComponentFactory m_xMCF; |
| |
| private XNameAccess m_xAccessLeaves; |
| |
| /**Names of supported options pages. |
| */ |
| private String[] m_arWindowNames = { |
| "Writer1", "Writer2", "Writer3", "Calc1", "Calc2", "Calc3", |
| "Draw1", "Draw2", "Draw3", "Node1_1", "Node1_2", "Node1_3", |
| "Node2_1", "Node2_2", "Node2_3", "Node3_1", "Node3_2", "Node3_3"}; |
| |
| /**Names of the controls which are supported by this handler. All these |
| *controls must have a "Text" property. |
| */ |
| private String[] m_arStringControls = { |
| "String0", "String1", "String2", "String3", "String4"}; |
| |
| public _OptionsEventHandler(XComponentContext xCompContext) { |
| m_cmpCtx = xCompContext; |
| m_xMCF = m_cmpCtx.getServiceManager(); |
| |
| //Create the com.sun.star.configuration.ConfigurationUpdateAccess |
| //for the registry node which contains the data for our option |
| //pages. |
| XMultiServiceFactory xConfig; |
| try { |
| xConfig = (XMultiServiceFactory) UnoRuntime.queryInterface( |
| XMultiServiceFactory.class, |
| m_cmpCtx.getServiceManager().createInstanceWithContext( |
| "com.sun.star.configuration.ConfigurationProvider", m_cmpCtx)); |
| } catch (com.sun.star.uno.Exception e) { |
| e.printStackTrace(); |
| return; |
| } |
| |
| //One argument for creating the ConfigurationUpdateAccess is the "nodepath". |
| //Our nodepath point to the node of which the direct subnodes represent the |
| //different options pages. |
| Object[] args = new Object[1]; |
| args[0] = new PropertyValue( |
| "nodepath", 0, "/org.openoffice.desktop.deployment.options.ExtensionData/Leaves", |
| PropertyState.DIRECT_VALUE); |
| |
| //We get the com.sun.star.container.XNameAccess from the instance of |
| //ConfigurationUpdateAccess and save it for later use. |
| try { |
| m_xAccessLeaves = (XNameAccess) UnoRuntime.queryInterface( |
| XNameAccess.class, xConfig.createInstanceWithArguments( |
| "com.sun.star.configuration.ConfigurationUpdateAccess", args)); |
| |
| } catch (com.sun.star.uno.Exception e) { |
| e.printStackTrace(); |
| return; |
| } |
| } |
| |
| /** This method returns an array of all supported service names. |
| * @return Array of supported service names. |
| */ |
| public String[] getSupportedServiceNames() { |
| return getServiceNames(); |
| } |
| |
| /** This method is a simple helper function to used in the |
| * static component initialisation functions as well as in |
| * getSupportedServiceNames. |
| */ |
| public static String[] getServiceNames() { |
| String[] sSupportedServiceNames = { __serviceName }; |
| return sSupportedServiceNames; |
| } |
| |
| /** This method returns true, if the given service will be |
| * supported by the component. |
| * @param sServiceName Service name. |
| * @return True, if the given service name will be supported. |
| */ |
| public boolean supportsService( String sServiceName ) { |
| return sServiceName.equals( __serviceName ); |
| } |
| |
| /** Return the class name of the component. |
| * @return Class name of the component. |
| */ |
| public String getImplementationName() { |
| return _OptionsEventHandler.class.getName(); |
| } |
| |
| //XContainerWindowEventHandler |
| public boolean callHandlerMethod(com.sun.star.awt.XWindow aWindow, |
| Object aEventObject, String sMethod) |
| throws WrappedTargetException { |
| if (sMethod.equals("external_event") ){ |
| try { |
| return handleExternalEvent(aWindow, aEventObject); |
| } catch (com.sun.star.uno.RuntimeException re) { |
| throw re; |
| } catch (com.sun.star.uno.Exception e) { |
| throw new WrappedTargetException(sMethod, this, e); |
| } |
| } |
| |
| return true; |
| } |
| |
| //XContainerWindowEventHandler |
| public String[] getSupportedMethodNames() { |
| return new String[] {"external_event"}; |
| } |
| |
| private boolean handleExternalEvent(com.sun.star.awt.XWindow aWindow, Object aEventObject) |
| throws com.sun.star.uno.Exception { |
| try { |
| String sMethod = AnyConverter.toString(aEventObject); |
| if (sMethod.equals("ok")) { |
| saveData(aWindow); |
| } else if (sMethod.equals("back") || sMethod.equals("initialize")) { |
| loadData(aWindow); |
| } |
| } catch (com.sun.star.lang.IllegalArgumentException e) { |
| throw new com.sun.star.lang.IllegalArgumentException( |
| "Method external_event requires a string in the event object argument.", |
| this, (short) -1); |
| } |
| |
| return true; |
| } |
| |
| private void saveData(com.sun.star.awt.XWindow aWindow) |
| throws com.sun.star.lang.IllegalArgumentException, |
| com.sun.star.uno.Exception { |
| |
| //Determine the name of the options page. This serves two purposes. First, if this |
| //options page is supported by this handler and second we use the name two locate |
| //the corresponding data in the registry. |
| String sWindowName = getWindowName(aWindow); |
| if (sWindowName == null) |
| throw new com.sun.star.lang.IllegalArgumentException( |
| "This window is not supported by this handler", this, (short) -1); |
| |
| //To access the separate controls of the window we need to obtain the |
| //XControlContainer from the window implementation |
| XControlContainer xContainer = (XControlContainer) UnoRuntime.queryInterface( |
| XControlContainer.class, aWindow); |
| if (xContainer == null) |
| throw new com.sun.star.uno.Exception( |
| "Could not get XControlContainer from window.", this); |
| |
| //This is an implementation which will be used for several options pages |
| //which all have the same controls. m_arStringControls is an array which |
| //contains the names. |
| for (int i = 0; i < m_arStringControls.length; i++) { |
| |
| //To obtain the data from the controls we need to get their model. |
| //First get the respective control from the XControlContainer. |
| XControl xControl = xContainer.getControl(m_arStringControls[i]); |
| |
| //This generic handler and the corresponding registry schema support |
| //up to five text controls. However, if a options page does not use all |
| //five controls then we will not complain here. |
| if (xControl == null) |
| continue; |
| |
| //From the control we get the model, which in turn supports the |
| //XPropertySet interface, which we finally use to get the data from |
| //the control. |
| XPropertySet xProp = (XPropertySet) UnoRuntime.queryInterface( |
| XPropertySet.class, xControl.getModel()); |
| |
| if (xProp == null) |
| throw new com.sun.star.uno.Exception( |
| "Could not get XPropertySet from control.", this); |
| //Get the "Text" property. |
| Object aText = xProp.getPropertyValue("Text"); |
| String sValue = null; |
| |
| //The value is still contained in a com.sun.star.uno.Any - so convert it. |
| try { |
| sValue = AnyConverter.toString(aText); |
| } catch (com.sun.star.lang.IllegalArgumentException e) { |
| throw new com.sun.star.lang.IllegalArgumentException( |
| "Wrong property type.", this, (short) -1); |
| } |
| |
| //Now we have the actual string value of the control. What we need now is |
| //the XPropertySet of the respective property in the registry, so that we |
| //can store the value. |
| //To access the registry we have previously created a service instance |
| //of com.sun.star.configuration.ConfigurationUpdateAccess which supports |
| //com.sun.star.container.XNameAccess. The XNameAccess is used to get the |
| //particular registry node which represents this options page. |
| //Fortunately the name of the window is the same as the registry node. |
| XPropertySet xLeaf = (XPropertySet) UnoRuntime.queryInterface( |
| XPropertySet.class, m_xAccessLeaves.getByName(sWindowName)); |
| if (xLeaf == null) |
| throw new com.sun.star.uno.Exception( |
| "XPropertySet not supported.", this); |
| |
| //Finally we can set the value |
| xLeaf.setPropertyValue(m_arStringControls[i], sValue); |
| } |
| |
| //Committing the changes will cause or changes to be written to the registry. |
| XChangesBatch xUpdateCommit = |
| (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class, m_xAccessLeaves); |
| xUpdateCommit.commitChanges(); |
| } |
| |
| private void loadData(com.sun.star.awt.XWindow aWindow) |
| throws com.sun.star.uno.Exception { |
| |
| //Determine the name of the window. This serves two purposes. First, if this |
| //window is supported by this handler and second we use the name two locate |
| //the corresponding data in the registry. |
| String sWindowName = getWindowName(aWindow); |
| if (sWindowName == null) |
| throw new com.sun.star.lang.IllegalArgumentException( |
| "The window is not supported by this handler", this, (short) -1); |
| |
| //To acces the separate controls of the window we need to obtain the |
| //XControlContainer from window implementation |
| XControlContainer xContainer = (XControlContainer) UnoRuntime.queryInterface( |
| XControlContainer.class, aWindow); |
| if (xContainer == null) |
| throw new com.sun.star.uno.Exception( |
| "Could not get XControlContainer from window.", this); |
| |
| //This is an implementation which will be used for several options pages |
| //which all have the same controls. m_arStringControls is an array which |
| //contains the names. |
| for (int i = 0; i < m_arStringControls.length; i++) { |
| |
| //load the values from the registry |
| //To access the registry we have previously created a service instance |
| //of com.sun.star.configuration.ConfigurationUpdateAccess which supports |
| //com.sun.star.container.XNameAccess. We obtain now the section |
| //of the registry which is assigned to this options page. |
| XPropertySet xLeaf = (XPropertySet) UnoRuntime.queryInterface( |
| XPropertySet.class, m_xAccessLeaves.getByName(sWindowName)); |
| if (xLeaf == null) |
| throw new com.sun.star.uno.Exception( |
| "XPropertySet not supported.", this); |
| |
| //The properties in the registry have the same name as the respective |
| //controls. We use the names now to obtain the property values. |
| Object aValue = xLeaf.getPropertyValue(m_arStringControls[i]); |
| |
| //Now that we have the value we need to set it at the corresponding |
| //control in the window. The XControlContainer, which we obtained earlier |
| //is the means to get hold of all the controls. |
| XControl xControl = xContainer.getControl(m_arStringControls[i]); |
| |
| //This generic handler and the corresponding registry schema support |
| //up to five text controls. However, if a options page does not use all |
| //five controls then we will not complain here. |
| if (xControl == null) |
| continue; |
| |
| //From the control we get the model, which in turn supports the |
| //XPropertySet interface, which we finally use to set the data at the |
| //control |
| XPropertySet xProp = (XPropertySet) UnoRuntime.queryInterface( |
| XPropertySet.class, xControl.getModel()); |
| |
| if (xProp == null) |
| throw new com.sun.star.uno.Exception( |
| "Could not get XPropertySet from control.", this); |
| |
| //This handler supports only text controls, which are named "Pattern Field" |
| //in the dialog editor. We set the "Text" property. |
| xProp.setPropertyValue("Text", aValue); |
| } |
| } |
| |
| //Checks if the name property of the window is one of the supported names and returns |
| //always a valid string or null |
| private String getWindowName(com.sun.star.awt.XWindow aWindow) |
| throws com.sun.star.uno.Exception { |
| |
| if (aWindow == null) |
| new com.sun.star.lang.IllegalArgumentException( |
| "Method external_event requires that a window is passed as argument", |
| this, (short) -1); |
| |
| //We need to get the control model of the window. Therefore the first step is |
| //to query for it. |
| XControl xControlDlg = (XControl) UnoRuntime.queryInterface( |
| XControl.class, aWindow); |
| |
| if (xControlDlg == null) |
| throw new com.sun.star.uno.Exception( |
| "Cannot obtain XControl from XWindow in method external_event."); |
| //Now get model |
| XControlModel xModelDlg = xControlDlg.getModel(); |
| |
| if (xModelDlg == null) |
| throw new com.sun.star.uno.Exception( |
| "Cannot obtain XControlModel from XWindow in method external_event.", this); |
| //The model itself does not provide any information except that its |
| //implementation supports XPropertySet which is used to access the data. |
| XPropertySet xPropDlg = (XPropertySet) UnoRuntime.queryInterface( |
| XPropertySet.class, xModelDlg); |
| if (xPropDlg == null) |
| throw new com.sun.star.uno.Exception( |
| "Cannot obtain XPropertySet from window in method external_event.", this); |
| |
| //Get the "Name" property of the window |
| Object aWindowName = xPropDlg.getPropertyValue("Name"); |
| |
| //Get the string from the returned com.sun.star.uno.Any |
| String sName = null; |
| try { |
| sName = AnyConverter.toString(aWindowName); |
| } catch (com.sun.star.lang.IllegalArgumentException e) { |
| throw new com.sun.star.uno.Exception( |
| "Name - property of window is not a string.", this); |
| } |
| |
| //Eventually we can check if we this handler can "handle" this options page. |
| //The class has a member m_arWindowNames which contains all names of windows |
| //for which it is intended |
| for (int i = 0; i < m_arWindowNames.length; i++) { |
| if (m_arWindowNames[i].equals(sName)) { |
| return sName; |
| } |
| } |
| return null; |
| } |
| } |
| |
| |
| /** |
| * Gives a factory for creating the service. |
| * This method is called by the <code>JavaLoader</code> |
| * <p> |
| * @return returns a <code>XSingleComponentFactory</code> for creating |
| * the component |
| * @param sImplName the name of the implementation for which a |
| * service is desired |
| * @see com.sun.star.comp.loader.JavaLoader |
| */ |
| public static XSingleComponentFactory __getComponentFactory(String sImplName) |
| { |
| XSingleComponentFactory xFactory = null; |
| |
| if ( sImplName.equals( _OptionsEventHandler.class.getName() ) ) |
| xFactory = Factory.createComponentFactory(_OptionsEventHandler.class, |
| _OptionsEventHandler.getServiceNames()); |
| |
| return xFactory; |
| } |
| |
| /** |
| * Writes the service information into the given registry key. |
| * This method is called by the <code>JavaLoader</code> |
| * <p> |
| * @return returns true if the operation succeeded |
| * @param regKey the registryKey |
| * @see com.sun.star.comp.loader.JavaLoader |
| */ |
| public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { |
| return Factory.writeRegistryServiceInfo(_OptionsEventHandler.class.getName(), |
| _OptionsEventHandler.getServiceNames(), |
| regKey); |
| } |
| |
| /** This method is a member of the interface for initializing an object |
| * directly after its creation. |
| * @param object This array of arbitrary objects will be passed to the |
| * component after its creation. |
| * @throws Exception Every exception will not be handled, but will be |
| * passed to the caller. |
| */ |
| public void initialize( Object[] object ) |
| throws com.sun.star.uno.Exception { |
| } |
| |
| } |