diff options
Diffstat (limited to 'odk/examples/DevelopersGuide/OfficeDev')
75 files changed, 13038 insertions, 0 deletions
diff --git a/odk/examples/DevelopersGuide/OfficeDev/Clipboard/Clipboard.java b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/Clipboard.java new file mode 100644 index 000000000..742fed8ed --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/Clipboard.java @@ -0,0 +1,212 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.uno.XComponentContext; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.frame.Desktop; +import com.sun.star.frame.XDesktop2; +import com.sun.star.datatransfer.DataFlavor; +import com.sun.star.datatransfer.UnsupportedFlavorException; +import com.sun.star.datatransfer.XTransferable; +import com.sun.star.datatransfer.clipboard.XClipboard; +import com.sun.star.datatransfer.clipboard.SystemClipboard; +import com.sun.star.datatransfer.clipboard.XSystemClipboard; +import com.sun.star.text.XTextDocument; +import com.sun.star.uno.AnyConverter; + + +// Demonstrates the usage of the clipboard service + + +public class Clipboard +{ + public static void main(String[] args) + { + try + { + // get the remote office context. If necessary a new office + // process is started + XComponentContext xOfficeContext = + com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + + // create a new test document + XDesktop2 xDesktop = Desktop.create(xOfficeContext); + com.sun.star.lang.XComponent xComponent = + xDesktop.loadComponentFromURL("private:factory/swriter", + "_blank", 0, new com.sun.star.beans.PropertyValue[0]); + { + XTextDocument xDoc =UnoRuntime.queryInterface(XTextDocument.class, xComponent); + xDoc.getText().setString("In the first step, paste the current content of the clipboard in the document!\nThe text \"Hello world!\" shall be insert at the current cursor position below.\n\nIn the second step, please select some words and put it into the clipboard! ...\n\nCurrent clipboard content = "); + + // ensure that the document content is optimal visible + com.sun.star.frame.XModel xModel = + UnoRuntime.queryInterface( + com.sun.star.frame.XModel.class, xDoc); + // get the frame for later usage + com.sun.star.frame.XFrame xFrame = + xModel.getCurrentController().getFrame(); + + com.sun.star.view.XViewSettingsSupplier xViewSettings = + UnoRuntime.queryInterface( + com.sun.star.view.XViewSettingsSupplier.class, + xModel.getCurrentController()); + xViewSettings.getViewSettings().setPropertyValue( + "ZoomType", Short.valueOf((short)0)); + } + // test document will be closed later + + XSystemClipboard xClipboard = SystemClipboard.create(xOfficeContext); + + + // registering as clipboard listener + + + ClipboardListener aClipListener= new ClipboardListener(); + + xClipboard.addClipboardListener(aClipListener); + + // Read ClipBoard + readClipBoard(xClipboard); + + + // becoming a clipboard owner + + + System.out.println("Becoming a clipboard owner..."); + System.out.println(""); + + ClipboardOwner aClipOwner = new ClipboardOwner(); + xClipboard.setContents(new TextTransferable("Hello World!"), aClipOwner); + int iFirst = 0; + + while (aClipOwner.isClipboardOwner()) + { + if (iFirst != 2) { + if (iFirst == 1) { + System.out.println("Change clipboard ownership by putting something into the clipboard!\n"); + System.out.print("Still clipboard owner..."); + } else { + System.out.println("Still clipboard owner..."); + } + ++iFirst; + } else { + System.out.print("."); + } + Thread.sleep(1000); + } + + // Read ClipBoard again + readClipBoard(xClipboard); + + + // unregistering as clipboard listener + + xClipboard.removeClipboardListener(aClipListener); + + // close test document + com.sun.star.util.XCloseable xCloseable = UnoRuntime.queryInterface(com.sun.star.util.XCloseable.class, + xComponent ); + + if (xCloseable != null ) { + xCloseable.close(false); + } else + { + xComponent.dispose(); + } + + System.exit(0); + } + catch( Exception ex ) + { + ex.printStackTrace(); + } + } + + public static void readClipBoard(XClipboard xClipboard) + throws java.lang.Exception + { + + // get a list of formats currently on the clipboard + + + XTransferable xTransferable = xClipboard.getContents(); + + DataFlavor[] aDflvArr = xTransferable.getTransferDataFlavors(); + + // print all available formats + + System.out.println("Reading the clipboard..."); + System.out.println("Available clipboard formats:"); + + DataFlavor aUniFlv = null; + + for (int i=0;i<aDflvArr.length;i++) + { + System.out.println( "MimeType: " + + aDflvArr[i].MimeType + + " HumanPresentableName: " + + aDflvArr[i].HumanPresentableName ); + + // if there is the format unicode text on the clipboard save the + // corresponding DataFlavor so that we can later output the string + + if ( aDflvArr[i].MimeType.equals("text/plain;charset=utf-16") ) + { + aUniFlv = aDflvArr[i]; + } + } + + System.out.println(""); + + try + { + if (aUniFlv != null) + { + System.out.print("Unicode text on the clipboard ...\nYour selected text \""); + Object aData = xTransferable.getTransferData(aUniFlv); + System.out.println(AnyConverter.toString(aData) + + "\" is now in the clipboard.\n"); + } + } + catch( UnsupportedFlavorException ex ) + { + System.err.println( "Requested format is not available on the clipboard!" ); + ex.printStackTrace(); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Clipboard/ClipboardListener.java b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/ClipboardListener.java new file mode 100644 index 000000000..b6af51602 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/ClipboardListener.java @@ -0,0 +1,58 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.lang.EventObject; +import com.sun.star.datatransfer.clipboard.ClipboardEvent; +import com.sun.star.datatransfer.clipboard.XClipboardListener; + + +// A simple clipboard listener + + +public class ClipboardListener implements XClipboardListener +{ + public void disposing(EventObject event) + { + } + + public void changedContents(ClipboardEvent event) + { + System.out.println(""); + System.out.println("Clipboard content has changed!"); + System.out.println(""); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Clipboard/ClipboardOwner.java b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/ClipboardOwner.java new file mode 100644 index 000000000..f3b3c8087 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/ClipboardOwner.java @@ -0,0 +1,63 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.datatransfer.XTransferable; +import com.sun.star.datatransfer.clipboard.XClipboard; +import com.sun.star.datatransfer.clipboard.XClipboardOwner; + + +// A simple clipboard owner + + +public class ClipboardOwner implements XClipboardOwner +{ + public void lostOwnership( XClipboard xClipboard, XTransferable xTransferable ) + { + System.out.println(""); + System.out.println( "Lost clipboard ownership..." ); + System.out.println(""); + + isowner = false; + } + + public boolean isClipboardOwner() + { + return isowner; + } + + private boolean isowner = true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Clipboard/Makefile b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/Makefile new file mode 100644 index 000000000..90884f2f4 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/Makefile @@ -0,0 +1,98 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevClipboard example of the Developers Guide. + +PRJ=../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevClipboardExample +OUT_APP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +APP1_NAME=Clipboard +APP1_JAR=$(OUT_APP_CLASS)/$(APP1_NAME).jar + +APP1_JAVAFILES = \ + Clipboard.java \ + ClipboardListener.java \ + ClipboardOwner.java \ + TextTransferable.java + +APP1_CLASSFILES = $(patsubst %.java,$(OUT_APP_CLASS)/%.class,$(APP1_JAVAFILES)) +APP1_CLASSNAMES = $(patsubst %.java,%.class,$(APP1_JAVAFILES)) + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_APP_CLASS)) + + +# Targets +.PHONY: ALL +ALL : $(EXAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(APP1_CLASSFILES) : $(APP1_JAVAFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $^ + +$(OUT_APP_CLASS)/%.mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: $*>> $@ + +$(APP1_JAR) : $(OUT_APP_CLASS)/$(APP1_NAME).mf $(APP1_CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(basename $(@F)).mf $(APP1_CLASSNAMES) + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + +$(EXAMPLE_NAME) : $(APP1_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following command to execute the example! + @echo - + @echo $(MAKE) $(APP1_NAME).run + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_APP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_CLASS)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/Clipboard/TextTransferable.java b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/TextTransferable.java new file mode 100644 index 000000000..82a2b316a --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Clipboard/TextTransferable.java @@ -0,0 +1,88 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.datatransfer.DataFlavor; +import com.sun.star.datatransfer.UnsupportedFlavorException; +import com.sun.star.datatransfer.XTransferable; +import com.sun.star.uno.Type; + + +// A simple transferable containing only +// one format, unicode text + + +public class TextTransferable implements XTransferable +{ + public TextTransferable(String aText) + { + text = aText; + } + + // XTransferable methods + + public Object getTransferData(DataFlavor aFlavor) throws UnsupportedFlavorException + { + if ( !aFlavor.MimeType.equalsIgnoreCase( UNICODE_CONTENT_TYPE ) ) + throw new UnsupportedFlavorException(); + + return text; + } + + public DataFlavor[] getTransferDataFlavors() + { + DataFlavor[] adf = new DataFlavor[1]; + + DataFlavor uniflv = new DataFlavor( + UNICODE_CONTENT_TYPE, + "Unicode Text", + new Type(String.class) ); + + adf[0] = uniflv; + + return adf; + } + + public boolean isDataFlavorSupported(DataFlavor aFlavor) + { + return aFlavor.MimeType.equalsIgnoreCase(UNICODE_CONTENT_TYPE); + } + +// members + + private final String text; + private static final String UNICODE_CONTENT_TYPE = "text/plain;charset=utf-16"; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/ContextMenuInterceptor.java b/odk/examples/DevelopersGuide/OfficeDev/ContextMenuInterceptor.java new file mode 100644 index 000000000..d73554972 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/ContextMenuInterceptor.java @@ -0,0 +1,253 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.beans.XPropertySet; +import com.sun.star.ui.ActionTriggerSeparatorType; +import com.sun.star.ui.ContextMenuInterceptorAction; +import com.sun.star.ui.XContextMenuInterceptor; +import com.sun.star.uno.UnoRuntime; + +public class ContextMenuInterceptor implements XContextMenuInterceptor { + + /** + *Description of the Method + * + *@param args Description of Parameter + */ + public static void main(String args[]) + { + try { + OfficeConnect aConnect = OfficeConnect.createConnection(); + + com.sun.star.frame.XDesktop xDesktop = + aConnect.createRemoteInstance( + com.sun.star.frame.XDesktop.class,"com.sun.star.frame.Desktop"); + + // create a new test document + com.sun.star.frame.XComponentLoader xCompLoader = + UnoRuntime.queryInterface( + com.sun.star.frame.XComponentLoader.class, xDesktop); + + com.sun.star.lang.XComponent xComponent = + xCompLoader.loadComponentFromURL("private:factory/swriter", + "_blank", 0, new com.sun.star.beans.PropertyValue[0]); + + // initialize the test document + com.sun.star.frame.XFrame xFrame = null; + { + com.sun.star.text.XTextDocument xDoc =UnoRuntime.queryInterface(com.sun.star.text.XTextDocument.class, + xComponent); + + String infoMsg = "All context menus of the created document frame contains now a 'Help' entry with the submenus 'Content', 'Help on Help' and 'Tips'.\n\nPress 'Return' in the shell to remove the context menu interceptor and finish the example!"; + xDoc.getText().setString(infoMsg); + + // ensure that the document content is optimal visible + com.sun.star.frame.XModel xModel = + UnoRuntime.queryInterface( + com.sun.star.frame.XModel.class, xDoc); + // get the frame for later usage + xFrame = xModel.getCurrentController().getFrame(); + + com.sun.star.view.XViewSettingsSupplier xViewSettings = + UnoRuntime.queryInterface( + com.sun.star.view.XViewSettingsSupplier.class, xModel.getCurrentController()); + xViewSettings.getViewSettings().setPropertyValue( + "ZoomType", Short.valueOf((short)0)); + } + // test document will be closed later + + // reuse the frame + com.sun.star.frame.XController xController = xFrame.getController(); + if ( xController != null ) { + com.sun.star.ui.XContextMenuInterception xContextMenuInterception = + UnoRuntime.queryInterface( + com.sun.star.ui.XContextMenuInterception.class, xController ); + if( xContextMenuInterception != null ) { + ContextMenuInterceptor aContextMenuInterceptor = new ContextMenuInterceptor(); + com.sun.star.ui.XContextMenuInterceptor xContextMenuInterceptor = + UnoRuntime.queryInterface( + com.sun.star.ui.XContextMenuInterceptor.class, aContextMenuInterceptor ); + xContextMenuInterception.registerContextMenuInterceptor( xContextMenuInterceptor ); + + System.out.println( "\n ... all context menus of the created document frame contains now a 'Help' entry with the\n submenus 'Content', 'Help on Help' and 'Tips'.\n\nPress 'Return' to remove the context menu interceptor and finish the example!"); + + java.io.BufferedReader reader + = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); + reader.read(); + + xContextMenuInterception.releaseContextMenuInterceptor( + xContextMenuInterceptor ); + System.out.println( " ... context menu interceptor removed!" ); + } + } + + // close test document + com.sun.star.util.XCloseable xCloseable = UnoRuntime.queryInterface(com.sun.star.util.XCloseable.class, + xComponent ); + + if (xCloseable != null ) { + xCloseable.close(false); + } else + { + xComponent.dispose(); + } + } + catch ( com.sun.star.uno.RuntimeException ex ) { + // something strange has happened! + System.out.println( " Sample caught exception! " + ex ); + System.exit(1); + } + catch ( java.lang.Exception ex ) { + // catch java exceptions and do something useful + System.out.println( " Sample caught exception! " + ex ); + System.exit(1); + } + + System.out.println(" ... exit!\n"); + System.exit( 0 ); + } + + /** + *Description of the Method + */ + public ContextMenuInterceptorAction notifyContextMenuExecute( + com.sun.star.ui.ContextMenuExecuteEvent aEvent ) throws RuntimeException { + + try { + + // Retrieve context menu container and query for service factory to + // create sub menus, menu entries and separators + com.sun.star.container.XIndexContainer xContextMenu = aEvent.ActionTriggerContainer; + com.sun.star.lang.XMultiServiceFactory xMenuElementFactory = + UnoRuntime.queryInterface( + com.sun.star.lang.XMultiServiceFactory.class, xContextMenu ); + if ( xMenuElementFactory != null ) { + // create root menu entry and sub menu + com.sun.star.beans.XPropertySet xRootMenuEntry = + UnoRuntime.queryInterface( + com.sun.star.beans.XPropertySet.class, + xMenuElementFactory.createInstance( "com.sun.star.ui.ActionTrigger" )); + + // create a line separator for our new help sub menu + com.sun.star.beans.XPropertySet xSeparator = + UnoRuntime.queryInterface( + com.sun.star.beans.XPropertySet.class, + xMenuElementFactory.createInstance( "com.sun.star.ui.ActionTriggerSeparator" )); + + Short aSeparatorType = Short.valueOf( ActionTriggerSeparatorType.LINE ); + xSeparator.setPropertyValue( "SeparatorType", aSeparatorType ); + + // query sub menu for index container to get access + com.sun.star.container.XIndexContainer xSubMenuContainer = + UnoRuntime.queryInterface( + com.sun.star.container.XIndexContainer.class, + xMenuElementFactory.createInstance( + "com.sun.star.ui.ActionTriggerContainer" )); + + // initialize root menu entry + xRootMenuEntry.setPropertyValue( "Text", "Help"); + xRootMenuEntry.setPropertyValue( "CommandURL", "slot:5410"); + xRootMenuEntry.setPropertyValue( "HelpURL", "5410"); + xRootMenuEntry.setPropertyValue( "SubContainer", xSubMenuContainer ); + + // create menu entries for the new sub menu + + // initialize help/content menu entry + XPropertySet xMenuEntry = UnoRuntime.queryInterface( + XPropertySet.class, xMenuElementFactory.createInstance( + "com.sun.star.ui.ActionTrigger" )); + + xMenuEntry.setPropertyValue( "Text", "Content" ); + xMenuEntry.setPropertyValue( "CommandURL", "slot:5401" ); + xMenuEntry.setPropertyValue( "HelpURL", "5401" ); + + // insert menu entry to sub menu + xSubMenuContainer.insertByIndex( 0, xMenuEntry ); + + // initialize help/help on help + xMenuEntry = UnoRuntime.queryInterface( + com.sun.star.beans.XPropertySet.class, + xMenuElementFactory.createInstance( + "com.sun.star.ui.ActionTrigger" )); + xMenuEntry.setPropertyValue("Text", "Help on Help"); + xMenuEntry.setPropertyValue("CommandURL", "slot:5400"); + xMenuEntry.setPropertyValue("HelpURL", "5400"); + + // insert menu entry to sub menu + xSubMenuContainer.insertByIndex( 1, xMenuEntry ); + + // initialize help/tips + xMenuEntry = UnoRuntime.queryInterface( + com.sun.star.beans.XPropertySet.class, + xMenuElementFactory.createInstance( + "com.sun.star.ui.ActionTrigger" )); + xMenuEntry.setPropertyValue( "Text", "Tips" ); + xMenuEntry.setPropertyValue( "CommandURL", "slot:5404" ); + xMenuEntry.setPropertyValue( "HelpURL", "5404" ); + + // insert menu entry to sub menu + xSubMenuContainer.insertByIndex( 2, xMenuEntry ); + + // add separator into the given context menu + xContextMenu.insertByIndex( 0, xSeparator ); + + // add new sub menu into the given context menu + xContextMenu.insertByIndex( 0, xRootMenuEntry ); + + // The controller should execute the modified context menu and stop notifying other + // interceptors. + return com.sun.star.ui.ContextMenuInterceptorAction.EXECUTE_MODIFIED; + } + } + catch ( com.sun.star.beans.UnknownPropertyException ex ) { + // do something useful + // we used an unknown property + } + catch ( com.sun.star.lang.IndexOutOfBoundsException ex ) { + // do something useful + // we used an invalid index for accessing a container + } + catch ( com.sun.star.uno.Exception ex ) { + // something strange has happened! + } + catch ( java.lang.Exception ex ) { + // catch java exceptions and something useful + } + + return com.sun.star.ui.ContextMenuInterceptorAction.IGNORED; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/CustomizeView.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/CustomizeView.java new file mode 100644 index 000000000..f19429585 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/CustomizeView.java @@ -0,0 +1,285 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import java.awt.*; +import javax.swing.*; +import java.awt.event.*; + +/** + * Makes it possible to change some states of currently loaded + * document (e.g. enable/disable menubar, toolbar, objectbar) + * + */ +public class CustomizeView extends JPanel + implements IShutdownListener +{ + /** + * These const URL's describe feature for toggling some properties of loaded document. + * Dispatch it with the corresponding parameter to the frame. + */ + private static final String FEATUREURL_MENUBAR = "slot:6661" ; + private static final String FEATUREURL_TOOLBAR = "slot:5909" ; + private static final String FEATUREURL_OBJECTBAR = "slot:5905" ; + + private static final String FEATUREPROP_MENUBAR = "MenuBarVisible" ; + private static final String FEATUREPROP_TOOLBAR = "ToolBarVisible" ; + private static final String FEATUREPROP_OBJECTBAR = "ObjectBarVisible" ; + + private static final String ACTION_MENUBAR = "toggle_menu" ; + private static final String ACTION_TOOLBAR = "toggle_toolbar" ; + private static final String ACTION_OBJECTBAR = "toggle_objectbar" ; + + private static final String MENUBAR_ON = "menubar on" ; + private static final String TOOLBAR_ON = "toolbar on" ; + private static final String OBJECTBAR_ON = "objectbar on" ; + + private static final String MENUBAR_OFF = "menubar off" ; + private static final String TOOLBAR_OFF = "toolbar off" ; + private static final String OBJECTBAR_OFF = "objectbar off" ; + + + // member + + /** + * @member m_cbMenuBar reference to checkbox for toggling menubar + * @member m_cbToolBar reference to checkbox for toggling toolbar + * @member m_cbObjectBar reference to checkbox for toggling objectbar + * + * @member m_aMenuBarListener listener for status events of the menu bar + * @member m_aToolBarListener listener for status events of the tool bar + * @member m_aObjectBarListener listener for status events of the object bar + */ + private final JCheckBox m_cbMenuBar ; + private final JCheckBox m_cbToolBar ; + private final JCheckBox m_cbObjectBar ; + + private StatusListener m_aMenuBarListener ; + private StatusListener m_aToolBarListener ; + private StatusListener m_aObjectBarListener; + + + + /** + * ctor + * Create view controls on startup and initialize it. + * We don't start listening here. see setFrame()! + */ + CustomizeView() + { + this.setLayout(new GridLayout(3,0)); + + m_cbMenuBar = new JCheckBox(MENUBAR_OFF , false); + m_cbToolBar = new JCheckBox(TOOLBAR_OFF , false); + m_cbObjectBar = new JCheckBox(OBJECTBAR_OFF, false); + + m_cbMenuBar.setEnabled (false); + m_cbToolBar.setEnabled (false); + m_cbObjectBar.setEnabled(false); + + m_cbMenuBar.setActionCommand (ACTION_MENUBAR ); + m_cbToolBar.setActionCommand (ACTION_TOOLBAR ); + m_cbObjectBar.setActionCommand(ACTION_OBJECTBAR); + + this.add(m_cbMenuBar ); + this.add(m_cbToolBar ); + this.add(m_cbObjectBar); + } + + + + /** + * set new frame for this view + * We start listening for frame action/status and click events instandly. + * If an event occurs, we use it to synchronize our controls + * with states of a (maybe) new document view of this frame. + * + * @param xFrame + * the reference to the frame, which provides the + * possibility to get the required status information + * + * Attention: We don't accept new frames here. + * We get one after startup and work with it. + * That's it! + */ + public void setFrame(com.sun.star.frame.XFrame xFrame) + { + if (xFrame==null) + return; + + // be listener for click events + // They will toggle the UI controls. + ClickListener aMenuBarHandler = new ClickListener(FEATUREURL_MENUBAR ,FEATUREPROP_MENUBAR ,xFrame); + ClickListener aToolBarHandler = new ClickListener(FEATUREURL_TOOLBAR ,FEATUREPROP_TOOLBAR ,xFrame); + ClickListener aObjectBarHandler = new ClickListener(FEATUREURL_OBJECTBAR,FEATUREPROP_OBJECTBAR,xFrame); + + m_cbMenuBar.addActionListener (aMenuBarHandler ); + m_cbToolBar.addActionListener (aToolBarHandler ); + m_cbObjectBar.addActionListener(aObjectBarHandler); + + // be frame action listener + // The callback will update listener connections + // for status updates automatically! + m_aMenuBarListener = new StatusListener(m_cbMenuBar ,MENUBAR_ON ,MENUBAR_OFF ,xFrame, FEATUREURL_MENUBAR ); + m_aToolBarListener = new StatusListener(m_cbToolBar ,TOOLBAR_ON ,TOOLBAR_OFF ,xFrame, FEATUREURL_TOOLBAR ); + m_aObjectBarListener = new StatusListener(m_cbObjectBar,OBJECTBAR_ON,OBJECTBAR_OFF,xFrame, FEATUREURL_OBJECTBAR); + + m_aMenuBarListener.startListening(); + m_aToolBarListener.startListening(); + m_aObjectBarListener.startListening(); + } + + + + /* + * react for click events of the used check boxes + * We use our internal set dispatch objects to + * call it. This calls toggle the menu/object- or toolbar. + * Note: Because we are listener status events too - hopefully + * we get a notification, if toggling was successfully or not. + * We use this information to update our check boxes again. + * But such update doesn't force (hopefully) an action event. Otherwise + * we can produce a never ending recursion! + */ + private class ClickListener implements ActionListener, + com.sun.star.lang.XEventListener + { + /// URL, to toggle the requested UI item + private final String m_sURL; + /// name of the property which must be used in combination with the URL + private final String m_sProp; + /// we must use this frame to dispatch a request + private com.sun.star.frame.XFrame m_xFrame; + + + + /** + * ctor + * It initialize an instance of this class only. + */ + private ClickListener( String sURL , + String sProp , + com.sun.star.frame.XFrame xFrame ) + { + m_sURL = sURL ; + m_sProp = sProp ; + m_xFrame = xFrame; + } + + + + /** + * callback for action events + * Such events occur, if someone clicked the + * JCheckBox control, on which we are registered. + * Such events do not occur, if we set it programmatically + * (e.g. if we get status events to -> see class StatusListener too) + * + * @param aEvent + * describes the check box and its state + * we can use to toggle the requested office + * resource. + */ + public void actionPerformed(ActionEvent aEvent) + { + synchronized(this) + { + if (m_xFrame==null) + return; + } + + // define parameters for following dispatch + boolean bState = ((JCheckBox)aEvent.getSource()).isSelected(); + + // prepare the dispatch + com.sun.star.util.URL aURL = FunctionHelper.parseURL(m_sURL); + if (aURL==null) + return; + + com.sun.star.beans.PropertyValue[] lProperties = new com.sun.star.beans.PropertyValue[1]; + lProperties[0] = new com.sun.star.beans.PropertyValue(); + lProperties[0].Name = m_sProp; + lProperties[0].Value = Boolean.valueOf(bState); + + // execute (dispatch) it into the frame + if (m_xFrame==null) + return; + FunctionHelper.execute(m_xFrame,aURL,lProperties,null); + } + + + + /** + * callback for disposing events + * Internally we save a reference to an office frame. + * Of course he can die and inform us then. We should react + * and forget his reference. + * + * @param aEvent + * describes the source which fire this event + * Must be our internal saved frame. Otherwise + * somewhere know us without a registration ... + */ + public void disposing(com.sun.star.lang.EventObject aEvent) + { + synchronized(this) + { + m_xFrame = null; + } + } + } + + + + /** + * If this java application shutdown - we must cancel all current existing + * listener connections. Otherwise the office will run into some + * DisposedExceptions if it tries to use these forgotten listener references. + * And of course it can die doing that. + * We are registered at a central object to be informed if the VM will exit. + * So we can react. + */ + public void shutdown() + { + m_aMenuBarListener.shutdown(); + m_aToolBarListener.shutdown(); + m_aObjectBarListener.shutdown(); + + m_aMenuBarListener = null; + m_aToolBarListener = null; + m_aObjectBarListener = null; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Desk.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Desk.java new file mode 100644 index 000000000..7ce2682fe --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Desk.java @@ -0,0 +1,93 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +// __________ Implementation __________ + +/** + * TODO + * + */ +public class Desk +{ + + + /** + * main + * Establish connection to a remote office and starts the demo application. + * User can overwrite some of necessary start options by using command line parameters. + * + * syntax: Desk [mode={inplace|outplace}] [file=<filename>] + * + * @param lArguments command line arguments + * mode describe using mode of document view {inplace/outplace} + * default=inplace + * file name of first file which should be open + * default="private:factory/swriter" to open empty writer document + */ + public static void main(String[] lArguments) + { + // Analyze command line parameters. + String sMode = "inplace"; + String sFile = "private:factory/swriter"; + + for(int i=0; i<lArguments.length; ++i) + { + lArguments[i] = lArguments[i].toLowerCase(); + if(lArguments[i].startsWith("mode=")) + sMode = lArguments[i].substring(5); + else + if(lArguments[i].startsWith("file=")) + sFile = lArguments[i].substring(5); + } + + ViewContainer.mbInplace = sMode.equals("inplace"); + + // Connect to remote office. + OfficeConnect.createConnection(); + + // Create first document view. + // This one will register himself at the global + // ViewContainer. Further views will be open + // automatically started from this first one. + DocumentView aView = new DocumentView(); + aView.setVisible(true); + aView.createFrame(); + aView.load(sFile); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/DocumentView.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/DocumentView.java new file mode 100644 index 000000000..57ac4e779 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/DocumentView.java @@ -0,0 +1,428 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import com.sun.star.uno.UnoRuntime; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.border.*; +import java.awt.AWTEvent; +import java.awt.event.WindowEvent; + +// __________ Implementation __________ + +/** + * This implement a java frame which contains + * an office document, shows some status information + * about that, provides simple functionality on it + * (e.g. toggle menubar, save document) and + * react for different situations independent + * (e.g. closing the document from outside). + * Every instance of this class will be a member + * inside the global "ViewContainer" of this java + * demo application which holds all opened views alive. + * + */ +public class DocumentView extends JFrame + implements com.sun.star.lang.XEventListener, // react for Frame::disposing() + IShutdownListener // react for System.exit() +{ + + + /** + * const + * These command strings are used to identify a received action + * of buttons on which we listen for action events. + */ + private static final String COMMAND_OPEN = "open" ; + private static final String COMMAND_SAVE = "save" ; + private static final String COMMAND_EXPORT = "export" ; + private static final String COMMAND_EXIT = "exit" ; + + + + /** + * @member mxFrame office frame which contains the document of this view + * + * @member maStatusView special panel which shows available status information of currently loaded document + * @member maDocumentView use JNI mechanism to plug an office window into our own java UI container (used for inplace mode only!) + * @member maCustomizeView special panel makes it possible to toggle menubar/toolbar or objectbar of loaded document + * @member maInterceptor interceptor thread which intercept "new" menu of office frame to open new frames inside this java application + * + * @member msName unique name of this view (returned by the global ViewContainer during registration) + * + * @member mbOpen button to open documents + * @member mbSave button to save currently loaded document + * @member mbExport button to save currently loaded document in HTML format (if it is possible!) + * @member mbExit button to exit this demo + * + * @member maInterception we try to intercept the file->new menu to open new document inside this java application + */ + private com.sun.star.frame.XFrame mxFrame ; + + private StatusView maStatusView ; + private NativeView maDocumentView ; + private CustomizeView maCustomizeView ; + private Interceptor maInterceptor ; + + private final String msName; + + private final JButton mbtSave; + private final JButton mbtExport; + + private boolean mbDead ; + + + + /** + * ctor + * Create view controls on startup and initialize it with default values. + */ + DocumentView() + { + this.setSize( new Dimension(800,600) ); + + JPanel paMainPanel = (JPanel)this.getContentPane(); + + // create and add command buttons to a panel + // it will be a sub panel of later layouted UI + JButton mbtOpen = new JButton("Open ..." ); + mbtSave = new JButton("Save" ); + mbtExport = new JButton("Save as HTML ..."); + JButton mbtExit = new JButton("Exit" ); + + mbtOpen.setEnabled (true ); + mbtSave.setEnabled (false); + mbtExport.setEnabled(false); + mbtExit.setEnabled (true ); + + mbtOpen.setActionCommand (COMMAND_OPEN ); + mbtSave.setActionCommand (COMMAND_SAVE ); + mbtExport.setActionCommand(COMMAND_EXPORT); + mbtExit.setActionCommand (COMMAND_EXIT ); + + Reactor aListener = new Reactor(); + mbtOpen.addActionListener (aListener); + mbtSave.addActionListener (aListener); + mbtExport.addActionListener(aListener); + mbtExit.addActionListener (aListener); + + JPanel paCommands = new JPanel( new GridLayout(4,0) ); + paCommands.add(mbtOpen); + paCommands.add(mbtSave); + paCommands.add(mbtExport); + paCommands.add(mbtExit); + + // create view to show status information of opened file + maStatusView = new StatusView(); + + // create view for toggle different bar's of document + maCustomizeView = new CustomizeView(); + + paCommands.setBorder ( new TitledBorder(BorderFactory.createEtchedBorder(),"Commands") ); + maStatusView.setBorder ( new TitledBorder(BorderFactory.createEtchedBorder(),"Status Information") ); + maCustomizeView.setBorder( new TitledBorder(BorderFactory.createEtchedBorder(),"Customize Document View") ); + + // layout the whole UI + JPanel paTest = new JPanel(new GridLayout(3,0)); + paTest.add(paCommands ); + paTest.add(maStatusView ); + paTest.add(maCustomizeView); + JScrollPane paScroll = new JScrollPane(); + paScroll.getViewport().add(paTest,null); + + if(ViewContainer.mbInplace) + { + // create view to show opened documents + // This special view is necessary for inplace mode only! + maDocumentView = new NativeView(); + + JSplitPane paSplit = new JSplitPane(); + paSplit.setOneTouchExpandable( true ); + + paSplit.setLeftComponent (maDocumentView); + paSplit.setRightComponent(paScroll ); + + paMainPanel.add(paSplit); + } + else + { + paMainPanel.add(paScroll); + } + + // Register this new view on our global view container. + msName = FunctionHelper.getUniqueFrameName(); + this.setTitle(msName); + ViewContainer.getGlobalContainer().addView(this); + ViewContainer.getGlobalContainer().addListener(this); + // be listener for closing the application + this.enableEvents(AWTEvent.WINDOW_EVENT_MASK); + } + + + + /** + * Create the view frame for showing the office documents on demand. + * Depending on given command line parameter we create + * an office XFrame and initialize it with a window. This + * window can be a pure toolkit window (means toolkit of office!) + * or a plugged java canvas - office window combination. + */ + public void createFrame() + { + // create view frame (as a XFrame!) here + // Look for right view mode set by user command line parameter. + // First try to get a new unambiguous frame name from our global ViewContainer. + if(ViewContainer.mbInplace) + { + // inplace document view can't be initialized without a visible parent window hierarchy! + // So make sure that we are visible in every case! + this.setVisible(true); + mxFrame = FunctionHelper.createViewFrame(msName,maDocumentView); + } + else + mxFrame = FunctionHelper.createViewFrame(msName,null); + + if(mxFrame!=null) + { + // start interception + maInterceptor = new Interceptor(mxFrame); + maInterceptor.startListening(); + + // start listening for status events and actualization + // of our status view + // (of course for our CustomizeView too) + maStatusView.setFrame (mxFrame); + maCustomizeView.setFrame(mxFrame); + + // be listener for closing the remote target view frame + com.sun.star.lang.XComponent xBroadcaster = UnoRuntime.queryInterface( + com.sun.star.lang.XComponent.class, + mxFrame); + + if(xBroadcaster!=null) + xBroadcaster.addEventListener(this); + } + } + + + + /** + * Different ways to load any URL from outside (may be by the command line) + * into this document view or to save it. + */ + public void load(String sURL) + { + load(sURL,new com.sun.star.beans.PropertyValue[0]); + } + + + + public void load(String sURL, com.sun.star.beans.PropertyValue[] lArguments) + { + com.sun.star.lang.XComponent xDocument = FunctionHelper.loadDocument(mxFrame,sURL,lArguments); + if(xDocument!=null) + { + mbtSave.setEnabled (true); + mbtExport.setEnabled(true); + } + else + { + mbtSave.setEnabled (false); + mbtExport.setEnabled(false); + } + } + + + + private void save() + { + com.sun.star.frame.XController xController = mxFrame.getController(); + if (xController==null) + return; + com.sun.star.frame.XModel xDocument = xController.getModel(); + if (xDocument==null) + return; + FunctionHelper.saveDocument(xDocument); + } + + + + private void exportHTML(String sURL) + { + com.sun.star.frame.XController xController = mxFrame.getController(); + if (xController==null) + return; + com.sun.star.frame.XModel xDocument = xController.getModel(); + if (xDocument==null) + return; + FunctionHelper.saveAsHTML(xDocument,sURL); + } + + + + /** + * Overridden so we can react for window closing of this view. + */ + @Override + protected void processWindowEvent(WindowEvent aEvent) + { + if (aEvent.getID()!=WindowEvent.WINDOW_CLOSING) + { + super.processWindowEvent(aEvent); + } + else + if (FunctionHelper.closeFrame(mxFrame)) + { + mxFrame = null; + shutdown(); + super.processWindowEvent(aEvent); + } + } + + + + /** + * Here we can react for System.exit() normally. + * But we use it for disposing() or windowClosing() too. + */ + public void shutdown() + { + if (mbDead) + return; + mbDead=true; + + // force these sub view to release her remote + // references too! + maStatusView.shutdown(); + maCustomizeView.shutdown(); + + maStatusView = null; + maCustomizeView = null; + + // disable all interceptions + maInterceptor.shutdown(); + maInterceptor = null; + + // close the frame and his document + // Releasing of our listener connections for disposing() + // will be forced automatically then. Because the frame + // will call us back ... + if (mxFrame!=null) + FunctionHelper.closeFrame(mxFrame); + + // deregister this view in the global container + // Normally we should die afterwards by garbage collection ... + // In cease this was the last view - it force a system.exit(). + // But then we are no longer a member of the global container + // of possible shutdown listener ... and this method should be + // called again. + ViewContainer.getGlobalContainer().removeView(this); + } + + + + /** + * callback from our internal saved frame + * which wishes to die. It's not necessary to remove listener connections + * here. Because the broadcaster do it automatically. + * We have to release all references to him only. + * + * @param aSource + * describe the broadcaster of this event + * Must be our internal saved frame. + */ + public void disposing(com.sun.star.lang.EventObject aSource) + { + mxFrame = null; + } + + + + /** + * This inner class is used to react for events of our own UI controls. + * So we can start different actions then. + */ + private class Reactor implements ActionListener + { + + + /** + * This method react for pressed buttons or selected check boxes. + */ + public void actionPerformed(ActionEvent aEvent) + { + String sCommand = aEvent.getActionCommand(); + + // open any file from disk + if( sCommand.equals(COMMAND_OPEN) ) + { + String sURL = FunctionHelper.askUserForFileURL(DocumentView.this,true); + if(sURL!=null) + DocumentView.this.load(sURL); + } + else + + // save current document + if( sCommand.equals(COMMAND_SAVE) ) + { + DocumentView.this.save(); + } + else + + // export current document to html + if( sCommand.equals(COMMAND_EXPORT)) + { + String sURL = FunctionHelper.askUserForFileURL(DocumentView.this,false); + if(sURL!=null) + DocumentView.this.exportHTML(sURL); + } + else + + // exit application + if( sCommand.equals(COMMAND_EXIT) ) + { + // This will force deleting of this and + // all other currently opened views automatically! + System.exit(0); + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/FunctionHelper.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/FunctionHelper.java new file mode 100644 index 000000000..fa24cde96 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/FunctionHelper.java @@ -0,0 +1,939 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.AnyConverter; + +import java.awt.*; +import javax.swing.*; +import java.io.*; +import java.net.*; + +// __________ Implementation __________ + +/** + * Is a collection of basic features. + * This helper shows different functionality of framework api + * in an example manner. You can use the follow ones: + * (1) parse URL's + * (2) create frames (inside/outside a java application) + * (3) dispatches (with[out] notifications) + * (4) loading/saving documents + * (5) convert documents to HTML (if possible) + * (6) close documents (and her frames) correctly + * + * There exist some other helper functionality too, which + * doesn't use or demonstrate the office api: + * (a) getting file names by using a file chosser + */ +public class FunctionHelper +{ + + + /** + * This convert a URL (formatted as a string) to a struct com.sun.star.util.URL. + * It use a special service to do that: the URLTransformer. + * Because some API calls need it and it's not allowed to set "Complete" + * part of the util struct only. The URL must be parsed. + * + * @param sURL + * URL for parsing in string notation + * + * @return [com.sun.star.util.URL] + * URL in UNO struct notation + */ + public static com.sun.star.util.URL parseURL(String sURL) + { + com.sun.star.util.URL aURL = null; + + if (sURL==null || sURL.equals("")) + { + System.out.println("wrong using of URL parser"); + return null; + } + + try + { + com.sun.star.uno.XComponentContext xOfficeCtx = + OfficeConnect.getOfficeContext(); + + // Create special service for parsing of given URL. + com.sun.star.util.XURLTransformer xParser = + UnoRuntime.queryInterface( + com.sun.star.util.XURLTransformer.class, + xOfficeCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.util.URLTransformer", xOfficeCtx)); + + // Because it's an in/out parameter we must use an array of URL objects. + com.sun.star.util.URL[] aParseURL = new com.sun.star.util.URL[1]; + aParseURL[0] = new com.sun.star.util.URL(); + aParseURL[0].Complete = sURL; + + // Parse the URL + xParser.parseStrict(aParseURL); + + aURL = aParseURL[0]; + } + catch(com.sun.star.uno.RuntimeException exRuntime) + { + // Any UNO method of this scope can throw this exception. + // Reset the return value only. + } + catch(com.sun.star.uno.Exception exUno) + { + // "createInstance()" method of used service manager can throw it. + // Then it wasn't possible to get the URL transformer. + // Return default instead of really parsed URL. + } + + return aURL; + } + + + + /** + * create a new empty target frame + * Attention: Currently we must use special service com.sun.star.frame.Task instead of Frame. + * Because desktop environment accept this special frame type only as direct children. + * Note - This service will be deprecated and must be replaces by com.sun.star.frame.Frame in + * further versions. To feature prove we use both service names. If for new versions + * the deprecated one not exist we get an empty frame, we can try to use the new service. + * + * @param xSMGR + * we need the remote service manager to create this task/frame service + * + * @return [com.sun.star.frame.XFrame] + * the new created frame reference in case of success or null otherwise + */ + private static com.sun.star.frame.XFrame impl_createEmptyFrame( + com.sun.star.uno.XComponentContext xCtx ) + { + com.sun.star.frame.XFrame xFrame = null; + + try{ + xFrame = UnoRuntime.queryInterface( + com.sun.star.frame.XFrame.class, + xCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.frame.Task", xCtx)); + } catch(com.sun.star.uno.Exception ex1) {} + + if (xFrame==null) + { + try{ + xFrame = UnoRuntime.queryInterface( + com.sun.star.frame.XFrame.class, + xCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.frame.Frame", xCtx)); + } catch(com.sun.star.uno.Exception ex2) {} + } + + return xFrame; + } + + + + /** + * create a new window which can be used as container window of an office frame + * We know two modes for creation: + * - the office window will be a child of one of our java windows + * - the office will be a normal system window outside this java application + * This behaviour will be regulated by the second parameter of this operation. + * If a parentview is given the first mode will be activated - otherwise + * the second one. + * + * Note: First mode (creation of a child window) can be reached by two different + * ways. + * - pack the required window handle of our java window inside a UNO object + * to transport it to the remote office toolkit and get a child office + * window. + * This is the old way. It's better to use the second one - but to be + * future prove this old one should be tried too. + * - it's possible to pass the native window handle directly to the toolkit. + * A special interface method was enabled to accept that. + * + * The right way to create an office window should be then: + * - try to use second creation mode (directly using of the window handle) + * - if it failed ... use the old way by packing the handle inside an object + * + * @param xSMGR + * we need a service manager to be able to create remote office + * services + * + * @param aParentView + * the java window as parent for the office window if an inplace office + * is required. If it is set to null the created office window will be + * a normal system window outside of our java application. + * + * @return [com.sun.star.awt.XWindow] + * The new created office window which can be used to set it as + * a ContainerWindow on an empty office frame. + */ + private static com.sun.star.awt.XWindow impl_createWindow( + com.sun.star.uno.XComponentContext xCtx, NativeView aParentView ) + { + com.sun.star.awt.XWindow xWindow = null; + com.sun.star.awt.XWindowPeer xPeer = null; + com.sun.star.awt.XToolkit xToolkit = null; + + // get access to toolkit of remote office to create the container window of + // new target frame + try{ + xToolkit = UnoRuntime.queryInterface( + com.sun.star.awt.XToolkit.class, + xCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.awt.Toolkit", xCtx)); + } + catch(com.sun.star.uno.Exception ex) + { + return null; + } + + // mode 1) create an external system window + if (aParentView==null) + { + // Describe the properties of the container window. + com.sun.star.awt.WindowDescriptor aDescriptor = + new com.sun.star.awt.WindowDescriptor(); + aDescriptor.Type = com.sun.star.awt.WindowClass.TOP; + aDescriptor.WindowServiceName = "window"; + aDescriptor.ParentIndex = -1; + aDescriptor.Parent = null; + aDescriptor.Bounds = new com.sun.star.awt.Rectangle(0,0,0,0); + aDescriptor.WindowAttributes = com.sun.star.awt.WindowAttribute.BORDER | + com.sun.star.awt.WindowAttribute.MOVEABLE | + com.sun.star.awt.WindowAttribute.SIZEABLE | + com.sun.star.awt.WindowAttribute.CLOSEABLE; + + try{ + xPeer = xToolkit.createWindow( aDescriptor ); + } catch(com.sun.star.lang.IllegalArgumentException exIllegal) {} + } + // mode 2) create an internal office window as child of our given java + // parent window + else + { + // try new version of creation first: directly using of the window + // handle. The old implementation of the corresponding toolkit method + // requires a process ID. If this id isn't the right one a null object + // is returned. But normally nobody outside the office knows this id. + // New version of this method ignore the id parameter and creation will + // work. + // Note: You must be sure if your window handle can be really used by + // the remote office. Means if this java client and the remote office + // use the same display! + com.sun.star.awt.XSystemChildFactory xChildFactory = + UnoRuntime.queryInterface( + com.sun.star.awt.XSystemChildFactory.class, xToolkit); + + try + { + Integer nHandle = aParentView.getHWND(); + short nSystem = (short)aParentView.getNativeWindowSystemType(); + byte[] lProcID = new byte[0]; + + xPeer = xChildFactory.createSystemChild(nHandle, + lProcID, nSystem); + + if (xPeer==null) + { + // mode 3) OK - new version doesn't work. It requires the + // process id which we don't have. + // So we must use the old way to get the right window peer. + // Pack the handle inside a wrapper object. + JavaWindowPeerFake aWrapper = new + JavaWindowPeerFake(aParentView); + + com.sun.star.awt.XWindowPeer xParentPeer = + UnoRuntime.queryInterface( + com.sun.star.awt.XWindowPeer.class, aWrapper); + + com.sun.star.awt.WindowDescriptor aDescriptor = + new com.sun.star.awt.WindowDescriptor(); + aDescriptor.Type = com.sun.star.awt.WindowClass.TOP; + aDescriptor.WindowServiceName = "workwindow"; + aDescriptor.ParentIndex = 1; + aDescriptor.Parent = xParentPeer; + aDescriptor.Bounds = new com.sun.star.awt.Rectangle(0,0,0,0); + if (nSystem == com.sun.star.lang.SystemDependent.SYSTEM_WIN32) + aDescriptor.WindowAttributes = + com.sun.star.awt.WindowAttribute.SHOW; + else + aDescriptor.WindowAttributes = + com.sun.star.awt.WindowAttribute.SYSTEMDEPENDENT; + + try{ + xPeer = xToolkit.createWindow( aDescriptor ); + } catch(com.sun.star.lang.IllegalArgumentException exIllegal) {} + } + } + catch(java.lang.RuntimeException exJRun) + { + // This exception is thrown by the native JNI code if it try to get + // the systemw window handle. A possible reason can be an invisible + // java window. In this case it should be enough to set return + // values to null. All other resources (which was created before) + // will be freed automatically if scope will be leaved. + System.out.println("May be the NativeView object wasn't really visible at calling time of getNativeWindow()?"); + xPeer = null; + xWindow = null; + } + } + + // It doesn't matter which way was used to get the window peer. + // Cast it to the right return interface and return it. + xWindow = UnoRuntime.queryInterface( + com.sun.star.awt.XWindow.class, + xPeer); + + return xWindow; + } + + + + /** + * This method create a new empty child frame on desktop instance of remote office. + * It use a special JNI functionality to pass the office XWindow over a java window. + * This java window can be inserted into another java window container for complex layouting. + * If this parent java window isn't used, a top level system window will be created. + * The resulting office frame isn't plugged into this java application. + * + * @param sName + * name to set it on the new created frame + * + * @param aParentView + * java window which should be used as parent window of new created office frame window + * May be set to null. + * + * @return [com.sun.star.frame.XFrame] + * reference to the new created frame for success or null if it failed + */ + public static com.sun.star.frame.XFrame createViewFrame(String sName, NativeView aParentView) + { + com.sun.star.frame.XFrame xFrame = null; + + try + { + com.sun.star.uno.XComponentContext xCtx = + OfficeConnect.getOfficeContext(); + + // create an empty office frame first + xFrame = impl_createEmptyFrame(xCtx); + + // create an office window then + // Depending from the given parameter aParentView it will be a child or a top level + // system window. (see impl method for further information) + // But before we call this helper - prepare the possible parent window: show it. + // JNI calls to get system window handle of java window can't work without that! + if (aParentView!=null) + aParentView.setVisible(true); + com.sun.star.awt.XWindow xWindow = impl_createWindow(xCtx, aParentView); + + // pass the window the frame as his new container window. + // It's necessary to do it first - before you call anything else there. + // Otherwise the frame throws some exceptions for "uninitialized state". + xFrame.initialize( xWindow ); + + // Insert the new frame in desktop hierarchy. + // Use XFrames interface to do so. It provides access to the child frame container of that instance. + com.sun.star.frame.XFramesSupplier xTreeRoot = UnoRuntime.queryInterface( + com.sun.star.frame.XFramesSupplier.class, + xCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.frame.Desktop", xCtx)); + com.sun.star.frame.XFrames xChildContainer = xTreeRoot.getFrames(); + xChildContainer.append(xFrame); + + // Make some further initializations on frame and window. + xWindow.setVisible(true); + xFrame.setName(sName); + } + catch(com.sun.star.uno.RuntimeException exRuntime) + { + // Any UNO method of this scope can throw this exception. + // So the frame can be already created and he must be freed + // correctly. May be he was inserted into the desktop tree too ... + if(xFrame!=null) + { + // Try to dispose the frame. He should deregister himself at the desktop object + // and free all internal used resources (e.g. the container window) automatically. + // It's possible to do that here - because frame has no component inside yet. + // So nobody can disagree with that. + // After the dispose() call forget all references to this frame and let him die. + // If a new exception will occur ... no general solution exist then. + // Nobody can guarantee if next call will work or not. + com.sun.star.lang.XComponent xComponent = UnoRuntime.queryInterface( + com.sun.star.lang.XComponent.class, + xFrame); + xComponent.dispose(); + xComponent = null; + xFrame = null; + } + } + catch(com.sun.star.uno.Exception exUno) + { + // "createInstance()" method of used service manager can throw it. + // If it occurred during creation of desktop service the frame already was created. + // Free it by decreasing his refcount. Changes on the desktop tree couldn't exist. + // Without the desktop service that wasn't possible. So no further rollbacks must follow. + if(xFrame!=null) + { + com.sun.star.lang.XComponent xComponent = UnoRuntime.queryInterface( + com.sun.star.lang.XComponent.class, + xFrame); + xComponent.dispose(); + xComponent = null; + xFrame = null; + } + } + + return xFrame; + } + + + + /** + * Dispatch a URL to given frame. + * Caller can register himself for following status events for dispatched + * URL too. But nobody guarantee that such notifications will occur. + * (see dispatchWithNotification() if you interest on that) + * The returned dispatch object should be hold alive by caller + * till he doesn't need it any longer. Otherwise the dispatcher can(!) + * die by decreasing his refcount. + * + * @param xFrame frame which should be the target of this dispatch + * @param aURL full parsed and converted office URL for dispatch + * @param lProperties optional arguments for dispatch + * @param xListener optional listener which is registered automatically for status events + * (Note: Deregistration is part of this listener himself!) + * + * @return [XDispatch] It's the used dispatch object and can be used for deregistration of an optional listener. + * Otherwise caller can ignore it. + */ + public static com.sun.star.frame.XDispatch execute(com.sun.star.frame.XFrame xFrame , + com.sun.star.util.URL aURL , + com.sun.star.beans.PropertyValue[] lProperties, + com.sun.star.frame.XStatusListener xListener ) + { + com.sun.star.frame.XDispatch xDispatcher = null; + + try + { + // Query the frame for right interface which provides access to all available dispatch objects. + com.sun.star.frame.XDispatchProvider xProvider = UnoRuntime.queryInterface( + com.sun.star.frame.XDispatchProvider.class, + xFrame); + + // Ask him for right dispatch object for given URL. + // Force given frame as target for following dispatch by using "". + // It means the same like "_self". + xDispatcher = xProvider.queryDispatch(aURL,"",0); + + // Dispatch the URL into the frame. + if(xDispatcher!=null) + { + if(xListener!=null) + xDispatcher.addStatusListener(xListener,aURL); + + xDispatcher.dispatch(aURL,lProperties); + } + } + catch(com.sun.star.uno.RuntimeException exUno) + { + // Any UNO method of this scope can throw this exception. + // But there will be nothing to do then - because + // we haven't changed anything inside the remote objects + // except method "addStatusListener(). + // But in this case the source of this exception has to + // rollback all his operations. There is no chance to + // make anything right then. + // Reset the return value to a default - that's it. + exUno.printStackTrace(); + xDispatcher = null; + } + + return xDispatcher; + } + + + + + + + + /** + * Load document specified by a URL into given frame synchronously. + * The result of this operation will be the loaded document for success + * or null if loading failed. + * + * @param xFrame frame which should be the target of this load call + * @param sURL unparsed URL for loading + * @param lProperties optional arguments + * + * @return [XComponent] the loaded document for success or null if it's failed + */ + public static com.sun.star.lang.XComponent loadDocument( + com.sun.star.frame.XFrame xFrame, String sURL, + com.sun.star.beans.PropertyValue[] lProperties) + { + com.sun.star.lang.XComponent xDocument = null; + String sOldName = null; + + try + { + com.sun.star.uno.XComponentContext xCtx = + OfficeConnect.getOfficeContext(); + + // First prepare frame for loading + // We must address it inside the frame tree without any complications. + // So we set an unambiguous (we hope it) name and use it later. + // Don't forget to reset original name after that. + sOldName = xFrame.getName(); + String sTarget = "odk_officedev_desk"; + xFrame.setName(sTarget); + + // Get access to the global component loader of the office + // for synchronous loading the document. + com.sun.star.frame.XComponentLoader xLoader = + UnoRuntime.queryInterface( + com.sun.star.frame.XComponentLoader.class, + xCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.frame.Desktop", xCtx)); + + // Load the document into the target frame by using his name and + // special search flags. + xDocument = xLoader.loadComponentFromURL( + sURL, + sTarget, + com.sun.star.frame.FrameSearchFlag.CHILDREN, + lProperties); + + // don't forget to restore old frame name... + xFrame.setName(sOldName); + } + catch(com.sun.star.io.IOException exIO) + { + // Can be thrown by "loadComponentFromURL()" call. + // The only thing we should do then is to reset changed frame name! + exIO.printStackTrace(); + xDocument = null; + if(sOldName!=null) + xFrame.setName(sOldName); + } + catch(com.sun.star.lang.IllegalArgumentException exIllegal) + { + // Can be thrown by "loadComponentFromURL()" call. + // The only thing we should do then is to reset changed frame name! + exIllegal.printStackTrace(); + xDocument = null; + if(sOldName!=null) + xFrame.setName(sOldName); + } + catch(com.sun.star.uno.RuntimeException exRuntime) + { + // Any UNO method of this scope can throw this exception. + // The only thing we can try(!) is to reset changed frame name. + exRuntime.printStackTrace(); + xDocument = null; + if(sOldName!=null) + xFrame.setName(sOldName); + } + catch(com.sun.star.uno.Exception exUno) + { + // "createInstance()" method of used service manager can throw it. + // The only thing we should do then is to reset changed frame name! + exUno.printStackTrace(); + xDocument = null; + if(sOldName!=null) + xFrame.setName(sOldName); + } + + return xDocument; + } + + + + /** + * Save currently loaded document of given frame. + * + * @param xDocument document for saving changes + */ + public static void saveDocument(com.sun.star.lang.XComponent xDocument) + { + try + { + // Check for supported model functionality. + // Normally the application documents (text, spreadsheet ...) do so + // but some other ones (e.g. db components) doesn't do that. + // They can't be save then. + com.sun.star.frame.XModel xModel = UnoRuntime.queryInterface( + com.sun.star.frame.XModel.class, + xDocument); + if(xModel!=null) + { + // Check for modifications => break save process if there is nothing to do. + com.sun.star.util.XModifiable xModified = UnoRuntime.queryInterface( + com.sun.star.util.XModifiable.class, + xModel); + if(xModified.isModified()) + { + com.sun.star.frame.XStorable xStore = UnoRuntime.queryInterface( + com.sun.star.frame.XStorable.class, + xModel); + + xStore.store(); + } + } + } + catch(com.sun.star.io.IOException exIO) + { + // Can be thrown by "store()" call. + // But there is nothing we can do then. + exIO.printStackTrace(); + } + catch(com.sun.star.uno.RuntimeException exUno) + { + // Any UNO method of this scope can throw this exception. + // But there is nothing we can do then. + exUno.printStackTrace(); + } + } + + + + /** + * It try to export given document in HTML format. + * Current document will be converted to HTML and moved to new place on disk. + * A "new" file will be created by given URL (may be overwritten + * if it already exist). Right filter will be used automatically if factory of + * this document support it. If no valid filter can be found for export, + * nothing will be done here. + * + * @param xDocument document which should be exported + * @param sURL target URL for converted document + */ + public static void saveAsHTML(com.sun.star.lang.XComponent xDocument, + String sURL ) + { + try + { + // First detect factory of this document. + // Ask for the supported service name of this document. + // If information is available it can be used to find out which + // filter exist for HTML export. Normally this filter should be searched + // inside the filter configuration but this little demo doesn't do so. + // (see service com.sun.star.document.FilterFactory for further + // information too) + // Well known filter names are used directly. They must exist in current + // office installation. Otherwise this code will fail. But to prevent + // this code against missing filters it check for existing state of it. + com.sun.star.lang.XServiceInfo xInfo = UnoRuntime.queryInterface(com.sun.star.lang.XServiceInfo.class, + xDocument); + + if(xInfo!=null) + { + // Find out possible filter name. + String sFilter = null; + if(xInfo.supportsService("com.sun.star.text.TextDocument")) + sFilter = "HTML (StarWriter)"; + else + if(xInfo.supportsService("com.sun.star.text.WebDocument")) + sFilter = "HTML"; + else + if(xInfo.supportsService("com.sun.star.sheet.SpreadsheetDocument")) + sFilter = "HTML (StarCalc)"; + + // Check for existing state of this filter. + if(sFilter!=null) + { + com.sun.star.uno.XComponentContext xCtx = + OfficeConnect.getOfficeContext(); + + com.sun.star.container.XNameAccess xFilterContainer = + UnoRuntime.queryInterface( + com.sun.star.container.XNameAccess.class, + xCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.document.FilterFactory", xCtx)); + + if(!xFilterContainer.hasByName(sFilter)) + sFilter=null; + } + + // Use this filter for export. + if(sFilter!=null) + { + // Export can be forced by saving the document and using a + // special filter name which can write needed format. Build + // necessary argument list now. + // Use special flag "Overwrite" too, to prevent operation + // against possible exceptions, if file already exist. + com.sun.star.beans.PropertyValue[] lProperties = + new com.sun.star.beans.PropertyValue[2]; + lProperties[0] = new com.sun.star.beans.PropertyValue(); + lProperties[0].Name = "FilterName"; + lProperties[0].Value = sFilter; + lProperties[1] = new com.sun.star.beans.PropertyValue(); + lProperties[1].Name = "Overwrite"; + lProperties[1].Value = Boolean.TRUE; + + com.sun.star.frame.XStorable xStore = + UnoRuntime.queryInterface( + com.sun.star.frame.XStorable.class, xDocument); + + xStore.storeAsURL(sURL,lProperties); + } + } + } + catch(com.sun.star.io.IOException exIO) + { + // Can be thrown by "store()" call. + // Do nothing then. Saving failed - that's it. + exIO.printStackTrace(); + } + catch(com.sun.star.uno.RuntimeException exRuntime) + { + // Can be thrown by any uno call. + // Do nothing here. Saving failed - that's it. + exRuntime.printStackTrace(); + } + catch(com.sun.star.uno.Exception exUno) + { + // Can be thrown by "createInstance()" call of service manager. + // Do nothing here. Saving failed - that's it. + exUno.printStackTrace(); + } + } + + + + + + + + /* + * Try to close the frame instead of the document. + * It shows the possible interface to do so. + * + * @param xFrame + * frame which should be closed + * + * @return <TRUE/> in case frame could be closed + * <FALSE/> otherwise + */ + public static boolean closeFrame(com.sun.star.frame.XFrame xFrame) + { + boolean bClosed = false; + + try + { + // first try the new way: use new interface XCloseable + // It replace the deprecated XTask::close() and should be preferred ... + // if it can be queried. + com.sun.star.util.XCloseable xCloseable = + UnoRuntime.queryInterface( + com.sun.star.util.XCloseable.class, xFrame); + if (xCloseable!=null) + { + // We deliver the ownership of this frame not to the (possible) + // source which throw a CloseVetoException. We wish to have it + // under our own control. + try + { + xCloseable.close(false); + bClosed = true; + } + catch( com.sun.star.util.CloseVetoException exVeto ) + { + bClosed = false; + } + } + else + { + // OK: the new way isn't possible. Try the old one. + com.sun.star.frame.XTask xTask = UnoRuntime.queryInterface(com.sun.star.frame.XTask.class, + xFrame); + if (xTask!=null) + { + // return value doesn't interest here. Because + // we forget this task ... + bClosed = xTask.close(); + } + } + } + catch (com.sun.star.lang.DisposedException exDisposed) + { + // Of course - this task can be already dead - means disposed. + // But for us it's not important. Because we tried to close it too. + // And "already disposed" or "closed" should be the same ... + bClosed = true; + } + + return bClosed; + } + + + + /** + * Try to find a unique frame name, which isn't currently used inside + * remote office instance. Because we create top level frames + * only, it's enough to check the names of existing child frames on the + * desktop only. + * + * should represent a unique frame name, which currently isn't + * used inside the remote office frame tree + * (Couldn't guaranteed for a real multithreaded environment. + * But we try it ...) + */ + private static final String BASEFRAMENAME = "Desk View "; + + public static String getUniqueFrameName() + { + String sName = null; + + com.sun.star.uno.XComponentContext xCtx = OfficeConnect.getOfficeContext(); + + try + { + com.sun.star.frame.XFramesSupplier xSupplier = + UnoRuntime.queryInterface( + com.sun.star.frame.XFramesSupplier.class, + xCtx.getServiceManager().createInstanceWithContext( + "com.sun.star.frame.Desktop", xCtx)); + + com.sun.star.container.XIndexAccess xContainer = + UnoRuntime.queryInterface( + com.sun.star.container.XIndexAccess.class, + xSupplier.getFrames()); + + int nCount = xContainer.getCount(); + for (int i=0; i<nCount; ++i ) + { + com.sun.star.frame.XFrame xFrame = (com.sun.star.frame.XFrame)AnyConverter.toObject(new com.sun.star.uno.Type(com.sun.star.frame.XFrame.class), xContainer.getByIndex(i)); + sName = BASEFRAMENAME+mnViewCount; + while(sName.equals(xFrame.getName())) + { + ++mnViewCount; + sName = BASEFRAMENAME+mnViewCount; + } + } + } + catch(com.sun.star.uno.Exception exCreateFailed) + { + sName = BASEFRAMENAME; + } + + if (sName==null) + { + System.out.println("invalid name!"); + sName = BASEFRAMENAME; + } + + return sName; + } + + + + /** + * helper to get a file URL selected by user + * This method doesn't show any API concepts... + * but is necessary for this demo application. + * + * @param aParent parent window of this dialog + * @param bOpen If it is set to true => + * dialog is opened in "file open" mode - + * otherwise in "file save" mode. + */ + public static String askUserForFileURL(Component aParent,boolean bOpen) + { + String sFileURL = null; + int nDecision = JFileChooser.CANCEL_OPTION; + JFileChooser aChooser = null; + + // set last visited directory on new file chosser + // (if this information is available) + if( maLastDir==null ) + aChooser = new JFileChooser(); + else + aChooser = new JFileChooser(maLastDir); + + // decide between file open/save dialog + if( bOpen ) + nDecision = aChooser.showOpenDialog(aParent); + else + nDecision = aChooser.showSaveDialog(aParent); + + // react for "OK" result only + if(nDecision == JFileChooser.APPROVE_OPTION) + { + // save current directory as last visited one + maLastDir = aChooser.getCurrentDirectory(); + // get file URL from the dialog + try + { + sFileURL = aChooser.getSelectedFile().toURI().toURL().toExternalForm(); + } + catch( MalformedURLException ex ) + { + ex.printStackTrace(); + sFileURL = null; + } + // problem of java: file URL's are coded with 1 slash instead of 3 ones! + // => correct this problem first, otherwise office can't use these URL's + if( + ( sFileURL !=null ) && + ( sFileURL.startsWith("file:/") ) && + ( !sFileURL.startsWith("file://") ) + ) + { + StringBuffer sWorkBuffer = new StringBuffer(sFileURL); + sWorkBuffer.insert(6,"//"); + sFileURL = sWorkBuffer.toString(); + } + } + + return sFileURL; + } + + + + /** + * @member maLastDir save the last visited directory of used file open/save dialog + * @member mnViewCount we try to set unique names on every frame we create (that's why we must count it) + */ + private static File maLastDir = null; + private static int mnViewCount = 0 ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/IOnewayLink.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/IOnewayLink.java new file mode 100644 index 000000000..c6732155d --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/IOnewayLink.java @@ -0,0 +1,71 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import java.util.ArrayList; + +// __________ Implementation __________ + +/** + * We need a generic interface to forward any oneway uno interface method + * by using threads to the original object. Reason: + * It's not allowed to call synchronous back to the office if a java object + * was called in a oneway declared interface method. Then it must be + * executed asynchronous. To do so - a thread can be created which use this + * interface. It get the object, which has to be called back and the type and + * parameter of the original request. + * + */ +public interface IOnewayLink +{ + + + /** + * @param nRequest + * The two user of this callback can define a unique number, + * which identify the type of original interface method. So the called + * interface object can decide, which action will be necessary. + * + * @param lParams + * If the original method used parameters, they will be coded here in + * a generic way. Only the called interface object know (it depends + * from the original request - see nRequest too), how this list must + * be interpreted. + * Note: Atomic types (e.g. int, long) will be transported as objects + * too (Integer, Long)! + */ + void execOneway( int nRequest, ArrayList<Object> lParams ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/IShutdownListener.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/IShutdownListener.java new file mode 100644 index 000000000..753d364d0 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/IShutdownListener.java @@ -0,0 +1,48 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Implementation __________ + +/** + * Listener interface to get information about application shutdown + * if java virtual machine dies. + * + */ +public interface IShutdownListener +{ + void shutdown(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Install.txt b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Install.txt new file mode 100644 index 000000000..79a1ee2bf --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Install.txt @@ -0,0 +1,10 @@ +(1) goto "./nativelib/<platform>" directory and build it +(2) build this directory +(3) expand your class path to include all jar files of an office installation + (means all files in path "<officeinst>/program/classes") +(4) goto "api/<platform>/class" +(5) copy from an existing java installation the runtime library "jawt" (e.g. jawt.dll for windows) + into this directory +(6) copy "api/<platform>/bin/nativelib.dll" (for windows) to "api/<platform>/class" +(7) start an office : "soffice --accept=socket,host=localhost,port=2083;urp;" +(8) goto "api/<platform>/class" and start java applet: "java -jar desktop.jar" diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Interceptor.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Interceptor.java new file mode 100644 index 000000000..380f8da3c --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Interceptor.java @@ -0,0 +1,655 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +// Imports + +import java.util.ArrayList; + +import com.sun.star.frame.FrameActionEvent; +import com.sun.star.uno.UnoRuntime; + +// Implementation + +/* + * This class can be used to intercept dispatched URL's + * on any frame used in this demo application. + * It intercept all URL's which try to create a new empty frame. + * (e.g. "private:factory/swriter") + * Nobody can guarantee that this interception will be really used - + * because another interceptor (registered at a later time then this one!) + * will be called before this one. + * Implementation is executed inside a new thread to prevent application + * against possible deadlocks. This deadlocks can occur if + * synchronous/asynchronous ... normal ones and oneway calls are mixed. + * Notifications of listener will be oneway mostly - her reactions can + * be synchronous then. => deadlocks are possible + */ +public class Interceptor implements com.sun.star.frame.XFrameActionListener, + com.sun.star.frame.XDispatchProviderInterceptor, + com.sun.star.frame.XDispatch, + com.sun.star.frame.XInterceptorInfo, + IShutdownListener, + IOnewayLink +{ + + + /** + * const + * All these URL's are intercepted by this implementation. + */ + private static final String[] INTERCEPTED_URLS = { "private:factory/*" , + ".uno:SaveAs" , + "slot:5300" , + ".uno:Quit" }; + + + + /* + * @member m_xMaster use this interceptor if he doesn't handle queried dispatch request + * @member m_xSlave we can forward all unhandled requests to this slave interceptor + * @member m_xFrame intercepted frame + * @member m_bDead there exist more than one way to finish an object of this class - we must know it sometimes + */ + private com.sun.star.frame.XDispatchProvider m_xMaster ; + private com.sun.star.frame.XDispatchProvider m_xSlave ; + private com.sun.star.frame.XFrame m_xFrame ; + private boolean m_bIsActionListener ; + private boolean m_bIsRegistered ; + private boolean m_bDead ; + + + + /* + * ctor + * Initialize the new interceptor. Given frame reference can be used to + * register this interceptor on it automatically later. + * + * @seealso startListening() + * + * @param xFrame + * this interceptor will register himself at this frame to intercept dispatched URLs + */ + Interceptor(/*IN*/ com.sun.star.frame.XFrame xFrame) + { + m_xFrame = xFrame ; + m_xSlave = null ; + m_xMaster = null ; + m_bIsRegistered = false ; + m_bIsActionListener = false ; + m_bDead = false ; + } + + + + /* + * start working as frame action listener really. + * We will be frame action listener here. In case + * we get a frame action which indicates, that we should + * update our interception. Because such using of an interceptor + * isn't guaranteed - in case a newer one was registered... + */ + public void startListening() + { + com.sun.star.frame.XFrame xFrame = null; + synchronized(this) + { + if (m_bDead) + return; + if (m_xFrame==null) + return; + if (m_bIsActionListener) + return; + xFrame = m_xFrame; + } + m_xFrame.addFrameActionListener(this); + synchronized(this) + { + m_bIsActionListener=true; + } + } + + + + /* + * In case we got a oneway listener callback - we had to use the office + * asynchronous then. This method is the callback from the started thread + * (started inside the original oneway method). We found all parameters of + * the original request packed inside a vector. Here we unpack it and + * call the right internal helper method, which implements the right + * functionality. + * + * @seealso frameAction() + * @seealso dispatch() + * + * @param nRequest + * indicates, which was the original request (identifies the + * original called method) + * + * @param lParams + * the vector with all packed parameters of the original request + */ + public void execOneway(/*IN*/ int nRequest,/*IN*/ ArrayList<Object> lParams ) + { + synchronized(this) + { + if (m_bDead) + return; + } + + // was it frameAction()? + if (nRequest==OnewayExecutor.REQUEST_FRAMEACTION) + { + impl_frameAction((FrameActionEvent) lParams.get(0)); + } + else + // was it dispatch()? + if (nRequest==OnewayExecutor.REQUEST_DISPATCH) + { + com.sun.star.util.URL[] lOutURL = new com.sun.star.util.URL[1]; + com.sun.star.beans.PropertyValue[][] lOutProps = new com.sun.star.beans.PropertyValue[1][]; + + OnewayExecutor.decodeDispatch( + lParams , + lOutURL , + lOutProps ); + impl_dispatch(lOutURL[0],lOutProps[0]); + } + } + + + + /* + * callback for frame action events + * We use it to update our interception. Because if a new component was loaded into + * the frame or another interceptor was registered, we should refresh our connection + * to the frame. Otherwise we can't guarantee full functionality here. + * + * Note: Don't react synchronous in an asynchronous listener callback. So use a thread + * here to update anything. + * + * @seealso impl_frameAction() + * + * @param aEvent + * describes the action + */ + public /*ONEWAY*/ void frameAction(/*IN*/ com.sun.star.frame.FrameActionEvent aEvent) + { + synchronized(this) + { + if (m_bDead) + return; + } + + boolean bHandle = false; + switch(aEvent.Action.getValue()) + { + case com.sun.star.frame.FrameAction.COMPONENT_ATTACHED_value : bHandle=true; break; + case com.sun.star.frame.FrameAction.COMPONENT_DETACHING_value : bHandle=true; break; + case com.sun.star.frame.FrameAction.COMPONENT_REATTACHED_value : bHandle=true; break; + // Don't react for CONTEXT_CHANGED here. Ok it indicates, that may another interceptor + // was registered at the frame ... but if we register ourself there - we get a context + // changed too :-( Best way to produce a never ending recursion ... + // May be that somewhere find a safe mechanism to detect own produced frame action events + // and ignore it. + case com.sun.star.frame.FrameAction.CONTEXT_CHANGED_value : + System.out.println("Time to update interception ... but may it will start a recursion. So I let it :-("); + bHandle=false; + break; + } + + // ignore some events + if (! bHandle) + return; + + // pack the event and start thread - which call us back later + ArrayList<Object> lOutParams = new ArrayList<Object>(); + lOutParams.add(aEvent); + + OnewayExecutor aExecutor = new OnewayExecutor( this , + OnewayExecutor.REQUEST_FRAMEACTION , + lOutParams ); + aExecutor.start(); + } + + + + /* + * Indicates using of us as an interceptor. + * Now we have to react for the requests, we are registered. + * That means: load new empty documents - triggered by the new menu of the office. + * Because it's oneway - use thread for loading! + * + * @seealso impl_dispatch() + * + * @param aURL + * describes the document, which should be loaded + * + * @param lArguments + * optional parameters for loading + */ + public /*ONEWAY*/ void dispatch(/*IN*/ com.sun.star.util.URL aURL,/*IN*/ com.sun.star.beans.PropertyValue[] lArguments) + { + synchronized(this) + { + if (m_bDead) + return; + } + + com.sun.star.util.URL[] lInURL = new com.sun.star.util.URL[1]; + com.sun.star.beans.PropertyValue[][] lInArguments = new com.sun.star.beans.PropertyValue[1][]; + lInURL[0] = aURL ; + lInArguments[0] = lArguments; + + ArrayList<Object> lOutParams = OnewayExecutor.encodeDispatch( + lInURL , + lInArguments ); + OnewayExecutor aExecutor = new OnewayExecutor( this , + OnewayExecutor.REQUEST_DISPATCH , + lOutParams ); + aExecutor.start(); + } + + + + + /* + * Internal callback for frame action events, triggered by the used + * OnewayExecutor thread we started in frameAction(). + * We use it to update our interception on the internal saved frame. + * + * @param aEvent + * describes the action + */ + private void impl_frameAction(/*IN*/ com.sun.star.frame.FrameActionEvent aEvent) + { + synchronized(this) + { + if (m_bDead) + return; + } + + // deregistration will be done every time... + // But may it's not necessary to establish a new registration! + // Don't look for ignoring actions - it was done already inside original frameAction() call! + boolean bRegister = false; + + // analyze the event and decide which reaction is useful + switch(aEvent.Action.getValue()) + { + case com.sun.star.frame.FrameAction.COMPONENT_ATTACHED_value : bRegister = true ; break; + case com.sun.star.frame.FrameAction.COMPONENT_REATTACHED_value : bRegister = true ; break; + case com.sun.star.frame.FrameAction.COMPONENT_DETACHING_value : bRegister = false; break; + } + + com.sun.star.frame.XFrame xFrame = null ; + boolean bIsRegistered = false; + synchronized(this) + { + bIsRegistered = m_bIsRegistered; + m_bIsRegistered = false; + xFrame = m_xFrame; + } + + com.sun.star.frame.XDispatchProviderInterception xRegistration = UnoRuntime.queryInterface( + com.sun.star.frame.XDispatchProviderInterception.class, + xFrame); + + if(xRegistration==null) + return; + + if (bIsRegistered) + xRegistration.releaseDispatchProviderInterceptor(this); + + if (! bRegister) + return; + + xRegistration.registerDispatchProviderInterceptor(this); + synchronized(this) + { + m_bIsRegistered = true; + } + } + + + + /* + * Implementation of interface XDispatchProviderInterceptor + * These functions are used to build a list of interceptor objects + * connected in both ways. + * Searching for a right interceptor is made by forwarding any request + * from toppest master to lowest slave of this hierarchy. + * If an interceptor wish to handle the request he can break that + * and return himself as a dispatcher. + */ + public com.sun.star.frame.XDispatchProvider getSlaveDispatchProvider() + { + synchronized(this) + { + return m_xSlave; + } + } + + + + public void setSlaveDispatchProvider(com.sun.star.frame.XDispatchProvider xSlave) + { + synchronized(this) + { + m_xSlave = xSlave; + } + } + + + + public com.sun.star.frame.XDispatchProvider getMasterDispatchProvider() + { + synchronized(this) + { + return m_xMaster; + } + } + + + + public void setMasterDispatchProvider(com.sun.star.frame.XDispatchProvider xMaster) + { + synchronized(this) + { + m_xMaster = xMaster; + } + } + + + + /* + * Implementation of interface XDispatchProvider + * These functions are called from our master if he will not handle the outstanding request. + * Given parameter should be checked if they are right for us. If it's true, the returned + * dispatcher should be this implementation himself; otherwise call should be forwarded + * to the slave. + * + * @param aURL + * describes the request, which should be handled + * + * @param sTarget + * specifies the target frame for this request + * + * @param nSearchFlags + * optional search flags, if sTarget isn't a special one + * + * @return [XDispatch] + * a dispatch object, which can handle the given URL + * May be NULL! + */ + public com.sun.star.frame.XDispatch queryDispatch(/*IN*/ com.sun.star.util.URL aURL,/*IN*/ String sTarget,/*IN*/ int nSearchFlags) + { + synchronized(this) + { + if (m_bDead) + return null; + } + + // intercept loading empty documents into new created frames + if( + (sTarget.compareTo ("_blank" ) == 0 ) && + (aURL.Complete.startsWith("private:factory")) + ) + { + System.out.println("intercept private:factory"); + return this; + } + + // intercept opening the SaveAs dialog + if (aURL.Complete.startsWith(".uno:SaveAs")) + { + System.out.println("intercept SaveAs by returning null!"); + return null; + } + + // intercept "File->Exit" inside the menu + if ( + (aURL.Complete.startsWith("slot:5300")) || + (aURL.Complete.startsWith(".uno:Quit")) + ) + { + System.out.println("intercept File->Exit"); + return this; + } + + synchronized(this) + { + if (m_xSlave!=null) + return m_xSlave.queryDispatch(aURL, sTarget, nSearchFlags); + } + + return null; + } + + + + public com.sun.star.frame.XDispatch[] queryDispatches(/*IN*/ com.sun.star.frame.DispatchDescriptor[] lDescriptor) + { + synchronized(this) + { + if (m_bDead) + return null; + } + // Resolve any request separately by using own "dispatch()" method. + // Note: Don't pack return list if "null" objects occur! + int nCount = lDescriptor.length; + com.sun.star.frame.XDispatch[] lDispatcher = new com.sun.star.frame.XDispatch[nCount]; + for(int i=0; i<nCount; ++i) + { + lDispatcher[i] = queryDispatch(lDescriptor[i].FeatureURL , + lDescriptor[i].FrameName , + lDescriptor[i].SearchFlags); + } + return lDispatcher; + } + + + + /* + * This method is called if this interceptor "wins the request". + * We intercepted creation of new frames and loading of empty documents. + * Do it now. + * + * @param aURL + * describes the document + * + * @param lArguments + * optional arguments for loading + */ + private void impl_dispatch(/*IN*/ com.sun.star.util.URL aURL,/*IN*/ com.sun.star.beans.PropertyValue[] lArguments) + { + synchronized(this) + { + if (m_bDead) + return; + } + + if ( + (aURL.Complete.startsWith("slot:5300")) || + (aURL.Complete.startsWith(".uno:Quit")) + ) + { + System.exit(0); + } + else + if (aURL.Complete.startsWith("private:factory")) + { + // Create view frame for showing loaded documents on demand. + // The visible state is necessary for JNI functionality to get the HWND and plug office + // inside a java window hierarchy! + DocumentView aNewView = new DocumentView(); + aNewView.setVisible(true); + aNewView.createFrame(); + aNewView.load(aURL.Complete,lArguments); + } + } + + + + /* + * Notification of status listener isn't guaranteed (instead of listener on XNotifyingDispatch interface). + * So this interceptor doesn't support that really... + */ + public /*ONEWAY*/ void addStatusListener(/*IN*/ com.sun.star.frame.XStatusListener xListener,/*IN*/ com.sun.star.util.URL aURL) + { +/* if (aURL.Complete.startsWith(".uno:SaveAs")==true) + { + com.sun.star.frame.FeatureStateEvent aEvent = new com.sun.star.frame.FeatureStateEvent( + this, + aURL, + "", + false, + false, + null); + if (xListener!=null) + { + System.out.println("interceptor disable SaveAs by listener notify"); + xListener.statusChanged(aEvent); + } + }*/ + } + + + + public /*ONEWAY*/ void removeStatusListener(/*IN*/ com.sun.star.frame.XStatusListener xListener,/*IN*/ com.sun.star.util.URL aURL) + { + } + + + + /* + * Implements (optional!) optimization for interceptor mechanism. + * Any interceptor which provides this special interface is called automatically + * at registration time on this method. Returned URL's will be used to + * call this interceptor directly without calling his masters before, IF(!) + * following rules will be true: + * (1) every master supports this optional interface too + * (2) nobody of these masters wish to intercept same URL then this one + * This interceptor wish to intercept creation of new documents. + */ + public String[] getInterceptedURLs() + { + return INTERCEPTED_URLS; + } + + + + /* + * This class listen on the intercepted frame to free all used resources on closing. + * We forget the reference to the frame only here. Deregistration + * isn't necessary here - because this frame dies and wish to be forgotten. + * + * @param aSource + * must be our internal saved frame, on which we listen for frame action events + */ + public /*ONEAY*/ void disposing(/*IN*/ com.sun.star.lang.EventObject aSource) + { + synchronized(this) + { + if (m_bDead) + return; + if (m_xFrame!=null && UnoRuntime.areSame(aSource.Source,m_xFrame)) + { + m_bIsActionListener = false; + m_xFrame = null ; + } + } + shutdown(); + } + + + + /* + * If this java application shutdown - we must cancel all current existing + * listener connections. Otherwise the office will run into some + * DisposedExceptions if it tries to use these forgotten listener references. + * And of course it can die doing that. + * We are registered at a central object to be informed if the VM will exit. + * So we can react. + */ + public void shutdown() + { + com.sun.star.frame.XFrame xFrame = null ; + boolean bIsRegistered = false; + boolean bIsActionListener = false; + synchronized(this) + { + // don't react a second time here! + if (m_bDead) + return; + m_bDead = true; + + bIsRegistered = m_bIsRegistered; + m_bIsRegistered = false; + + bIsActionListener = m_bIsActionListener; + m_bIsActionListener = false; + + xFrame = m_xFrame; + m_xFrame = null; + } + + // it's a good idea to cancel listening for frame action events + // before(!) we deregister us as an interceptor. + // Because registration and deregistration of interceptor objects + // will force sending of frame action events...! + if (bIsActionListener) + xFrame.removeFrameActionListener(this); + + if (bIsRegistered) + { + com.sun.star.frame.XDispatchProviderInterception xRegistration = UnoRuntime.queryInterface( + com.sun.star.frame.XDispatchProviderInterception.class, + xFrame); + + if(xRegistration!=null) + xRegistration.releaseDispatchProviderInterceptor(this); + } + + xFrame = null; + + synchronized(this) + { + m_xMaster = null; + m_xSlave = null; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/JavaWindowPeerFake.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/JavaWindowPeerFake.java new file mode 100644 index 000000000..25281ac5f --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/JavaWindowPeerFake.java @@ -0,0 +1,109 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + + + + +/** <p>Class to pass the system window handle to the OpenOffice.org toolkit.</p> + */ +class JavaWindowPeerFake implements com.sun.star.awt.XSystemDependentWindowPeer, + com.sun.star.awt.XWindowPeer +{ + private final NativeView maView; + + public JavaWindowPeerFake(NativeView aNative) + { + maView = aNative; + } + + + /** + * Implementation of XSystemDependentWindowPeer (that's all we really need). + * This method is called back from the Office toolkit to retrieve the system data. + */ + public java.lang.Object getWindowHandle(byte[] aProcessId, short aSystem) + throws com.sun.star.uno.RuntimeException + { + Object aReturn = null; + if(aSystem==maView.maSystem) + aReturn = maView.maHandle; + return aReturn; + } + + /** not really needed. + */ + public com.sun.star.awt.XToolkit getToolkit() + throws com.sun.star.uno.RuntimeException + { + return null; + } + + public void setPointer(com.sun.star.awt.XPointer xPointer) + throws com.sun.star.uno.RuntimeException + { + } + + public void setBackground(int nColor) + throws com.sun.star.uno.RuntimeException + { + } + + public void invalidate(short nFlags) + throws com.sun.star.uno.RuntimeException + { + } + + public void invalidateRect(com.sun.star.awt.Rectangle aRect,short nFlags) + throws com.sun.star.uno.RuntimeException + { + } + + public void dispose() + throws com.sun.star.uno.RuntimeException + { + } + + public void addEventListener(com.sun.star.lang.XEventListener xListener) + throws com.sun.star.uno.RuntimeException + { + } + + public void removeEventListener(com.sun.star.lang.XEventListener xListener) + throws com.sun.star.uno.RuntimeException + { + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Makefile b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Makefile new file mode 100644 index 000000000..5b0462b25 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/Makefile @@ -0,0 +1,131 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevDesktopEnvironment example of the Developers Guide. + +PRJ=../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevDesktopEnv +OUT_APP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +APP1_NAME=DesktopExample +APP1_JAR=$(OUT_APP_CLASS)/$(APP1_NAME).jar + +APP1_JAVAFILES = \ + CustomizeView.java \ + Desk.java \ + DocumentView.java \ + FunctionHelper.java \ + Interceptor.java \ + IOnewayLink.java \ + IShutdownListener.java \ + JavaWindowPeerFake.java \ + NativeView.java \ + OfficeConnect.java \ + OnewayExecutor.java \ + StatusListener.java \ + StatusView.java \ + ViewContainer.java + +APP1_CLASSFILES = $(patsubst %.java,$(OUT_APP_CLASS)/%.class,$(APP1_JAVAFILES)) +APP1_CLASSNAMES = $(patsubst %.java,%.class,$(APP1_JAVAFILES)) \ + CustomizeView$(QUOTE)$$ClickListener.class \ + DocumentView$(QUOTE)$$*.class + + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_APP_CLASS)) + +ifeq "$(OS)" "WIN" +SUBDIR= nativelib/windows +else +SUBDIR= nativelib/unix +endif + +# Targets +.PHONY: ALL +ifeq "$(OS)" "MACOSX" +ALL : + @printf 'This example does not work on macOS\n' +else +ALL : $(SUBDIR) \ + $(EXAMPLE_NAME) +endif + +include $(SETTINGS)/stdtarget.mk + +.PHONY : $(SUBDIR) +$(SUBDIR) : + $(MAKE) -C $@ + +$(APP1_CLASSFILES) : $(APP1_JAVAFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $(APP1_JAVAFILES) + +$(OUT_APP_CLASS)/$(APP1_NAME).mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: Desk>> $@ + +$(APP1_JAR) : $(OUT_APP_CLASS)/$(APP1_NAME).mf $(APP1_CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(basename $(@F)).mf $(APP1_CLASSNAMES) + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + +$(EXAMPLE_NAME) : $(APP1_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following command to execute the example! + @echo - + @echo $(MAKE) DesktopExample.run + @echo ------ + @echo If you want to run the $(JAR1_JAR) file please set your + @echo CLASSPATH = $(SDK_CLASSPATH) + @echo Start the example with jar -jar $(JAR1_JAR) + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_APP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + $(MAKE) -C $(SUBDIR) clean + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_CLASS)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/NativeView.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/NativeView.java new file mode 100644 index 000000000..273290e55 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/NativeView.java @@ -0,0 +1,186 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import java.awt.*; + +// __________ Implementation __________ + +/** + * Class to pass the system window handle to the OpenOffice.org toolkit. + * It use special JNI methods to get the system handle of used java window. + * + * Attention! + * Use JNI functions on already visible canvas objects only! + * Otherwise they can make some trouble. + * + */ + +public class NativeView extends java.awt.Canvas +{ + + + /** + * ctor + * Does nothing really. + * We can use our JNI mechanism for an already visible + * canvas only. So we override the method for showing ("setVisible()") + * and make our initialization there. But we try to show an empty clean + * window till there. + */ + public NativeView() + { + maHandle = null; + maSystem = 0; + this.setBackground(Color.white); + } + + + + /** + * Override this method to make necessary initializations here. + * (e.g. get the window handle and necessary system information) + * + * Why here? + * Because the handle seems to be available for already visible windows + * only. So it's the best place to get it. Special helper method + * can be called more than ones - but call native code one times only + * and safe the handle and the system type on our members maHandle/maSystem! + */ + @Override + public void setVisible(boolean bState) + { + getHWND(); + } + + + + /** + * to guarantee right resize handling inside a swing container + * (e.g. JSplitPane) we must provide some information about our + * preferred/minimum and maximum size. + */ + @Override + public Dimension getPreferredSize() + { + return new Dimension(500,300); + } + + @Override + public Dimension getMaximumSize() + { + return new Dimension(1024,768); + } + + @Override + public Dimension getMinimumSize() + { + return new Dimension(100,100); + } + + + + /** + * Override paint routine to show provide against + * repaint errors if no office view is really plugged + * into this canvas. + * If handle is present - we shouldn't paint anything further. + * May the remote window is already plugged. In such case we + * shouldn't paint it over. + */ + @Override + public void paint(Graphics aGraphic) + { + if(maHandle==null) + { + Dimension aSize = getSize(); + aGraphic.clearRect(0,0,aSize.width,aSize.height); + } + } + + + + /** + * JNI interface of this class + * These two methods are implemented by using JNI mechanismen. + * The will be used to get the platform dependent window handle + * of a java awt canvas. This handle can be used to create an office + * window as direct child of it. So it's possible to plug Office + * windows in a java UI container. + * + * Note: + * Native code for Windows registers a special function pointer to handle + * window messages... But if it doesn't check for an already-registered + * instance of this handler it will do it twice and produce a stack overflow + * because such method calls itself in a never-ending loop... + * So we try to use the JNI code one time only and save already-obtained + * information inside this class. + */ + public native int getNativeWindowSystemType(); + private native long getNativeWindow(); // private! => use getHWND() with cache mechanism! + + public Integer getHWND() + { + if(maHandle==null) + { + maHandle = Integer.valueOf((int)getNativeWindow()); + maSystem = getNativeWindowSystemType(); + } + return maHandle; + } + + + + /** + * for using of the JNI methods it's necessary to load + * system library which exports it. + */ + static + { + System.loadLibrary("nativeview"); + } + + + + /** + * @member maHandle system window handle + * @member maSystem info about currently used platform + */ + public Integer maHandle ; + public int maSystem ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/OfficeConnect.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/OfficeConnect.java new file mode 100644 index 000000000..617e38047 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/OfficeConnect.java @@ -0,0 +1,127 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + + + + +// __________ Implementation __________ + +/** + * support ONE singleton uno connection to a running office installation! + * Can be used to open/use/close connection to uno environment of an office. If + * necessary a new office instance is started. + * ctor isn't available from outside. You should call static function + * "getConnection()" to open or use internal set connection which is created one + * times only. + * + */ +public class OfficeConnect +{ + + + /** + * At first call we create static connection object and open connection to an + * office - a new office instance is started if necessary + * Then - and for all further requests we return these static connection member. + */ + public static synchronized void createConnection() + { + if (maConnection == null) + maConnection = new OfficeConnect(); + } + + + + + + + + /** + * ctor + * We try to open the connection in our ctor ... transparently for user. + * After it was successful you will find an internal set member + * m_xRemoteContext which means remote component context of the connected office. + * The context can be used to get the remote service manager from the office. + * We made it private to support singleton pattern of these implementation. + * see getConnection() for further information + */ + private OfficeConnect() + { + try + { + // get the remote office context. If necessary a new office + // process is started + mxOfficeContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + mxServiceManager = mxOfficeContext.getServiceManager(); + } + catch (java.lang.Exception ex) + { + System.err.println("connection failed" + ex); + ex.printStackTrace(System.err); + System.exit(1); + + } + } + + + + + + + + /** + * returns remote component context of the connected office + */ + public static synchronized com.sun.star.uno.XComponentContext getOfficeContext() + { + return mxOfficeContext; + } + + + + /** + * member + */ + // singleton connection instance + private static OfficeConnect maConnection; + + // reference to the office component context + private static com.sun.star.uno.XComponentContext mxOfficeContext; + // reference to remote service manager of singleton connection object + private static com.sun.star.lang.XMultiComponentFactory mxServiceManager; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/OnewayExecutor.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/OnewayExecutor.java new file mode 100644 index 000000000..4eb7f80a7 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/OnewayExecutor.java @@ -0,0 +1,189 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import java.util.ArrayList; + +// __________ Implementation __________ + +/** + * It's not allowed to call synchronous back inside a oneway interface call. + * (see IOnewayLink too). So we start a thread (implemented by this class), which + * gets all necessary parameters from the original called object and + * call it back later inside his run() method. So the execution of such oneway call + * will be asynchronous. It works in a generic way and can be used or any type + * of oneway request. Because the source and the target of this call-link knows, + * which method was used and which parameters must be handled. + * + */ +class OnewayExecutor extends Thread +{ + + + /** + * const + * We define some request for some well known oneway interface + * calls here too. So they mustn't be declared more than ones. + * Of course it's not necessary to use it ... but why not :-) + */ + + public static final int REQUEST_FRAMEACTION = 1 ; + + + + public static final int REQUEST_DISPATCH = 5 ; + + + + + + + /** + * @member m_rLink the object, which wishes to be called back by this thread + * @member m_nRequest describes the type of the original request (means the + * called oneway method) + * @member m_lParams list of parameters of the original request + */ + private final IOnewayLink m_rLink ; + private final int m_nRequest ; + private final ArrayList<Object> m_lParams ; + + + + /** + * ctor + * It's initialize this thread with all necessary parameters. + * It gets the object, which wishes to be called back and the type + * and parameters of the original request. + * + * @param nRequest + * The two user of this callback can define a unique number, + * which identify the type of original interface method. + * So the called interface object can decide, which action will be + * necessary. + * + * @param lParams + * If the original method used parameters, they will be coded here in + * a generic way. Only the called interface object know (it depends + * from the original request - see nRequest too), how this list must + * be interpreted. + * Note: Atomic types (e.g. int, long) will be transported as objects + * too (Integer, Long)! + */ + public OnewayExecutor( IOnewayLink rLink , + int nRequest , + ArrayList<Object> lParams ) + { + m_rLink = rLink ; + m_nRequest = nRequest; + m_lParams = lParams ; + + if (m_rLink==null) + System.out.println("ctor ... m_rLink == null"); + if (m_lParams==null) + System.out.println("ctor ... m_lParams == null"); + } + + + + /** + * implements the thread function + * Here we call the internal set link object back and + * give him all necessary parameters. + * After that we die by ourselves ... + */ + @Override + public void run() + { + if (m_rLink==null) + System.out.println("run ... m_rLink == null"); + if (m_lParams==null) + System.out.println("run ... m_lParams == null"); + + if (m_rLink!=null) + m_rLink.execOneway( m_nRequest, m_lParams ); + } + + + + /** + * static helper! + * To make conversion of the generic parameter list to the original + * one easier - you can use this helper methods. They know how such list + * must be coded. It's not a must to use it - but you can ... + */ + + + + public static ArrayList<Object> encodeDispatch( + com.sun.star.util.URL[] aURL, + com.sun.star.beans.PropertyValue[][] lArgs) + { + int nLength = lArgs.length+1; + int nPos = 0; + ArrayList<Object> lParams = new ArrayList<Object>(nLength); + + lParams.add( aURL[0] ); + --nLength; + + while (nLength>0) + { + lParams.add( lArgs[0][nPos] ); + --nLength; + ++nPos ; + } + return lParams; + } + + public static void decodeDispatch( + ArrayList<Object> lParams, + com.sun.star.util.URL[] aURL, + com.sun.star.beans.PropertyValue[][] lArgs) + { + int nLength = lParams.size()-1; + int nPos = 0; + + lArgs[0] = new com.sun.star.beans.PropertyValue[nLength]; + aURL[0] = (com.sun.star.util.URL) lParams.get(0); + + while (nPos<nLength) + { + lArgs[0][nPos] = (com.sun.star.beans.PropertyValue) + (lParams.get(nPos+1)); + ++nPos; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/StatusListener.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/StatusListener.java new file mode 100644 index 000000000..f037949b0 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/StatusListener.java @@ -0,0 +1,469 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import java.awt.Component; +import java.util.ArrayList; + +import javax.swing.JCheckBox; +import javax.swing.JLabel; + +import com.sun.star.frame.FrameActionEvent; +import com.sun.star.uno.UnoRuntime; + +// __________ Implementation __________ + +/** + * reacts for status events we listen for + * We listen for status events to update our UI. + * To know which event must be used for which UI control + * we use a special class to do that. Otherwise we have + * to guess it ... + * + * Further we are frame action listener too. + * So we can update our status listener connections and + * internal holded dispatch object automatically. + * + * Another reason for such extra class for listening: + * Most listener callbacks are asynchronous [oneay] requests. + * And it's not allowed to call back synchronously there. + * So we must start threads for updating something internally. + * + */ +class StatusListener implements com.sun.star.frame.XStatusListener, + com.sun.star.frame.XFrameActionListener, + IShutdownListener, + IOnewayLink +{ + + + /** + * @member m_rControl reference to the UI control, which should be updated + * @member m_sTrueText this text will be shown at the used UI control as description for an enabled status + * @member m_sFalseText this text will be shown at the used UI control as description for an disabled status + * @member m_xDispatch if we listen for status events, we must hold the dispatch object alive! + * @member m_xFrame reference to the frame, which can provide new dispatch objects if it's necessary to update it + * @member m_aURL and of course we must be registered for a special URL + * @member m_bIsActionListener indicates if we are currently registered as a listener for frame action events or not + * @member m_bIsStatusListener indicates if we are currently registered as a listener for status events or not + * @member m_bDead there exist more than one way to finish an object of this class - we must know it sometimes + */ + private final Component m_rControl ; + private final String m_sTrueText ; + private final String m_sFalseText ; + private com.sun.star.frame.XDispatch m_xDispatch ; + private com.sun.star.frame.XFrame m_xFrame ; + private com.sun.star.util.URL m_aURL ; + private boolean m_bIsActionListener; + private boolean m_bIsStatusListener; + private boolean m_bDead ; + + + + /** + * ctor + * It initialize an instance of this class only. + * We set all necessary information on our internal member - that's it + */ + StatusListener( /*IN*/ Component rControl , + /*IN*/ String sTrueText , + /*IN*/ String sFalseText , + /*IN*/ com.sun.star.frame.XFrame xFrame , + /*IN*/ String sURL ) + { + m_rControl = rControl ; + m_sTrueText = sTrueText ; + m_sFalseText = sFalseText ; + m_xFrame = xFrame ; + m_bIsStatusListener = false ; + m_bIsActionListener = false ; + m_bDead = false ; + // to be perform - we parse the given URL one times only + // and use it till we die ... + m_aURL = FunctionHelper.parseURL(sURL); + } + + + + /** + * start working as frame action listener really. + * In case we get such frame action, it indicates that we should + * update our internal saved dispatch object on which we listen + * for status events. So we can do it automatically. The outside code + * mustn't check such things. We can work with one frame, + * till it die. It doesn't matter if he will be used for different + * load/save or any other requests. We will be up to date every time. + */ + public void startListening() + { + com.sun.star.frame.XFrame xFrame = null; + synchronized(this) + { + if (m_bDead) + return; + if (m_xFrame==null) + return; + if (m_bIsActionListener) + return; + xFrame = m_xFrame; + } + xFrame.addFrameActionListener(this); + synchronized(this) + { + m_bIsActionListener=true; + } + } + + + + /** + * In case we got a oneway listener callback - we had to use the office + * asynchronous then. This method is the callback from the started thread + * (started inside the original oneway method). We found all parameters of + * the original request packed inside a vector. Here we unpack it and + * call the right internal helper method, which implements the right + * functionality. + * + * @seealso frameAction() + * @seealso statusChanged() + * + * @param nRequest + * indicates, which was the original request (identifies the + * original called method) + * + * @param lParams + * the vector with all packed parameters of the original request + */ + public void execOneway(/*IN*/ int nRequest,/*IN*/ ArrayList<Object> lParams ) + { + synchronized(this) + { + if (m_bDead) + return; + } + // was it frameAction()? + if (nRequest==OnewayExecutor.REQUEST_FRAMEACTION) + { + impl_frameAction((FrameActionEvent) lParams.get(0)); + } + } + + + + /** + * This is the callback method for such frame action events, we listen for. + * Because it's a oneway method we start a thread as reaction. This thread call + * us back and we can do necessary things there. + * But we shouldn't start such action - if it's not really necessary. + * So we check before, if we are interested on this event really. + * + * @see #impl_frameAction + * + * @param aEvent + * describes the action, which triggered this event + */ + public /*ONEWAY*/ void frameAction(/*IN*/ com.sun.star.frame.FrameActionEvent aEvent) + { + synchronized(this) + { + if (m_bDead) + return; + } + boolean bHandle = false; + switch(aEvent.Action.getValue()) + { + case com.sun.star.frame.FrameAction.COMPONENT_ATTACHED_value : bHandle=true; break; + case com.sun.star.frame.FrameAction.COMPONENT_DETACHING_value : bHandle=true; break; + case com.sun.star.frame.FrameAction.COMPONENT_REATTACHED_value : bHandle=true; break; + case com.sun.star.frame.FrameAction.CONTEXT_CHANGED_value : bHandle=true; break; + } + + if (! bHandle) + return; + + ArrayList<Object> lOutParams = new ArrayList<Object>(); + lOutParams.add(aEvent); + + OnewayExecutor aExecutor = new OnewayExecutor( this , + OnewayExecutor.REQUEST_FRAMEACTION , + lOutParams ); + aExecutor.start(); + } + + + + /** + * This is the callback method for the status we listen for and wish to show it + * on our UI control. Of course it's a oneway method... but we don't call back + * to the office synchronously here. We update our UI only. So we don't leave this + * java process. In such case it's not necessary to use threads to decouple it. + * Do it here and now... + * + * @param aEvent + * describes the status, we can use to update our UI control + */ + public /*ONEWAY*/ void statusChanged(/*IN*/ com.sun.star.frame.FeatureStateEvent aEvent) + { + synchronized(this) + { + if (m_bDead) + return; + + // enable/disable the control. + // Means: if the feature isn't available currently - we can't show a status really here. + // Then we should colorize it gray... + m_rControl.setEnabled(aEvent.IsEnabled); + + // Only if status is enabled we can look for his value! + if (aEvent.IsEnabled) + { + // look for the right type of the UI control + // Following actions depend on it. + + + // it's a check box + if (m_rControl instanceof JCheckBox) + { + JCheckBox aBox = (JCheckBox)m_rControl; + + // State must be a boolean value too. Otherwise must + // ignore this event. + if ( ! (aEvent.State instanceof Boolean ) ) + return; + + boolean bState = ((Boolean)(aEvent.State)).booleanValue(); + aBox.setSelected(bState); + if (bState) + aBox.setText(m_sTrueText); + else + aBox.setText(m_sFalseText); + } + else + + // it's a label + if (m_rControl instanceof JLabel) + { + JLabel aLabel = (JLabel)m_rControl; + + // Detect type of state value + // and set it on internal well known UI control + // But do it only, if value really change. + if(aEvent.State instanceof String) + { + String sState = (String)aEvent.State; + aLabel.setText(sState); + } + else + if(aEvent.State instanceof Boolean) + { + boolean bState = ((Boolean)aEvent.State).booleanValue(); + if (bState) + aLabel.setText(m_sTrueText); + else + aLabel.setText(m_sFalseText); + } + else + if(aEvent.State instanceof Float) + { + String sState = ((Float)aEvent.State).toString(); + aLabel.setText(sState); + } + } + } + } + } + + + + /** + * Internal call back for frame action events, triggered by the used + * OnewayExecutor thread we started in frameAction(). + * We use it to update internal saved dispatch object and the corresponding + * listener connection for status events. + * + * @param aEvent + * describes the action + */ + private void impl_frameAction(/*IN*/ com.sun.star.frame.FrameActionEvent aEvent) + { + synchronized(this) + { + if (m_bDead) + return; + } + // Don't look for ignoring actions - it was done already inside original frameAction() call! + // deregistration as status listener will be done here every time - but registration only, if necessary! + boolean bRegister = false; + switch(aEvent.Action.getValue()) + { + case com.sun.star.frame.FrameAction.COMPONENT_ATTACHED_value : bRegister=true ; break; + case com.sun.star.frame.FrameAction.COMPONENT_DETACHING_value : bRegister=false; break; + case com.sun.star.frame.FrameAction.COMPONENT_REATTACHED_value : bRegister=true ; break; + case com.sun.star.frame.FrameAction.CONTEXT_CHANGED_value : bRegister=true ; break; + } + + boolean bIsStatusListener = false; + com.sun.star.frame.XFrame xFrame = null ; + com.sun.star.frame.XDispatch xDispatch = null ; + com.sun.star.util.URL aURL = null ; + synchronized(this) + { + bIsStatusListener = m_bIsStatusListener; + m_bIsStatusListener = false; + + xDispatch = m_xDispatch; + m_xDispatch = null; + + aURL = m_aURL; + xFrame = m_xFrame; + } + + if (bIsStatusListener) + xDispatch.removeStatusListener(this,aURL); + xDispatch = null; + + if (! bRegister) + return; + + com.sun.star.frame.XDispatchProvider xProvider = UnoRuntime.queryInterface( + com.sun.star.frame.XDispatchProvider.class, + xFrame); + + if (xProvider==null) + return; + + xDispatch = xProvider.queryDispatch(aURL,"",0); + + if (xDispatch==null) + return; + + xDispatch.addStatusListener(this,aURL); + synchronized(this) + { + m_xDispatch = xDispatch; + m_bIsStatusListener = true; + } + } + + + + /** + * callback for disposing events + * Our dispatch or frame object inform us about his following dead ... + * So we must forget his reference. But it's not necessary to + * remove listener connections here. Because the broadcaster + * forget us automatically. The only thing we have to do: release + * his reference and let him die! + * + * @param aEvent + * describes the source which fire this event + * Must be our internal saved dispatch or frame. Otherwise + * somewhere know us without a registration ... + */ + public /*ONEWAY*/ void disposing(/*IN*/ com.sun.star.lang.EventObject aEvent) + { + synchronized(this) + { + if (m_bDead) + return; + if (m_xFrame!=null && UnoRuntime.areSame(aEvent.Source,m_xFrame)) + { + m_bIsActionListener = false; + m_xFrame = null ; + } + else + if (m_xDispatch!=null && UnoRuntime.areSame(aEvent.Source,m_xDispatch)) + { + m_bIsStatusListener = false; + m_xDispatch = null ; + m_aURL = null ; + } + } + shutdown(); + } + + + + /** + * If this java application shutdown - we must cancel all current existing + * listener connections. Otherwise the office will run into some + * DisposedExceptions if it tries to use these forgotten listener references. + * And of course it can die doing that. + * We are registered at a central object to be informed if the VM will exit. + * So we can react. + */ + public void shutdown() + { + boolean bIsActionListener = false; + boolean bIsStatusListener = false; + com.sun.star.frame.XFrame xFrame = null ; + com.sun.star.frame.XDispatch xDispatch = null ; + com.sun.star.util.URL aURL = null ; + synchronized(this) + { + // don't react a second time here! + if (m_bDead) + return; + m_bDead = true; + + bIsActionListener = m_bIsActionListener; + m_bIsActionListener = false; + + bIsStatusListener = m_bIsStatusListener; + m_bIsStatusListener = false; + + xFrame = m_xFrame; + m_xFrame = null; + + xDispatch = m_xDispatch; + m_xDispatch = null; + + aURL = m_aURL; + m_aURL = null; + } + + if (bIsStatusListener) + xDispatch.removeStatusListener(this,aURL); + xDispatch = null ; + aURL = null ; + + if (bIsActionListener) + xFrame.removeFrameActionListener(this); + xFrame = null ; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/StatusView.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/StatusView.java new file mode 100644 index 000000000..92ae178ad --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/StatusView.java @@ -0,0 +1,264 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import java.awt.*; +import javax.swing.*; + +// __________ Implementation __________ + +/** + * Implement a view to show status information + * of currently loaded document of a document view. + * It uses separate listener threads to get this information + * and actualize it automatically, if frame broadcast changes of + * his contained document. + * Threads are necessary to prevent this view against deadlocks. + * These deadlocks can occur if a listener will be notified + * by the office in an "oneway" method and try to call back + * to the office by using a synchronous method. + * UNO must guarantee order of all these calls ... and if + * the source of arrived event holds a mutex and our synchronous + * call needs this mutex too => a deadlock occurs. + * Why? UNO had created a new thread for our synchronous call + * inside the office process and so exist different threads + * for this constellation. + * + */ +public class StatusView extends JPanel + implements IShutdownListener +{ + + + /** + * const + * These URL's describe available feature states. + */ + private static final String FEATUREURL_FONT = "slot:10007"; + private static final String FEATUREURL_SIZE = "slot:10015"; + private static final String FEATUREURL_BOLD = "slot:10009"; + private static final String FEATUREURL_ITALIC = "slot:10008"; + private static final String FEATUREURL_UNDERLINE = "slot:10014"; + + + + /** + * const + * These values are used to show current state of showed feature. + */ + private static final String FONT_OFF = "unknown" ; + private static final String SIZE_OFF = "0.0" ; + private static final String BOLD_OFF = "-" ; + private static final String ITALIC_OFF = "-" ; + private static final String UNDERLINE_OFF = "-" ; + + private static final String FONT_ON = "" ; + private static final String SIZE_ON = "" ; + private static final String BOLD_ON = "X" ; + private static final String ITALIC_ON = "X" ; + private static final String UNDERLINE_ON = "X" ; + + + + /** + * @member mlaFontValue shows status of font name + * @member mlaSizeValue shows status of font size + * @member mlaBoldValue shows status of font style bold + * @member mlaUnderlineValue shows status of font style underline + * @member mlaItalicValue shows status of font style italic + * + * @member maFontListener threadsafe(!) helper to listen for status event which describe font name + * @member maSizeListener threadsafe(!) helper to listen for status event which describe font size + * @member maBoldListener threadsafe(!) helper to listen for status event which describe font style bold + * @member maUnderlineListener threadsafe(!) helper to listen for status event which describe font style underline + * @member maItalicListener threadsafe(!) helper to listen for status event which describe font style italic + */ + private final JLabel m_laFontValue ; + private final JLabel m_laSizeValue ; + private final JLabel m_laBoldValue ; + private final JLabel m_laUnderlineValue ; + private final JLabel m_laItalicValue ; + + private StatusListener m_aFontListener ; + private StatusListener m_aSizeListener ; + private StatusListener m_aBoldListener ; + private StatusListener m_aUnderlineListener ; + private StatusListener m_aItalicListener ; + + + + /** + * ctor + * Create view controls on startup and initialize it with default values. + * Filling of view items can be done by special set-methods. + * We don't start listening here! see setFrame() for that ... + */ + StatusView() + { + this.setLayout(new GridBagLayout()); + + GridBagConstraints aConstraint = new GridBagConstraints(); + aConstraint.anchor = GridBagConstraints.NORTHWEST; + aConstraint.insets = new Insets(2,2,2,2); + aConstraint.gridy = 0; + aConstraint.gridx = 0; + + JLabel laFont = new JLabel("Font" ); + JLabel laSize = new JLabel("Size" ); + JLabel laBold = new JLabel("Bold" ); + JLabel laUnderline = new JLabel("Underline"); + JLabel laItalic = new JLabel("Italic" ); + + m_laFontValue = new JLabel(); + m_laSizeValue = new JLabel(); + m_laBoldValue = new JLabel(); + m_laUnderlineValue = new JLabel(); + m_laItalicValue = new JLabel(); + + aConstraint.gridx = 0; + this.add( laFont, aConstraint ); + aConstraint.gridx = 1; + this.add( m_laFontValue, aConstraint ); + + ++aConstraint.gridy; + + aConstraint.gridx = 0; + this.add( laSize, aConstraint ); + aConstraint.gridx = 1; + this.add( m_laSizeValue, aConstraint ); + + ++aConstraint.gridy; + + aConstraint.gridx = 0; + this.add( laSize, aConstraint ); + aConstraint.gridx = 1; + this.add( m_laSizeValue, aConstraint ); + + ++aConstraint.gridy; + + aConstraint.gridx = 0; + this.add( laBold, aConstraint ); + aConstraint.gridx = 1; + this.add( m_laBoldValue, aConstraint ); + + ++aConstraint.gridy; + + aConstraint.gridx = 0; + this.add( laUnderline, aConstraint ); + aConstraint.gridx = 1; + this.add( m_laUnderlineValue, aConstraint ); + + ++aConstraint.gridy; + + aConstraint.gridx = 0; + this.add( laItalic, aConstraint ); + aConstraint.gridx = 1; + this.add( m_laItalicValue, aConstraint ); + + m_laFontValue.setEnabled (false); + m_laSizeValue.setEnabled (false); + m_laBoldValue.setEnabled (false); + m_laItalicValue.setEnabled (false); + m_laUnderlineValue.setEnabled(false); + + m_laFontValue.setText (FONT_OFF ); + m_laSizeValue.setText (SIZE_OFF ); + m_laBoldValue.setText (BOLD_OFF ); + m_laItalicValue.setText (ITALIC_OFF ); + m_laUnderlineValue.setText(UNDERLINE_OFF); + } + + + + /* + * Set new frame for this view and start listening for events immediately. + * We create one status listener for every control we wish to update. + * And because the environment of the frame can be changed - these + * listener refresh himself internally for frame action events too. + * So we register it as such frame action listener only here. + * Rest is done automatically... + * + * @param xFrame + * will be used as source of possible status events + */ + public void setFrame(com.sun.star.frame.XFrame xFrame) + { + if (xFrame==null) + return; + + // create some listener on given frame for available status events + // Created listener instances will register themselves on this frame and + // show it received information automatically on set UI controls. + m_aFontListener = new StatusListener(m_laFontValue ,FONT_ON ,FONT_OFF ,xFrame, FEATUREURL_FONT ); + m_aSizeListener = new StatusListener(m_laSizeValue ,SIZE_ON ,SIZE_OFF ,xFrame, FEATUREURL_SIZE ); + m_aBoldListener = new StatusListener(m_laBoldValue ,BOLD_ON ,BOLD_OFF ,xFrame, FEATUREURL_BOLD ); + m_aItalicListener = new StatusListener(m_laItalicValue ,ITALIC_ON ,ITALIC_OFF ,xFrame, FEATUREURL_ITALIC ); + m_aUnderlineListener = new StatusListener(m_laUnderlineValue,UNDERLINE_ON,UNDERLINE_OFF,xFrame, FEATUREURL_UNDERLINE); + + m_aFontListener.startListening(); + m_aSizeListener.startListening(); + m_aBoldListener.startListening(); + m_aItalicListener.startListening(); + m_aUnderlineListener.startListening(); + } + + + + /** + * If this java application shutdown - we must cancel all current existing + * listener connections. Otherwise the office will run into some + * DisposedExceptions if it tries to use these forgotten listener references. + * And of course it can die doing that. + * We are registered at a central object to be informed if the VM will exit. + * So we can react. + */ + public void shutdown() + { + m_aFontListener.shutdown(); + m_aSizeListener.shutdown(); + m_aBoldListener.shutdown(); + m_aItalicListener.shutdown(); + m_aUnderlineListener.shutdown(); + + m_aFontListener = null; + m_aSizeListener = null; + m_aBoldListener = null; + m_aItalicListener = null; + m_aUnderlineListener = null; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/ViewContainer.java b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/ViewContainer.java new file mode 100644 index 000000000..d859f2035 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/ViewContainer.java @@ -0,0 +1,260 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import java.util.*; + +// __________ Implementation __________ + +/** + * It's implement a static container which hold + * all opened documents and her views alive. + * It's possible to register/deregister such views, + * to get information about these and it provides + * some global functionality - like termination of + * this demo application. + * + */ +public class ViewContainer extends Thread +{ + + + /** + * provides a singleton view container + * Necessary for terminate(9 functionality to be able + * to call Runtime.runFinilization(). + * + * @return a reference to the singleton ViewContainer instance + */ + public static synchronized ViewContainer getGlobalContainer() + { + if (maSingleton==null) + maSingleton=new ViewContainer(); + return maSingleton; + } + + + + /** + * ctor + * It's private - because nobody should create any instance + * expect the only global one, which will be created by ourself! + */ + private ViewContainer() + { + mlViews = new ArrayList<Object>(); + mlListener = new ArrayList<IShutdownListener>(); + mbShutdownActive = false ; + Runtime.getRuntime().addShutdownHook(this); + } + + + + /** + * This register a new view inside this global container + * (if it doesn't already exist). + * + * @param aView view which wishes to be registered inside this container + */ + public void addView(Object aView) + { + synchronized(mlViews) + { + if(!mlViews.contains(aView)) + mlViews.add(aView); + } + } + + + + /** + * This deregister a view from this global container. + * Normally it should be the last reference to the view + * and her finalize() method should be called. + * If last view will be closed here - we terminate these + * java application too. Because there is no further + * visible frame anymore. + * + * @param aView + * view object which wishes to be deregistered + */ + public void removeView(Object aView) + { + int nViewCount = 0; + synchronized(mlViews) + { + if(mlViews.contains(aView)) + mlViews.remove(aView); + + nViewCount = mlViews.size(); + + if (nViewCount<1) + mlViews = null; + } + // If this view is a registered shutdown listener on this view container + // too, we must call his interface and forget him as possible listener. + // It's necessary to guarantee his dead ... + boolean bShutdownView = false; + synchronized(mlListener) + { + bShutdownView = mlListener.contains(aView); + if (bShutdownView) + mlListener.remove(aView); + } + if (bShutdownView) + ((IShutdownListener)aView).shutdown(); + + // We use a system.exit() to finish the whole application. + // And further we have registered THIS instance as a possible shutdown + // hook at the runtime class. So our run() method will be called. + // Our view container should be empty - but + // our listener container can include some references. + // These objects will be informed then and release e.g. some + // remote references. + if (nViewCount<1) + { + boolean bNecessary = false; + synchronized(this) + { + bNecessary = ! mbShutdownActive; + } + if (bNecessary) + { + System.out.println("call exit(0)!"); + System.exit(0); + } + } + } + + + + /** + * add/remove listener for possible shutdown events + */ + public void addListener( IShutdownListener rListener ) + { + synchronized(mlListener) + { + if ( ! mlListener.contains(rListener) ) + mlListener.add(rListener); + } + } + + + + private void removeListener( IShutdownListener rListener ) + { + synchronized(mlListener) + { + if ( mlListener.contains(rListener) ) + mlListener.remove(rListener); + } + } + + + + /** + * Is called from current runtime system of the java machine + * on shutdown. We inform all current registered listener and + * views. They should deinitialize her internal things then. + */ + @Override + public void run() + { + synchronized(this) + { + if (mbShutdownActive) + return; + mbShutdownActive=true; + } + + while( true ) + { + IShutdownListener aListener = null; + synchronized(mlListener) + { + if (!mlListener.isEmpty()) + aListener = mlListener.get(0); + } + if (aListener==null) + break; + + aListener.shutdown(); + // May this listener has deregistered himself. + // But if not we must do it for him. Our own + // method "removeListener()" ignore requests for + // already gone listener objects. + removeListener(aListener); + } + + if (mlViews!=null) + { + synchronized(mlViews) + { + mlViews.clear(); + mlViews = null; + } + } + + if (mlListener!=null) + { + synchronized(mlListener) + { + mlListener.clear(); + mlListener = null; + } + } + } + + + + /** + * @member mbInplace indicates using of inplace office frames instead of outplace ones + * @member maSingleton singleton instance of this view container + * @member mlViews list of all currently registered document views + * @member mlListener list of all currently registered shutdown listener + * @member mbShutdownActive if this shutdown hook already was started it's not a good idea to + * call System.exit() again for other conditions. + * We suppress it by using this variable! + */ + public static boolean mbInplace = false ; + private static ViewContainer maSingleton = null ; + private ArrayList<Object> mlViews ; + private ArrayList<IShutdownListener> mlListener ; + private boolean mbShutdownActive ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/Makefile b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/Makefile new file mode 100644 index 000000000..aa7a158b8 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/Makefile @@ -0,0 +1,72 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevDesktopEnvironment native library of the Developers Guide. + +PRJ=../../../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +SHL_NAME=nativeview +SHL_LIBRARY=$(SHAREDLIB_OUT)/$(SHAREDLIB_PRE)$(SHL_NAME).$(SHAREDLIB_EXT) + +OUT_SHL_SLO=$(OUT_SLO)/nativeview + +CFILES = nativeview.c + +SLOFILES = $(patsubst %.c,$(OUT_SHL_SLO)/%.$(OBJ_EXT),$(CFILES)) + + +# Targets +.PHONY: ALL +ALL : $(SHL_LIBRARY) + +include $(SETTINGS)/stdtarget.mk + +$(OUT_SHL_SLO)/%.$(OBJ_EXT) : %.c + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(CC) $(CC_FLAGS_JNI) $(CC_INCLUDES) $(SDK_JAVA_INCLUDES) $(CC_DEFINES_JNI) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $< + +$(SHAREDLIB_OUT)/$(SHAREDLIB_PRE)$(SHL_NAME).$(SHAREDLIB_EXT) : $(SLOFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(LINK) $(LIBRARY_LINK_FLAGS) $(LINK_LIBS) $(LINK_JAVA_LIBS) -o $@ $< \ + -ljawt $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STDC++LIB) + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_SHL_SLO)) + -$(DEL) $(subst /,$(PS),$(SHAREDLIB_OUT))$(PS)*$(SHL_NAME)*.* diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/nativeview.c b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/nativeview.c new file mode 100644 index 000000000..5343f85e9 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/nativeview.c @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Intrinsic.h> + +#include "jawt.h" +#include "jawt_md.h" +#include "nativeview.h" + +#define MY_ASSERT(X,S) if (!X) { fprintf(stderr,S); return 0;} + +#define SYSTEM_WIN32 1 +#define SYSTEM_WIN16 2 +#define SYSTEM_JAVA 3 +#define SYSTEM_OS2 4 +#define SYSTEM_MAC 5 +#define SYSTEM_XWINDOW 6 + +/*****************************************************************************/ +/* + * Class: NativeView + * Method: getNativeWindowSystemType + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_NativeView_getNativeWindowSystemType + (JNIEnv * env, jobject obj_this) +{ + return SYSTEM_XWINDOW; +} + +/*****************************************************************************/ +/* + * Class: NativeView + * Method: getNativeWindow + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_NativeView_getNativeWindow + (JNIEnv * env, jobject obj_this) +{ + jboolean result ; + jint lock ; + JAWT awt ; + JAWT_DrawingSurface* ds ; + JAWT_DrawingSurfaceInfo* dsi ; + JAWT_X11DrawingSurfaceInfo* dsi_x11 ; + Drawable drawable; + + /* Get the AWT */ + awt.version = JAWT_VERSION_1_3; + result = JAWT_GetAWT(env, &awt); + MY_ASSERT(result != JNI_FALSE,"wrong jawt version"); + + /* Get the drawing surface */ + if ((ds = awt.GetDrawingSurface(env, obj_this)) == NULL) + return 0; + + /* Lock the drawing surface */ + lock = ds->Lock(ds); + MY_ASSERT((lock & JAWT_LOCK_ERROR)==0,"can't lock the drawing surface"); + + /* Get the drawing surface info */ + dsi = ds->GetDrawingSurfaceInfo(ds); + + /* Get the platform-specific drawing info */ + dsi_x11 = (JAWT_X11DrawingSurfaceInfo*)dsi->platformInfo; + drawable = dsi_x11->drawable; + + /* Free the drawing surface info */ + ds->FreeDrawingSurfaceInfo(dsi); + /* Unlock the drawing surface */ + ds->Unlock(ds); + /* Free the drawing surface */ + awt.FreeDrawingSurface(ds); + + return (jlong)drawable; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/nativeview.h b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/nativeview.h new file mode 100644 index 000000000..99207192f --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/unix/nativeview.h @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class org_openoffice_OpenOffice */ + +#ifndef _Included_NativeView +#define _Included_NativeView +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_openoffice_OpenOffice + * Method: getNativeWindowSystemType + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_NativeView_getNativeWindowSystemType(JNIEnv*, jobject); + +/* + * Class: org_openoffice_OpenOffice + * Method: getNativeWindow + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_NativeView_getNativeWindow(JNIEnv*, jobject); + +#ifdef __cplusplus +} +#endif +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/Makefile b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/Makefile new file mode 100644 index 000000000..62980a2ee --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/Makefile @@ -0,0 +1,77 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevDesktopEnvironment native library of the Developers Guide. + +PRJ=../../../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +SHL_NAME=nativeview +SHL_LIBRARY=$(SHAREDLIB_OUT)/$(SHAREDLIB_PRE)$(SHL_NAME).$(SHAREDLIB_EXT) + +OUT_SHL_SLO=$(OUT_SLO)/nativeview +OUT_SHL_MISC=$(OUT_MISC)/nativeview + +CFILES = nativeview.c + +SLOFILES = $(patsubst %.c,$(OUT_SHL_SLO)/%.$(OBJ_EXT),$(CFILES)) + +# Targets +.PHONY: ALL +ALL : \ + $(SHL_LIBRARY) + +include $(SETTINGS)/stdtarget.mk + +$(OUT_SHL_SLO)/%.$(OBJ_EXT) : %.c + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(CC) $(CC_FLAGS_JNI) $(CC_INCLUDES) $(SDK_JAVA_INCLUDES) $(CC_DEFINES_JNI) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $< + +$(SHAREDLIB_OUT)/$(SHAREDLIB_PRE)$(SHL_NAME).$(SHAREDLIB_EXT) : $(SLOFILES) $(SHL_NAME).def + -$(MKDIR) $(subst /,$(PS),$(@D)) + -$(MKDIR) $(subst /,$(PS),$(OUT_SHL_MISC)) + $(LINK) $(LIBRARY_LINK_FLAGS) /DEF:$(SHL_NAME).def /OUT:$@ \ + /MAP:$(OUT_SHL_MISC)/$(SHL_NAME).map $(LINK_JAVA_LIBS) \ + $(SLOFILES) jawt.lib $(LIBO_SDK_LDFLAGS_STDLIBS) user32.lib + $(LINK_MANIFEST) + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_SHL_SLO)) + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_SHL_MISC)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(SHAREDLIB_OUT))$(PS)*$(SHL_NAME)*.*) diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.c b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.c new file mode 100644 index 000000000..2de998c69 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.c @@ -0,0 +1,181 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +#include <windows.h> + +#include "jawt.h" +#include "jawt_md.h" +#include "NativeView.h" + +#define MY_ASSERT(X,S) if (!X) { fprintf(stderr,"%s\n",S); return 0;} + +#define SYSTEM_WIN32 1 +#define SYSTEM_WIN16 2 +#define SYSTEM_JAVA 3 +#define SYSTEM_OS2 4 +#define SYSTEM_MAC 5 +#define SYSTEM_XWINDOW 6 + +// property name to register own window procedure on hwnd +#define OLD_PROC_KEY "oldwindowproc" +// signature of this window procedure +static LRESULT APIENTRY NativeViewWndProc( HWND , UINT , WPARAM , LPARAM ); + +/***************************************************************************** + * + * Class : NativeView + * Method : getNativeWindowSystemType + * Signature : ()I + * Description: returns an identifier for the current operating system + */ +JNIEXPORT jint JNICALL Java_NativeView_getNativeWindowSystemType + (JNIEnv * env, jobject obj_this) +{ + return SYSTEM_WIN32; +} + +/***************************************************************************** + * + * Class : NativeView + * Method : getNativeWindow + * Signature : ()J + * Description: returns the native systemw window handle of this object + */ +JNIEXPORT jlong JNICALL Java_NativeView_getNativeWindow + (JNIEnv * env, jobject obj_this) +{ + jboolean result ; + jint lock ; + JAWT awt ; + JAWT_DrawingSurface* ds ; + JAWT_DrawingSurfaceInfo* dsi ; + JAWT_Win32DrawingSurfaceInfo* dsi_win ; + HDC hdc ; + HWND hWnd ; + LONG hFuncPtr; + + /* Get the AWT */ + awt.version = JAWT_VERSION_1_3; + result = JAWT_GetAWT(env, &awt); + MY_ASSERT(result!=JNI_FALSE,"wrong jawt version"); + + /* Get the drawing surface */ + if ((ds = awt.GetDrawingSurface(env, obj_this)) == NULL) + return 0; + + /* Lock the drawing surface */ + lock = ds->Lock(ds); + MY_ASSERT((lock & JAWT_LOCK_ERROR)==0,"can't lock the drawing surface"); + + /* Get the drawing surface info */ + dsi = ds->GetDrawingSurfaceInfo(ds); + + /* Get the platform-specific drawing info */ + dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo; + hdc = dsi_win->hdc; + hWnd = dsi_win->hwnd; + + /* Free the drawing surface info */ + ds->FreeDrawingSurfaceInfo(dsi); + /* Unlock the drawing surface */ + ds->Unlock(ds); + /* Free the drawing surface */ + awt.FreeDrawingSurface(ds); + + /* Register own window procedure + Do it one times only! Otherwise + multiple instances will be registered + and calls on such construct produce + a stack overflow. + */ + if (GetProp( hWnd, OLD_PROC_KEY )==0) + { + hFuncPtr = SetWindowLongPtr( hWnd, GWLP_WNDPROC, (LONG_PTR)NativeViewWndProc ); + SetProp( hWnd, OLD_PROC_KEY, (HANDLE)hFuncPtr ); + } + + return (jlong)hWnd; +} + +/***************************************************************************** + * + * Class : - + * Method : NativeViewWndProc + * Signature : - + * Description: registered window handler to intercept window messages between + * java and office process + */ +static LRESULT APIENTRY NativeViewWndProc( + HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + HANDLE hFuncPtr; + + /* resize new created child window to fill out the java window complete */ + if (uMsg==WM_PARENTNOTIFY) + { + if (wParam == WM_CREATE) + { + RECT rect; + HWND hChild = (HWND) lParam; + + GetClientRect(hWnd, &rect); + + SetWindowPos(hChild, + NULL, + rect.left, + rect.top, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOZORDER); + } + } + /* handle normal resize events */ + else if(uMsg==WM_SIZE) + { + WORD newHeight = HIWORD(lParam); + WORD newWidth = LOWORD(lParam); + HWND hChild = GetWindow(hWnd, GW_CHILD); + + if (hChild != NULL) + SetWindowPos(hChild, NULL, 0, 0, newWidth, newHeight, SWP_NOZORDER); + } + + /* forward request to original handler which is intercepted by this window procedure */ + hFuncPtr = GetProp(hWnd, OLD_PROC_KEY); + MY_ASSERT(hFuncPtr,"lost original window proc handler"); + return CallWindowProc( hFuncPtr, hWnd, uMsg, wParam, lParam); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.def b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.def new file mode 100644 index 000000000..f9ba2a78b --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.def @@ -0,0 +1,3 @@ +EXPORTS
+Java_NativeView_getNativeWindowSystemType
+Java_NativeView_getNativeWindow
diff --git a/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.h b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.h new file mode 100644 index 000000000..99207192f --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DesktopEnvironment/nativelib/windows/nativeview.h @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class org_openoffice_OpenOffice */ + +#ifndef _Included_NativeView +#define _Included_NativeView +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_openoffice_OpenOffice + * Method: getNativeWindowSystemType + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_NativeView_getNativeWindowSystemType(JNIEnv*, jobject); + +/* + * Class: org_openoffice_OpenOffice + * Method: getNativeWindow + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_NativeView_getNativeWindow(JNIEnv*, jobject); + +#ifdef __cplusplus +} +#endif +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DisableCommands/DisableCommandsTest.java b/odk/examples/DevelopersGuide/OfficeDev/DisableCommands/DisableCommandsTest.java new file mode 100644 index 000000000..0d4b09bf0 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DisableCommands/DisableCommandsTest.java @@ -0,0 +1,397 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.configuration.theDefaultProvider; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.util.XURLTransformer; +import com.sun.star.frame.XComponentLoader; +import com.sun.star.text.XTextDocument; + +/* + * Provides example code how to enable/disable + * commands. + */ +public class DisableCommandsTest { + + /* + * A list of command names + */ + final private static String[] aCommandURLTestSet = + { + "Open", + "About", + "SelectAll", + "Quit", + }; + + private static XComponentContext xRemoteContext = null; + private static XMultiComponentFactory xRemoteServiceManager = null; + private static XURLTransformer xTransformer = null; + private static XMultiServiceFactory xConfigProvider = null; + + /* + * @param args the command line arguments + */ + public static void main(String[] args) { + + try { + // get the remote office context. If necessary a new office + // process is started + xRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + xRemoteServiceManager = xRemoteContext.getServiceManager(); + + Object transformer = xRemoteServiceManager.createInstanceWithContext( + "com.sun.star.util.URLTransformer", xRemoteContext ); + xTransformer = UnoRuntime.queryInterface(com.sun.star.util.XURLTransformer.class, + transformer ); + + xConfigProvider = theDefaultProvider.get(xRemoteContext); + + // create a new test document + Object oDesktop = xRemoteServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", xRemoteContext); + + XComponentLoader xCompLoader =UnoRuntime.queryInterface(XComponentLoader.class, oDesktop); + + com.sun.star.lang.XComponent xComponent = + xCompLoader.loadComponentFromURL("private:factory/swriter", + "_blank", 0, new com.sun.star.beans.PropertyValue[0]); + { + XTextDocument xDoc =UnoRuntime.queryInterface(XTextDocument.class, xComponent); + xDoc.getText().setString("You can now check the disabled commands. The " + +"following commands are disabled:\n\n" + +" Open...\n Exit\n Select All\n " + +"About StarOffice|OpenOffice\n\nPress " + + "\"return\" in the shell where you have " + + "started the example to enable the " + + "commands!\n\nCheck the commands again and " + + "press once more \"return\" to finish the " + + "example and close the document."); + + // ensure that the document content is optimal visible + com.sun.star.frame.XModel xModel = + UnoRuntime.queryInterface( + com.sun.star.frame.XModel.class, xDoc); + // get the frame for later usage + com.sun.star.frame.XFrame xFrame = + xModel.getCurrentController().getFrame(); + + com.sun.star.view.XViewSettingsSupplier xViewSettings = + UnoRuntime.queryInterface( + com.sun.star.view.XViewSettingsSupplier.class, + xModel.getCurrentController()); + xViewSettings.getViewSettings().setPropertyValue( + "ZoomType", Short.valueOf((short)0)); + } + // test document will be closed later + + // First we need a defined starting point. So we have to remove + // all commands from the disabled set! + enableCommands(); + + // Check if the commands are usable + testCommands( false ); + + // Disable the commands + disableCommands(); + + // Now the commands shouldn't be usable anymore + testCommands( true ); + + // you can now check the test document and see which commands are + // disabled + System.out.println("\nYou can now check the disabled commands.\n" + +"Please press 'return' to enable the commands!"); + waitForUserInput(); + + // Remove disable commands to make Office usable again + enableCommands(); + + // you can check the test document again and see that the commands + // are enabled now + System.out.println("Check again the now enabled commands.\n" + +"Please press 'return' to finish the example and " + +"close the document!"); + waitForUserInput(); + + // close test document + com.sun.star.util.XCloseable xCloseable = UnoRuntime.queryInterface(com.sun.star.util.XCloseable.class, + xComponent ); + + if (xCloseable != null ) { + xCloseable.close(false); + } else + { + xComponent.dispose(); + } + } + catch (java.lang.Exception e){ + e.printStackTrace(); + } + finally { + System.exit(0); + } + } + + /** + * Wait for user input -> until the user press 'return' + */ + private static void waitForUserInput() throws java.io.IOException { + + java.io.BufferedReader reader + = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); + + reader.read(); + } + + /** + * Test the commands that we enabled/disabled + */ + private static void testCommands( boolean bDisabledCmds ) + throws com.sun.star.uno.Exception + { + // We need the desktop to get access to the current frame + Object desktop = xRemoteServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", xRemoteContext ); + com.sun.star.frame.XDesktop xDesktop = UnoRuntime.queryInterface(com.sun.star.frame.XDesktop.class, desktop ); + com.sun.star.frame.XFrame xFrame = xDesktop.getCurrentFrame(); + com.sun.star.frame.XDispatchProvider xDispatchProvider = null; + if ( xFrame != null ) + { + // We have a frame. Now we need access to the dispatch provider. + xDispatchProvider = + UnoRuntime.queryInterface( + com.sun.star.frame.XDispatchProvider.class, xFrame ); + if ( xDispatchProvider != null ) + { + // As we have the dispatch provider we can now check if we get + // a dispatch object or not. + for ( int n = 0; n < aCommandURLTestSet.length; n++ ) + { + // Prepare the URL + com.sun.star.util.URL[] aURL = new com.sun.star.util.URL[1]; + aURL[0] = new com.sun.star.util.URL(); + com.sun.star.frame.XDispatch xDispatch = null; + + aURL[0].Complete = ".uno:" + aCommandURLTestSet[n]; + xTransformer.parseSmart( aURL, ".uno:" ); + + // Try to get a dispatch object for our URL + xDispatch = xDispatchProvider.queryDispatch( aURL[0], "", 0 ); + + if ( xDispatch != null ) + { + if ( bDisabledCmds ) + System.out.println( + "Something is wrong, I got dispatch object for " + + aURL[0].Complete ); + else + System.out.println( "Ok, dispatch object for " + + aURL[0].Complete ); + } + else + { + if ( !bDisabledCmds ) + System.out.println("Something is wrong, I cannot get dispatch object for " + aURL[0].Complete ); + else + System.out.println( "Ok, no dispatch object for " + + aURL[0].Complete ); + } + resetURL( aURL[0] ); + } + } + else + System.out.println( "Couldn't get XDispatchProvider from Frame!" ); + } + else + System.out.println( "Couldn't get current Frame from Desktop!" ); + } + + /** + * Ensure that there are no disabled commands in the user layer. The + * implementation removes all commands from the disabled set! + */ + private static void enableCommands() { + // Set the root path for our configuration access + com.sun.star.beans.PropertyValue[] lParams = + new com.sun.star.beans.PropertyValue[1]; + + lParams[0] = new com.sun.star.beans.PropertyValue(); + lParams[0].Name = "nodepath"; + lParams[0].Value = "/org.openoffice.Office.Commands/Execute/Disabled"; + + try { + // Create configuration update access to have write access to the + // configuration + Object xAccess = xConfigProvider.createInstanceWithArguments( + "com.sun.star.configuration.ConfigurationUpdateAccess", + lParams ); + + com.sun.star.container.XNameAccess xNameAccess = + UnoRuntime.queryInterface( + com.sun.star.container.XNameAccess.class, xAccess ); + + if ( xNameAccess != null ) { + // We need the XNameContainer interface to remove the nodes by name + com.sun.star.container.XNameContainer xNameContainer = + UnoRuntime.queryInterface( + com.sun.star.container.XNameContainer.class, xAccess ); + + // Retrieves the names of all Disabled nodes + String[] aCommandsSeq = xNameAccess.getElementNames(); + for ( int n = 0; n < aCommandsSeq.length; n++ ) { + try { + // remove the node + xNameContainer.removeByName( aCommandsSeq[n] ); + } + catch ( com.sun.star.lang.WrappedTargetException e ) { + } + catch ( com.sun.star.container.NoSuchElementException e ) { + } + } + } + + // Commit our changes + com.sun.star.util.XChangesBatch xFlush = + UnoRuntime.queryInterface( + com.sun.star.util.XChangesBatch.class, xAccess); + + xFlush.commitChanges(); + } + catch ( com.sun.star.uno.Exception e ) { + System.out.println( "Exception detected!" ); + System.out.println( e ); + } + } + + /** + * Disable all commands defined in the aCommandURLTestSet array + */ + private static void disableCommands() { + // Set the root path for our configuration access + com.sun.star.beans.PropertyValue[] lParams = + new com.sun.star.beans.PropertyValue[1]; + + lParams[0] = new com.sun.star.beans.PropertyValue(); + lParams[0].Name = "nodepath"; + lParams[0].Value = "/org.openoffice.Office.Commands/Execute/Disabled"; + + try { + // Create configuration update access to have write access to the + // configuration + Object xAccess = xConfigProvider.createInstanceWithArguments( + "com.sun.star.configuration.ConfigurationUpdateAccess", + lParams ); + + com.sun.star.lang.XSingleServiceFactory xSetElementFactory = + UnoRuntime.queryInterface( + com.sun.star.lang.XSingleServiceFactory.class, xAccess ); + + com.sun.star.container.XNameContainer xNameContainer = + UnoRuntime.queryInterface( + com.sun.star.container.XNameContainer.class, xAccess ); + + if ( xSetElementFactory != null && xNameContainer != null ) { + Object[] aArgs = new Object[0]; + + for ( int i = 0; i < aCommandURLTestSet.length; i++ ) { + // Create the nodes with the XSingleServiceFactory of the + // configuration + Object xNewElement = + xSetElementFactory.createInstanceWithArguments( aArgs ); + + if ( xNewElement != null ) { + // We have a new node. To set the properties of the node + // we need the XPropertySet interface. + com.sun.star.beans.XPropertySet xPropertySet = + UnoRuntime.queryInterface( + com.sun.star.beans.XPropertySet.class, + xNewElement ); + + if ( xPropertySet != null ) { + // Create a unique node name. + String aCmdNodeName = "Command-"; + aCmdNodeName += i; + + // Insert the node into the Disabled set + xPropertySet.setPropertyValue( "Command", + aCommandURLTestSet[i] ); + xNameContainer.insertByName( aCmdNodeName, + xNewElement ); + } + } + } + + // Commit our changes + com.sun.star.util.XChangesBatch xFlush = + UnoRuntime.queryInterface( + com.sun.star.util.XChangesBatch.class, xAccess); + xFlush.commitChanges(); + } + } + catch ( com.sun.star.uno.Exception e ) + { + System.err.println( "Exception detected!" + e); + e.printStackTrace(); + } + } + + /** + * reset URL so it can be reused + * + * @param aURL + * the URL that should be reset + */ + private static void resetURL( com.sun.star.util.URL aURL ) + { + aURL.Protocol = ""; + aURL.User = ""; + aURL.Password = ""; + aURL.Server = ""; + aURL.Port = 0; + aURL.Path = ""; + aURL.Name = ""; + aURL.Arguments = ""; + aURL.Mark = ""; + aURL.Main = ""; + aURL.Complete = ""; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/DisableCommands/Makefile b/odk/examples/DevelopersGuide/OfficeDev/DisableCommands/Makefile new file mode 100644 index 000000000..0d60cb414 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/DisableCommands/Makefile @@ -0,0 +1,91 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevDisableCommandsTest example of the Developers Guide. + +PRJ=../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevDisableCommandsTest +OUT_APP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +APP1_NAME=DisableCommandsTest +APP1_JAR=$(OUT_APP_CLASS)/$(APP1_NAME).jar + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_APP_CLASS)) + + +# Targets +.PHONY: ALL +ALL : $(EXAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(OUT_APP_CLASS)/%.class : %.java + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $< + +$(OUT_APP_CLASS)/%.mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: $*>> $@ + +$(OUT_APP_CLASS)/%.jar : $(OUT_APP_CLASS)/%.mf $(OUT_APP_CLASS)/%.class + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $*.mf $*.class + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + +$(APP1_JAR) : $(OUT_APP_CLASS)/$(APP1_NAME).mf $(OUT_APP_CLASS)/$(APP1_NAME).class + +$(EXAMPLE_NAME) : $(APP1_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following command to execute the example! + @echo - + @echo $(MAKE) $(APP1_NAME).run + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_APP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_CLASS)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/AsciiReplaceFilter.java b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/AsciiReplaceFilter.java new file mode 100644 index 000000000..5ab5fb3b1 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/AsciiReplaceFilter.java @@ -0,0 +1,702 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +package FilterDevelopment.AsciiFilter; + +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.AnyConverter; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.container.XNamed; +import com.sun.star.document.XImporter; +import com.sun.star.document.XExporter; +import com.sun.star.document.XFilter; + +/*-************************************************************************ + @title implements a filter to import pure ascii text files + @description This filter can use an existing In/OutputStream of given + MediaDescriptor or use an existing URL instead of that + to open the file directly. But for second case the local + file system will be used only. There is no support for remote. + + During import/export special functionality can be used to + e.g. to change some characters inside the file content + or replace some strings (no using of regular expressions!). + User can decide at runtime which functionality really should + be used by selecting it in an extra filter property dialog. + + So we show how a filter works for import/export, use or create + streams and how a filter can offer properties for filtering + which can be edit by the user. + ************************************************************************-*/ + +public class AsciiReplaceFilter +{ + public static class _AsciiReplaceFilter extends WeakBase + implements XInitialization , + XServiceInfo , + XNamed , + XImporter , + XExporter , + XFilter + { + + + // the supported service names, the first one being the service name of the component itself + private static final String[] m_serviceNames = { "com.sun.star.comp.ansifilter.AsciiReplaceFilter" , "com.sun.star.document.ImportFilter", "com.sun.star.document.ExportFilter" }; + + // filterprocess states + private static final int FILTERPROC_RUNS = 0; + private static final int FILTERPROC_BREAK = 1; + private static final int FILTERPROC_STOPPED = 2; + + + // member + + + /// The initial component context, that gives access to the service manager, supported singletons, ... + private XComponentContext m_Ctx; + /// The service manager, that gives access to all registered services and which is passed to the FilterOptions class for instantiating a ucb service + private XMultiComponentFactory m_xMCF; + /// we must provide our name + private String m_sInternalName; + /// saved document reference for import or export (depends on other member m_bImport!) + private com.sun.star.text.XTextDocument m_xDocument; + /// because we implement an import AND an export filter, we must know which one is required + private boolean m_bImport; + // we need a flag to cancel any running filter operation + private int m_nFilterProcState; + + + // native interface + /** + * special debug helper to get an idea how expensive + * the implemented filter operations are really. + * May be useful for own purposes. + * + * To see the output inside an office environment + * use "soffice ...params... >output.txt" + */ + private final long m_nStart; + private long m_nLast ; + + private void measure( String sText ) + { + long nNow = System.currentTimeMillis(); + System.err.println(sText+"\t"+(nNow-m_nStart)+"\t"+(nNow-m_nLast)); + m_nLast = nNow; + } + + + // native interface + /** + * The constructor to initialize every instance + * + * @param Context + * the component context of the office + */ + public _AsciiReplaceFilter(XComponentContext Context ) + { + measure("ctor started"); + try + { + m_Ctx = Context ; + m_xMCF = m_Ctx.getServiceManager() ; + } + catch( Exception e ) + { + e.printStackTrace(); + } + + // these are safe, thus no errorhandling needed: + m_sInternalName = "" ; + m_xDocument = null ; + m_bImport = true ; + m_nFilterProcState = FILTERPROC_STOPPED ; + + m_nLast = System.currentTimeMillis(); + m_nStart = m_nLast; + } + + + // interface XInitialization + /** + * used for initializing after creation + * If an instance of this service is created by UNO we will be called + * automatically after that to get optional parameters of this creation call. + * E.g.: The service com.sun.star.document.FilterFactory use such mechanism + * to pass our own configuration data to this instance. + * + * @param lArguments + * This array of arbitrary objects represent our own filter configuration + * and may optional given parameters of the createWithArguments() call. + * + * @throws com.sun.star.uno.Exception + * Every exception will not be handled, but will be + * passed to the caller. + */ + public void initialize( Object[] lArguments ) throws com.sun.star.uno.Exception + { + measure("initialize {"); + + if (lArguments.length<1) + return; + + // lArguments[0] = own configuration data + com.sun.star.beans.PropertyValue[] lConfig = (com.sun.star.beans.PropertyValue[])lArguments[0]; + + /* + // lArguments[1..n] = optional arguments of create request + for (int n=1; n<lArguments.length; ++n) + { + } + */ + + // analyze own configuration data for our own internal filter name! + // Important for generic filter services, which are registered more than once. + // They can use this information to find out, which specialization of it + // is required. + for (int i=0; i<lConfig.length; ++i) + { + if (lConfig[i].Name.equals("Name")) + { + synchronized(this) + { + try + { + m_sInternalName = AnyConverter.toString(lConfig[i].Value); + } + catch(com.sun.star.lang.IllegalArgumentException exConvert) {} + } + } + } + + measure("} initialize"); + } + + + // interface XNamed + /** + * For external user of us we must provide our internal filter name + * (which is registered inside configuration package TypeDetection). + * User will be able then to ask there for further information about us. + * Otherwise we must implement a full featured XPropertySet... + * + * @return our internal filter name of configuration + */ + public String getName() + { + synchronized(this) + { + return m_sInternalName; + } + } + + /** + * It's not allowed for us - neither very easy to change our internal + * name during runtime of an office. Because every filter name must + * be unambiguous... + * So we don't implement this method here. + */ + public void setName( String sName ) + { + } + + + // interface XImporter + /** + * This interface is used to tell us: "you will be used for importing a document". + * We must save the given model reference to use it inside our own filter request. + * + * @param xDocument + * the document model for importing + * + * @throw IllegalArgumentException + * if given document isn't the right one or seems to be corrupt + */ + public void setTargetDocument( com.sun.star.lang.XComponent xDocument ) throws com.sun.star.lang.IllegalArgumentException + { + measure("setTargetDocument {"); + + if (xDocument==null) + throw new com.sun.star.lang.IllegalArgumentException("null reference detected"); + + com.sun.star.lang.XServiceInfo xInfo = UnoRuntime.queryInterface( + com.sun.star.lang.XServiceInfo.class, xDocument); + if ( ! xInfo.supportsService("com.sun.star.text.TextDocument") ) + throw new com.sun.star.lang.IllegalArgumentException( "wrong document type" ); + + // safe it as target document for import + // Don't forget to mark this filter used for importing too + synchronized(this) + { + m_xDocument = UnoRuntime.queryInterface( + com.sun.star.text.XTextDocument.class, xDocument); + m_bImport = true; + } + + measure("} setTargetDocument"); + } + + + // interface XExporter + /** + * This interface is used to tell us: "you will be used for exporting a document". + * We must save the given model reference to use it inside our own filter request. + * + * @param xDocument + * the document model for exporting + * + * @throw IllegalArgumentException + * if given document isn't the right one or seems to be corrupt + */ + public void setSourceDocument( com.sun.star.lang.XComponent xDocument ) throws com.sun.star.lang.IllegalArgumentException + { + measure("setSourceDocument {"); + + if (xDocument==null) + throw new com.sun.star.lang.IllegalArgumentException( "null reference given" ); + + com.sun.star.lang.XServiceInfo xInfo = UnoRuntime.queryInterface( + com.sun.star.lang.XServiceInfo.class, xDocument); + if ( ! xInfo.supportsService("com.sun.star.text.TextDocument") ) + throw new com.sun.star.lang.IllegalArgumentException( "wrong document type" ); + + // safe it as source document for export + // Don't forget to mark this filter used for exporting too + synchronized(this) + { + m_xDocument = UnoRuntime.queryInterface( + com.sun.star.text.XTextDocument.class, xDocument); + m_bImport = false; + } + + measure("} setSourceDocument"); + } + + + + // interface XFilter + /** + * Implements the real filter method. We detect if it must be an import or an export. + * Depends on that we use an existing stream (given inside the MediaDescriptor) + * or open it by using a URL (must be a part of the descriptor too). + * + * @param lDescriptor + * the MediaDescriptor which describes the document + * + * @return a bool value which describes if method was successful. + */ + + public boolean filter( com.sun.star.beans.PropertyValue[] lDescriptor ) + { + measure("filter {"); + + // first get state of filter operation (import/export) + // and try to create or get corresponding streams + // Means: analyze given MediaDescriptor + // By the way: use synchronized section to get some copies of other + // internal states too. + FilterOptions aOptions = null ; + boolean bImport = false; + com.sun.star.text.XTextDocument xText = null ; + synchronized(this) + { + aOptions = new FilterOptions(m_xMCF, m_Ctx, m_bImport, lDescriptor); + bImport = m_bImport; + xText = m_xDocument; + } + + measure("options analyzed"); + + if (!aOptions.isValid()) + return false; + + // start real filtering + boolean bState = false; + if (bImport) + bState = implts_import( xText, aOptions ); + else + bState = implts_export( xText, aOptions ); + + measure("} filter"); + + return bState; + } + + /** + * Makes the filter process breakable. To do so the outside code may use threads. + * We use an internal "condition" variable which is queried by the real filter method on + * every loop they do. So it's more a polling mechanism. + */ + public void cancel() + { + measure("cancel {"); + + synchronized(this) + { + if (m_nFilterProcState==FILTERPROC_RUNS) + m_nFilterProcState=FILTERPROC_BREAK; + } + + while (true) + { + synchronized(this) + { + if (m_nFilterProcState==FILTERPROC_STOPPED) + break; + } + } + + measure("} cancel"); + } + + + // private helper + /** + * This helper function imports a simple ascii text file into + * a text model. We copy every letter to the document. + * But if some optional filter options are given + * we make some changes: replace chars or complete strings. + * + * Note: It's not allowed for a filter to seek inside the stream. + * Because the outside frameloader has to set the stream position + * right and a filter must read till EOF occurs only. + * + * @param xTarget + * the target text model to put the data in + * + * @param aOptions + * capsulate all other necessary information for this filter request + * (streams, replace values ...) + * + * @return a bool value which describes if method was successful. + */ + private boolean implts_import( com.sun.star.text.XTextDocument xTarget , + FilterOptions aOptions ) + { + measure("implts_import {"); + + com.sun.star.text.XSimpleText xText = UnoRuntime.queryInterface( + com.sun.star.text.XSimpleText.class, + xTarget.getText()); + + measure("cast XSimpleText"); + + boolean bBreaked = false; + + try + { + StringBuffer sBuffer = new StringBuffer(100000); + byte[][] lData = new byte[1][]; + int nRead = aOptions.m_xInput.readBytes( lData, 4096 ); + + measure("read first bytes"); + + while (nRead>0 && !bBreaked) + { + // copy data from stream to temp. buffer + sBuffer.append( new String(lData[0]) ); + measure("buffer append ["+nRead+"]"); + + nRead = aOptions.m_xInput.readBytes( lData, 2048 ); + measure("read next bytes"); + + // check for cancelled filter proc on every loop! + synchronized(this) + { + if (m_nFilterProcState==FILTERPROC_BREAK) + { + m_nFilterProcState = FILTERPROC_STOPPED; + return false; + } + } + measure("break check"); + } + + // Make some replacements inside the buffer. + String sText = implts_replace( sBuffer, aOptions ); + measure("replace"); + + // copy current buffer to the document model. + // Create a new paragraph for every line inside original file. + // May not all data could be read - but that doesn't matter here. + // Reason: somewhere cancelled this function. + // But check for optional replace request before... + int nStart = 0; + int nEnd = -1; + int nLength = sText.length(); + + com.sun.star.text.XTextRange xCursor = UnoRuntime.queryInterface( + com.sun.star.text.XTextRange.class, + xText.createTextCursor()); + + while (true) + { + nEnd = sText.indexOf('\n',nStart); + + if (nEnd==-1 && nStart<nLength) + nEnd = nLength; + + if (nEnd==-1) + break; + + String sLine = sText.substring(nStart,nEnd); + nStart = nEnd+1; + + xText.insertString(xCursor,sLine,false); + xText.insertControlCharacter(xCursor,com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK,false); + + // check for cancelled filter proc on every loop! + synchronized(this) + { + if (m_nFilterProcState==FILTERPROC_BREAK) + { + m_nFilterProcState = FILTERPROC_STOPPED; + return false; + } + } + measure("break check"); + } + + measure("set on model"); + + // with refreshing the document we are on the safe-side, otherwise the first time the filter is used the document is not fully shown (flaw!). + com.sun.star.util.XRefreshable xRefresh = UnoRuntime.queryInterface( + com.sun.star.util.XRefreshable.class, + xTarget); + xRefresh.refresh(); + + // If we created used stream - we must close it too. + if (aOptions.m_bStreamOwner) + { + aOptions.m_xInput.closeInput(); + measure("stream close"); + } + } + catch(com.sun.star.lang.IllegalArgumentException exArgument ) { bBreaked = true; } + catch(com.sun.star.io.BufferSizeExceededException exExceed ) { bBreaked = true; } + catch(com.sun.star.io.NotConnectedException exConnect ) { bBreaked = true; } + catch(com.sun.star.io.IOException exIO ) { bBreaked = true; } + + + + measure("} implts_import"); + + return !bBreaked; + } + + /** + * This helper function exports a simple ansi text file from + * a text model. We copy every letter from the document. + * There are no checks. + * + * Note: It's not allowed for a filter to seek inside the stream. + * Because the outside frameloader has to set the stream position + * right and a filter must read till EOF occurs only. + * + * @param xSource + * the source text model to get the data from + * + * @param aOptions + * capsulate all other necessary information for this filter request + * (streams, replace values ...) + * + * @return a bool value which describes if method was successful. + */ + private boolean implts_export( com.sun.star.text.XTextDocument xSource , + FilterOptions aOptions) + { + measure("implts_export {"); + + com.sun.star.text.XTextRange xText = UnoRuntime.queryInterface( + com.sun.star.text.XSimpleText.class, + xSource.getText()); + + measure("cast XTextRange"); + + boolean bBreaked = false; + + try + { + StringBuffer sBuffer = new StringBuffer(xText.getString()); + String sText = implts_replace(sBuffer,aOptions); + + measure("get text from model"); + + // Normally this function isn't really cancelable + // But we following operation can be very expensive. So + // this place is the last one to stop it. + synchronized(this) + { + if (m_nFilterProcState==FILTERPROC_BREAK) + { + m_nFilterProcState = FILTERPROC_STOPPED; + return false; + } + } + + aOptions.m_xOutput.writeBytes(sText.getBytes()); + aOptions.m_xOutput.flush(); + + measure("written to file"); + + // If we created used stream - we must close it too. + if (aOptions.m_bStreamOwner) + { + aOptions.m_xOutput.closeOutput(); + measure("stream close"); + } + } + catch(com.sun.star.io.BufferSizeExceededException exExceed ) { bBreaked = true; } + catch(com.sun.star.io.NotConnectedException exConnect ) { bBreaked = true; } + catch(com.sun.star.io.IOException exIO ) { bBreaked = true; } + + measure("} implts_export"); + + return !bBreaked; + } + + /** + * helper function to convert the used StringBuffer into a String value. + * And we use this chance to have a look on optional filter options + * which can invite replacing of strings. + */ + private String implts_replace( StringBuffer rBuffer, FilterOptions aOptions ) + { + // replace complete strings first + // Because its easier on a buffer then on a string + if ( ! aOptions.m_sOld.equals(aOptions.m_sNew) ) + { + int nStart = rBuffer.indexOf(aOptions.m_sOld); + int nLength = aOptions.m_sNew.length(); + int nEnd = nStart+nLength; + while (nStart!=-1) + { + rBuffer.replace(nStart,nEnd,aOptions.m_sNew); + nStart = rBuffer.indexOf(aOptions.m_sOld,nEnd); + nEnd = nStart+nLength; + } + } + + // convert buffer into return format [string] + // and convert to lower or upper case if required. + String sResult = rBuffer.toString(); + if (aOptions.m_bCaseChange) + { + if (aOptions.m_bLower) + sResult = sResult.toLowerCase(); + else + sResult = sResult.toUpperCase(); + } + + return sResult; + } + + + + // interface XServiceInfo + /** + * This method returns an array of all supported service names. + * + * @return Array of supported service names. + */ + public String[] getSupportedServiceNames() + { + return m_serviceNames; + } + + /** + * This method returns true, if the given service will be + * supported by this component. + * + * @param sService + * the requested service name + * + * @return True, if the given service name will be supported; + * False otherwise. + */ + public boolean supportsService( String sService ) + { + return ( + sService.equals( m_serviceNames[0] ) || + sService.equals( m_serviceNames[1] ) || + sService.equals( m_serviceNames[2] ) + ); + } + + /** + * Return the real class name of the component + * + * @return Class name of the component. + */ + public String getImplementationName() + { + return _AsciiReplaceFilter.class.getName(); + } + + + } + // end of inner class, the wrapper class just has the two methods required for registering the component + + /** + * Gives a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * + * @param sImplName + * The implementation name of the component. + * + * @return Returns a <code>XSingleComponentFactory</code> for + * creating the component. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + + public static XSingleComponentFactory __getComponentFactory(String sImplName) + { + XSingleComponentFactory xFactory = null; + + if ( sImplName.equals( _AsciiReplaceFilter.class.getName() ) ) + xFactory = com.sun.star.lib.uno.helper.Factory.createComponentFactory(_AsciiReplaceFilter.class, + _AsciiReplaceFilter.m_serviceNames); + return xFactory; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/FilterOptions.java b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/FilterOptions.java new file mode 100644 index 000000000..18c45da85 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/FilterOptions.java @@ -0,0 +1,225 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +package FilterDevelopment.AsciiFilter; + +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.uno.UnoRuntime; + +/*-************************************************************************ + @title helper to analyze necessary option properties of our filter + @description Our filter needs some necessary properties for working: + - a stream for input or output + - or a URL for creating such streams + - information about required action on filtering + + @attention This class mustn't be threadsafe - because instances of it + are used temp. only - not as members. So no concurrent access + should occur. + Another reason: it would be very difficult to safe every + access on our internal member. To do so - we must implement + special methods instead of allowing pure member access. + ************************************************************************-*/ + +public class FilterOptions +{ + + // public member to provide these options to our outside filter class + public com.sun.star.io.XInputStream m_xInput ; + public com.sun.star.io.XOutputStream m_xOutput ; + public boolean m_bStreamOwner ; + private String m_sURL ; + public String m_sOld ; + public String m_sNew ; + public boolean m_bCaseChange ; + public boolean m_bLower ; + + + // private members for internal things + private final XMultiComponentFactory m_xMCF; + private final XComponentContext m_Ctx; + + + // interface + /** + * creates a new instance of this class + * It use the given MediaDescriptor to find right + * properties for initialization of the internal members. + * To do so it use another interface method analyze() + * which can be used after creation of an object instance + * to set a new descriptor here. + * + * @param xMCF + * we need it to create special help service top open + * streams in case they are not already a part of given + * MediaDescriptor + * + * @param bImport + * we must know which stream member should be valid initialized + * + * @param lDescriptor + * the initial MediaDescriptor to set internal member from it + */ + public FilterOptions( XMultiComponentFactory xMCF , + XComponentContext Context , + boolean bImport , + com.sun.star.beans.PropertyValue[] lDescriptor ) + { + m_xMCF = xMCF; + m_Ctx = Context; + analyze(bImport, lDescriptor); + } + + /** + * analyze given MediaDescriptor to find values for our internal member + * It reset all members to defaults before - to prevent us against + * mixed descriptor values! + * + * @param bImport + * we must know which stream member should be valid initialized + * + * @param lDescriptor + * the new MediaDescriptor to set internal member from it + */ + private void analyze( boolean bImport , + com.sun.star.beans.PropertyValue[] lDescriptor ) + { + m_xInput = null ; + m_xOutput = null ; + m_bStreamOwner = false ; + m_sURL = null ; + m_sOld = ""; + m_sNew = ""; + m_bCaseChange = false ; + m_bLower = false ; + + for ( int i=0; i<lDescriptor.length; ++i ) + { + try + { + if (lDescriptor[i].Name.equals("FileName")) + m_sURL = AnyConverter.toString(lDescriptor[i].Value); + else + if (lDescriptor[i].Name.equals("InputStream")) + m_xInput = (com.sun.star.io.XInputStream)AnyConverter.toObject(new com.sun.star.uno.Type(com.sun.star.io.XInputStream.class), lDescriptor[i].Value); + else + if (lDescriptor[i].Name.equals("OutputStream")) + m_xOutput = (com.sun.star.io.XOutputStream)AnyConverter.toObject(new com.sun.star.uno.Type(com.sun.star.io.XOutputStream.class), lDescriptor[i].Value); + else + if (lDescriptor[i].Name.equals("FilterData")) + { + com.sun.star.beans.PropertyValue[] lFilterProps = (com.sun.star.beans.PropertyValue[])AnyConverter.toArray(lDescriptor[i].Value); + int nCount = lFilterProps.length; + for (int p=0; p<nCount; ++p) + { + if (lFilterProps[p].Name.equals("OldString")) + m_sOld = AnyConverter.toString(lFilterProps[p].Value); + else + if (lFilterProps[p].Name.equals("NewString")) + m_sNew = AnyConverter.toString(lFilterProps[p].Value); + else + if (lFilterProps[p].Name.equals("LowerCase")) + { + m_bLower = AnyConverter.toBoolean(lFilterProps[p].Value); + m_bCaseChange = true; // Set it after m_bLower - because an exception can occur and we must use default values then! + } + } + } + } + catch(com.sun.star.lang.IllegalArgumentException exConvert) + { + // ONE argument has the wrong type + // But I think we mustn't react here - because we set + // default values for every necessary item we need. + // In case this exception occurs - this default exist + // and we can live with it. + } + } + + // Decide if it's necessary AND possible to open streams. + // Outside user can check for valid FilterOptions by using + // corresponding method isValid(). So it's not necessary to + // handle this error here in any case. + if (m_xInput==null && m_xOutput==null && m_sURL!=null) + impl_openStreams(bImport); + } + + /** + * with this method it's possible for the outside filter to decide + * if he can use this FilterOptions really or not. + * That means especially if necessary streams are available or not. + */ + public boolean isValid() + { + return(m_xInput!=null || m_xOutput!=null); + } + + + // helper + /** + * In case we couldn't found any valid stream inside the given MediaDescriptor, + * we must create it. Then we use a special helper service in combination + * with an existing URL to open a stream for reading or writing. It depends + * from given parameter bImport. + * + * Note: This method doesn't check for a valid URL. It must be done before. + * + * @param bImport + * indicates which stream member must be valid as result of this call + */ + private void impl_openStreams( boolean bImport ) + { + try{ + com.sun.star.ucb.XSimpleFileAccess xHelper = UnoRuntime.queryInterface( + com.sun.star.ucb.XSimpleFileAccess.class, + m_xMCF.createInstanceWithContext("com.sun.star.ucb.SimpleFileAccess", m_Ctx)); + if (xHelper!=null) + { + if (bImport) + m_xInput = xHelper.openFileRead(m_sURL); + else + m_xOutput = xHelper.openFileWrite(m_sURL); + } + + m_bStreamOwner = (m_xInput!=null || m_xOutput!=null); + } + catch(com.sun.star.ucb.CommandAbortedException exAborted) {} + catch(com.sun.star.uno.Exception exUno ) {} + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/Makefile b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/Makefile new file mode 100644 index 000000000..507f6cac4 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/Makefile @@ -0,0 +1,139 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevFilter example of the Developers Guide. + +PRJ=../../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +SAMPLE_NAME=OfficeDevAsciiFilterExample +SAMPLE_CLASS_OUT = $(OUT_CLASS)/$(SAMPLE_NAME) +SAMPLE_GEN_OUT = $(OUT_MISC)/$(SAMPLE_NAME) + +COMP_NAME=SampleFilter +COMP_CLASS_OUT=$(SAMPLE_CLASS_OUT)/$(COMP_NAME) +COMP_PACKAGE = $(OUT_BIN)/$(COMP_NAME).$(UNOOXT_EXT) +COMP_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP_NAME).$(UNOOXT_EXT)") +COMP_JAR_NAME = $(COMP_NAME).uno.jar +COMP_JAR = $(SAMPLE_CLASS_OUT)/$(COMP_JAR_NAME) +COMP_MANIFESTFILE = $(SAMPLE_GEN_OUT)/$(COMP_NAME).uno.Manifest +COMP_UNOPKG_MANIFEST = $(SAMPLE_GEN_OUT)/$(COMP_NAME)/META-INF/manifest.xml +COMP_REGISTERFLAG = $(SAMPLE_GEN_OUT)/devguide_$(COMP_NAME)_component.flag +COMP_COMPONENTS=$(COMP_NAME).components + +# often the java files are structured in a hierarchy similar to the package, +# for the example we know the package +PACKAGE = OfficeDev/samples/Filter + +COMP_JAVAFILES = \ + FilterOptions.java \ + AsciiReplaceFilter.java + +COMP_CLASSFILES = $(patsubst %.java,$(COMP_CLASS_OUT)/$(PACKAGE)/%.class,$(COMP_JAVAFILES)) + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(COMP_CLASS_OUT)) + + +# Targets +.PHONY: ALL +ALL : $(SAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(SAMPLE_GEN_OUT)/%.Manifest : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo RegistrationClassName: $(subst /,.,$(PACKAGE)).AsciiReplaceFilter> $@ + +$(COMP_CLASSFILES) : $(COMP_JAVAFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(COMP_CLASS_OUT) $(COMP_JAVAFILES) + +# rule for component jar file +$(COMP_JAR) : $(COMP_MANIFESTFILE) $(COMP_CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAR) cvfm $@ $< -C $(COMP_CLASS_OUT) . + +# rule for component package manifest +$(SAMPLE_GEN_OUT)/%/manifest.xml : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@ + @echo $(OSEP)!DOCTYPE manifest:manifest PUBLIC "$(QM)-//OpenOffice.org//DTD Manifest 1.0//EN$(QM)" "$(QM)Manifest.dtd$(QM)"$(CSEP) >> $@ + @echo $(OSEP)manifest:manifest xmlns:manifest="$(QM)http://openoffice.org/2001/manifest$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.configuration-data$(QM)" >> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)TypeDetection.xcu$(QM)"/$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.uno-components$(QM)">> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)$(COMP_COMPONENTS)$(QM)"/$(CSEP)>> $@ + @echo $(OSEP)/manifest:manifest$(CSEP) >> $@ + +# rule for component package file +$(COMP_PACKAGE) : $(COMP_JAR) TypeDetection.xcu $(COMP_UNOPKG_MANIFEST) $(COMP_COMPONENTS) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_ZIP) $@ TypeDetection.xcu + $(SDK_ZIP) -u $@ $(COMP_COMPONENTS) + cd $(subst /,$(PS),$(SAMPLE_CLASS_OUT)) && $(SDK_ZIP) -u ../../bin/$(@F) $(<F) + cd $(subst /,$(PS),$(SAMPLE_GEN_OUT)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xml + +$(COMP_REGISTERFLAG) : $(COMP_PACKAGE) +ifeq "$(SDK_AUTO_DEPLOYMENT)" "YES" + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(DEPLOYTOOL) $(COMP_PACKAGE_URL) + @echo flagged > $(subst /,$(PS),$@) +else + @echo -------------------------------------------------------------------------------- + @echo If you want to install your component automatically, please set the environment + @echo variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only + @echo possible if no office instance is running. + @echo -------------------------------------------------------------------------------- +endif + +$(SAMPLE_NAME) : $(COMP_REGISTERFLAG) + @echo -------------------------------------------------------------------------------- + @echo The "$(QM)$(COMP_NAME)$(QM)" Java component was installed if SDK_AUTO_DEPLOYMENT = YES. + @echo You can use the "$(QM)ASCII Replace$(QM)" filter in your office installation, see the + @echo example description. + @echo -------------------------------------------------------------------------------- + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(SAMPLE_CLASS_OUT)) + -$(DELRECURSIVE) $(subst /,$(PS),$(SAMPLE_GEN_OUT)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_PACKAGE_URL))) diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/SampleFilter.components b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/SampleFilter.components new file mode 100644 index 000000000..6b2545df9 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/SampleFilter.components @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<components xmlns="http://openoffice.org/2010/uno-components"> + <component loader="com.sun.star.loader.Java2" uri="SampleFilter.uno.jar"> + <implementation name="FilterDevelopment.AsciiFilter.AsciiReplaceFilter$_AsciiReplaceFilter"> + <service name="com.sun.star.comp.ansifilter.AsciiReplaceFilter"/> + <service name="com.sun.star.document.ImportFilter"/> + <service name="com.sun.star.document.ExportFilter"/> + </implementation> + </component> +</components> diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/TypeDetection.xcu b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/TypeDetection.xcu new file mode 100644 index 000000000..c2eb32ef2 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/AsciiFilter/TypeDetection.xcu @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . +--> +<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="TypeDetection" oor:package="org.openoffice.Office"> + <node oor:name="Types"> + <node oor:name="ascii" oor:op="replace"> + <prop oor:name="Data" oor:type="xs:string"> + <value>0,text/plain,,,txt,0</value> + </prop> + <prop oor:name="UIName" oor:type="xs:string"> + <value xml:lang="en-US">ASCII</value> + </prop> + </node> + </node> + <node oor:name="Filters"> + <node oor:name="Ascii_Replace" oor:op="replace"> + <prop oor:name="Data" oor:type="xs:string"> + <value>0,ascii,com.sun.star.text.TextDocument,com.sun.star.comp.ansifilter.AsciiReplaceFilter,268959747,,0,,</value> + </prop> + <prop oor:name="Installed" oor:type="xs:boolean"> + <value>true</value> + </prop> + <prop oor:name="UIName" oor:type="xs:string"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="en-US">ASCII Replace</value> + <value xml:lang="de">ASCII Konvertierung</value> + </prop> + </node> + </node> +</oor:component-data> diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/FlatXmlTypeDetection.xcu b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/FlatXmlTypeDetection.xcu new file mode 100644 index 000000000..2ac9a2440 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/FlatXmlTypeDetection.xcu @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . +--> +<!DOCTYPE oor:component-data SYSTEM "../../../../component-update.dtd"> +<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:package="org.openoffice.TypeDetection" oor:name="Types"> + <node oor:name="Types"> + <node oor:name="devguide_FlatXMLType_Cpp_calc" oor:op="replace"> + <prop oor:name="UIOrder"><value>0</value></prop> + <prop oor:name="DetectService"><value>devguide.officedev.samples.filter.FlatXmlDetect</value></prop> + <prop oor:name="URLPattern"/> + <prop oor:name="Extensions"><value>fods</value></prop> + <prop oor:name="MediaType"/> + <prop oor:name="Preferred"><value>false</value></prop> + <prop oor:name="PreferredFilter"><value>devguide_FlatXMLFilter_Cpp_calc</value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">DevGuide FlatXML Calc</value> + </prop> + <prop oor:name="ClipboardFormat"><value>doctype:office:document</value></prop> + </node> + <node oor:name="devguide_FlatXMLType_Cpp_draw" oor:op="replace"> + <prop oor:name="UIOrder"><value>0</value></prop> + <prop oor:name="DetectService"><value>devguide.officedev.samples.filter.FlatXmlDetect</value></prop> + <prop oor:name="URLPattern"/> + <prop oor:name="Extensions"><value>fodg</value></prop> + <prop oor:name="MediaType"/> + <prop oor:name="Preferred"><value>false</value></prop> + <prop oor:name="PreferredFilter"><value>devguide_FlatXMLFilter_Cpp_draw</value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">DevGuide FlatXML Draw</value> + </prop> + <prop oor:name="ClipboardFormat"><value>doctype:office:document</value></prop> + </node> + <node oor:name="devguide_FlatXMLType_Cpp_impress" oor:op="replace"> + <prop oor:name="UIOrder"><value>0</value></prop> + <prop oor:name="DetectService"><value>devguide.officedev.samples.filter.FlatXmlDetect</value></prop> + <prop oor:name="URLPattern"/> + <prop oor:name="Extensions"><value>fodp</value></prop> + <prop oor:name="MediaType"/> + <prop oor:name="Preferred"><value>false</value></prop> + <prop oor:name="PreferredFilter"><value>devguide_FlatXMLFilter_Cpp_impress</value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">DevGuide FlatXML Impress</value> + </prop> + <prop oor:name="ClipboardFormat"><value>doctype:office:document</value></prop> + </node> + <node oor:name="devguide_FlatXMLType_Cpp_writer" oor:op="replace"> + <prop oor:name="UIOrder"><value>0</value></prop> + <prop oor:name="DetectService"><value>devguide.officedev.samples.filter.FlatXmlDetect</value></prop> + <prop oor:name="URLPattern"/> + <prop oor:name="Extensions"><value>fodt</value></prop> + <prop oor:name="MediaType"/> + <prop oor:name="Preferred"><value>false</value></prop> + <prop oor:name="PreferredFilter"><value>devguide_FlatXMLFilter_Cpp_writer</value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">DevGuide FlatXML Writer</value> + </prop> + <prop oor:name="ClipboardFormat"><value>doctype:office:document</value></prop> + </node> + <node oor:name="devguide_FlatXMLType_Cpp_master" oor:op="replace"> + <prop oor:name="UIOrder"><value>0</value></prop> + <prop oor:name="DetectService"><value>devguide.officedev.samples.filter.FlatXmlDetect</value></prop> + <prop oor:name="URLPattern"/> + <prop oor:name="Extensions"><value>fodm</value></prop> + <prop oor:name="MediaType"/> + <prop oor:name="Preferred"><value>false</value></prop> + <prop oor:name="PreferredFilter"><value>devguide_FlatXMLFilter_Cpp_master</value></prop> + <prop oor:name="UIName"> + <value xml:lang="en-US">DevGuide FlatXML Master</value> + </prop> + <prop oor:name="ClipboardFormat"><value>doctype:office:document</value></prop> + </node> + </node> +</oor:component-data> diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/Makefile b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/Makefile new file mode 100644 index 000000000..2a9e24186 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/Makefile @@ -0,0 +1,155 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the filterdetection component for the FlatXmlFilter of the Developers Guide. + +PRJ=../../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +COMP_NAME=FlatXmlTypeDetection +COMP_IMPL_NAME=$(COMP_NAME).uno.$(SHAREDLIB_EXT) +OUT_COMP_INC = $(OUT_INC)/$(COMP_NAME) +OUT_COMP_GEN = $(OUT_MISC)/$(COMP_NAME) +OUT_COMP_SLO=$(OUT_SLO)/$(COMP_NAME) +COMP_RDB_NAME = $(COMP_NAME).uno.rdb +COMP_RDB = $(OUT_COMP_GEN)/$(COMP_RDB_NAME) +COMP_PACKAGE = $(OUT_BIN)/$(COMP_NAME).$(UNOOXT_EXT) +COMP_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP_NAME).$(UNOOXT_EXT)") +COMP_UNOPKG_MANIFEST = $(OUT_COMP_GEN)/$(COMP_NAME)/META-INF/manifest.xml +COMP_COMPONENTS = $(OUT_COMP_GEN)/$(COMP_NAME).components + +REGISTERFLAG = $(OUT_MISC)/devguide_$(COMP_NAME)_register_component.flag + +CXXFILES = filterdetect.cxx \ + fdcomp.cxx + +SLOFILES = $(patsubst %.cxx,$(OUT_COMP_SLO)/%.$(OBJ_EXT),$(CXXFILES)) + +# Targets +.PHONY: ALL +ALL : \ + XMLFilterDetect + +include $(SETTINGS)/stdtarget.mk + +$(OUT_COMP_SLO)/%.$(OBJ_EXT) : %.cxx $(SDKTYPEFLAG) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(CC) $(CC_FLAGS) $(CC_INCLUDES) -I$(OUT_COMP_INC) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $< + +ifeq "$(OS)" "WIN" +$(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)) + $(LINK) $(COMP_LINK_FLAGS) /OUT:$@ \ + /MAP:$(OUT_COMP_GEN)/$(subst $(SHAREDLIB_EXT),map,$(@F)) $(SLOFILES) \ + $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) msvcprt.lib $(LIBO_SDK_LDFLAGS_STDLIBS) + $(LINK_MANIFEST) +else +$(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(LINK) $(COMP_LINK_FLAGS) $(LINK_LIBS) -o $@ $(SLOFILES) \ + $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STC++LIB) +ifeq "$(OS)" "MACOSX" + $(INSTALL_NAME_URELIBS) $@ +endif +endif + +# rule for component package manifest +$(OUT_COMP_GEN)/%/manifest.xml : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@ + @echo $(OSEP)!DOCTYPE manifest:manifest PUBLIC "$(QM)-//OpenOffice.org//DTD Manifest 1.0//EN$(QM)" "$(QM)Manifest.dtd$(QM)"$(CSEP) >> $@ + @echo $(OSEP)manifest:manifest xmlns:manifest="$(QM)http://openoffice.org/2001/manifest$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.configuration-data$(QM)" >> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)FlatXmlTypeDetection.xcu$(QM)"/$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.uno-components;platform=$(UNOPKG_PLATFORM)$(QM)">> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)$(COMP_NAME).components$(QM)"/$(CSEP)>> $@ + @echo $(OSEP)/manifest:manifest$(CSEP) >> $@ + +$(COMP_COMPONENTS) : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@ + @echo $(OSEP)components xmlns="$(QM)http://openoffice.org/2010/uno-components$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)component loader="$(QM)com.sun.star.loader.SharedLibrary$(QM)" uri="$(QM)$(UNOPKG_PLATFORM)/$(COMP_IMPL_NAME)$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)implementation name="$(QM)devguide.officedev.samples.filter.FlatXmlDetect$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)service name="$(QM)com.sun.star.document.ExtendedTypeDetection$(QM)"/$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)/implementation$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)/component$(CSEP) >> $@ + @echo $(OSEP)/components$(CSEP) >> $@ + +# rule for component package file +$(COMP_PACKAGE) : $(SHAREDLIB_OUT)/$(COMP_IMPL_NAME) FlatXmlTypeDetection.xcu $(COMP_UNOPKG_MANIFEST) $(COMP_COMPONENTS) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)/$(UNOPKG_PLATFORM)) + $(COPY) $(subst /,$(PS),$<) $(subst /,$(PS),$(OUT_COMP_GEN)/$(UNOPKG_PLATFORM)) + $(SDK_ZIP) $@ FlatXmlTypeDetection.xcu + cd $(subst /,$(PS),$(OUT_COMP_GEN)) && $(SDK_ZIP) -u ../../bin/$(@F) $(COMP_NAME).components + cd $(subst /,$(PS),$(OUT_COMP_GEN)) && $(SDK_ZIP) -u ../../bin/$(@F) $(UNOPKG_PLATFORM)/$(<F) + cd $(subst /,$(PS),$(OUT_COMP_GEN)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xml + +$(REGISTERFLAG) : $(COMP_PACKAGE) +ifeq "$(SDK_AUTO_DEPLOYMENT)" "YES" + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(DEPLOYTOOL) $(COMP_PACKAGE_URL) + @echo flagged > $(subst /,$(PS),$@) +else + @echo -------------------------------------------------------------------------------- + @echo If you want to install your component automatically, please set the environment + @echo variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only + @echo possible if no office instance is running. + @echo -------------------------------------------------------------------------------- +endif + +XMLFilterDetect : $(REGISTERFLAG) + @echo -------------------------------------------------------------------------------- + @echo The FlatXMLFilterDetection component is installed if SDK_AUTO_DEPLOYMENT = YES. + @echo You will use this component implicitly in your office installation when you have + @echo installed a FlatXMLFilter component C++ or Java. + @echo -------------------------------------------------------------------------------- + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_INC)) + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_GEN)) + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_SLO)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_PACKAGE_URL))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_COMPONENTS)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(REGISTERFLAG))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(SHAREDLIB_OUT)/$(COMP_NAME).*)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/fdcomp.cxx b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/fdcomp.cxx new file mode 100644 index 000000000..37b7a9360 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/fdcomp.cxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +#include <stdio.h> + +#include <osl/mutex.hxx> +#include <osl/thread.h> +#include <uno/lbnames.h> +#include <cppuhelper/factory.hxx> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> + +#include "filterdetect.hxx" + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +extern "C" +{ +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + OUString implName = OUString::createFromAscii( pImplName ); + if ( pServiceManager && implName.equals(FilterDetect_getImplementationName()) ) + { + Reference< XSingleComponentFactory > xFactory( createSingleComponentFactory( + FilterDetect_createInstance, + OUString::createFromAscii( pImplName ), + FilterDetect_getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + return pRet; +} + +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + char const ** ppEnvTypeName, uno_Environment **) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/filterdetect.cxx b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/filterdetect.cxx new file mode 100644 index 000000000..f51e29941 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/filterdetect.cxx @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +#include "filterdetect.hxx" +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/XImportFilter.hpp> +#include <com/sun/star/xml/XExportFilter.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/task/XStatusIndicator.hpp> +#include <com/sun/star/task/XStatusIndicatorFactory.hpp> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/style/XStyleLoader.hpp> +#include <com/sun/star/document/XExtendedFilterDetection.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/ucb/SimpleFileAccess.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <cppuhelper/supportsservice.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::document; +using namespace com::sun::star::lang; +using namespace com::sun::star::io; +using namespace com::sun::star::beans; +using namespace com::sun::star::xml::sax; +using namespace com::sun::star::xml; +using namespace com::sun::star::task; +using namespace com::sun::star::frame; +using namespace com::sun::star::container; +using namespace com::sun::star::ucb; + +using ::rtl::OUString; +using ::rtl::OString; + + +OUString SAL_CALL FilterDetect::detect(Sequence< PropertyValue >& aArguments ) +{ + // type name to return + OUString sOriginalTypeName; + OUString sTypeName; + OUString sURL; + // stream of the document to be detected + Reference< XInputStream > xInStream; + for ( sal_Int32 i = 0 ; i < aArguments.getLength(); i++) + { + OUString aName = aArguments[i].Name; + if ( aName == "TypeName" ) + aArguments[i].Value >>= sOriginalTypeName; + if ( aName == "URL" ) + aArguments[i].Value >>= sURL; + if ( aName == "InputStream" ) + aArguments[i].Value >>= xInStream; + } + + if (!xInStream.is()) + { + // open the stream if it was not supplied by the framework + Reference< XSimpleFileAccess3 > xSFI(SimpleFileAccess::create(mxContext)); + if (sURL.getLength() > 0) + { + try + { + xInStream = xSFI->openFileRead( sURL); + } + catch( Exception& ) + { + return sTypeName; + } + } else { + // failed to access UCB + return sTypeName; + } + } + + // flatxml starts with an office:document element. this element + // contains a class="..." attribute by which we can deduct the + // type of document that is to be loaded + + // WARNING: + // parsing the plain text of the document is an easy way to do this + // but not the purest solution, since namespaces and other xml details + // may lead to another syntactic expression of the same document. + // this example works for the way the office serializes its XML stream + // but might need extension for other data sources... + static OString aDocToken("office:document"); + // static OString aClassToken("office:class=\""); + static OString aMimeTypeToken("office:mimetype=\""); + + sal_Int32 nHeadSize = 4096; + Sequence< sal_Int8 > aHeadData(nHeadSize); + + // rewind seekable stream + Reference< XSeekable > xSeek(xInStream, UNO_QUERY); + if (xSeek.is()) + xSeek->seek(0); + + long bytestRead = xInStream->readBytes(aHeadData, nHeadSize); + + OString aHead = OString((const char *)aHeadData.getConstArray(), bytestRead).toAsciiLowerCase(); + + // check for document element of flatxml format + if (aHead.indexOf(aDocToken) >= 0) + { + // read document class + sal_Int32 n = aHead.indexOf(aMimeTypeToken); + if (n >= 0) + { + n += aMimeTypeToken.getLength(); + OString aMimeType = aHead.copy(n, aHead.indexOf('\"', n) - n); + // return type for class found + if (aMimeType.equals("application/x-vnd.oasis.opendocument.text") || + aMimeType.equals("application/vnd.oasis.opendocument.text")) + sTypeName = "devguide_FlatXMLType_Cpp_writer"; + else if (aMimeType.equals("application/x-vnd.oasis.opendocument.text-master") || + aMimeType.equals("application/vnd.oasis.opendocument.text-master")) + sTypeName = "devguide_FlatXMLType_Cpp_master"; + else if (aMimeType.equals("application/x-vnd.oasis.openoffice.text-global") || + aMimeType.equals("application/vnd.oasis.openoffice.text-global")) + sTypeName = "devguide_FlatXMLType_Cpp_master"; + else if (aMimeType.equals("application/x-vnd.oasis.opendocument.spreadsheet") || + aMimeType.equals("application/vnd.oasis.opendocument.spreadsheet")) + sTypeName = "devguide_FlatXMLType_Cpp_calc"; + else if (aMimeType.equals("application/x-vnd.oasis.opendocument.drawing") || + aMimeType.equals("application/vnd.oasis.opendocument.drawing")) + sTypeName = "devguide_FlatXMLType_Cpp_draw"; + else if (aMimeType.equals("application/x-vnd.oasis.opendocument.presentation") || + aMimeType.equals("application/vnd.oasis.opendocument.presentation")) + sTypeName = "devguide_FlatXMLType_Cpp_impress"; + } + } + return sTypeName; +} + + +// XInitialization +void SAL_CALL FilterDetect::initialize( const Sequence< Any >& aArguments ) +{ + Sequence < PropertyValue > aAnySeq; + sal_Int32 nLength = aArguments.getLength(); + if ( nLength && ( aArguments[0] >>= aAnySeq ) ) + { + const PropertyValue * pValue = aAnySeq.getConstArray(); + nLength = aAnySeq.getLength(); + for ( sal_Int32 i = 0 ; i < nLength; i++) + { + if ( pValue[i].Name == "Type" ) + { + pValue[i].Value >>= msFilterName; + } + else if ( pValue[i].Name == "UserData" ) + { + pValue[i].Value >>= msUserData; + } + else if ( pValue[i].Name == "TemplateName" ) + { + pValue[i].Value>>=msTemplateName; + } + } + } +} + +OUString FilterDetect_getImplementationName () +{ + return OUString( "devguide.officedev.samples.filter.FlatXmlDetect" ); +} + +#define SERVICE_NAME1 "com.sun.star.document.ExtendedTypeDetection" + +Sequence< OUString > SAL_CALL FilterDetect_getSupportedServiceNames( ) +{ + Sequence < OUString > aRet(2); + OUString* pArray = aRet.getArray(); + pArray[0] = OUString ( SERVICE_NAME1 ); + return aRet; +} +#undef SERVICE_NAME1 +#undef SERVICE_NAME2 + +Reference< XInterface > SAL_CALL FilterDetect_createInstance( const Reference< XComponentContext > & rContext) +{ + return (cppu::OWeakObject*) new FilterDetect( rContext ); +} + +// XServiceInfo +OUString SAL_CALL FilterDetect::getImplementationName( ) +{ + return FilterDetect_getImplementationName(); +} + +sal_Bool SAL_CALL FilterDetect::supportsService( const OUString& rServiceName ) +{ + return cppu::supportsService(this, rServiceName); +} + +Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames( ) +{ + return FilterDetect_getSupportedServiceNames(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/filterdetect.hxx b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/filterdetect.hxx new file mode 100644 index 000000000..cf17157e7 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilterDetection/filterdetect.hxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +#ifndef INCLUDED_EXAMPLES_OFFICEDEV_FILTERDEVELOPMENT_FLATXMLFILTERDETECTION_FILTERDETECT_HXX +#define INCLUDED_EXAMPLES_OFFICEDEV_FILTERDEVELOPMENT_FLATXMLFILTERDETECTION_FILTERDETECT_HXX + + +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/document/XExtendedFilterDetection.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase5.hxx> + +#include <cppuhelper/implbase3.hxx> + +namespace com { namespace sun { namespace star { namespace uno { + class XComponentContext; +} } } } + +enum FilterType +{ + FILTER_IMPORT, + FILTER_EXPORT +}; + +/* This component will be instantiated for both import or export. Whether it calls + * setSourceDocument or setTargetDocument determines which Impl function the filter + * member calls */ +class FilterDetect : public cppu::WeakImplHelper3 <com::sun::star::document::XExtendedFilterDetection, + com::sun::star::lang::XInitialization, + com::sun::star::lang::XServiceInfo> +{ +protected: + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxContext; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mxDoc; + ::rtl::OUString msFilterName; + ::com::sun::star::uno::Sequence< ::rtl::OUString > msUserData; + ::rtl::OUString msTemplateName; + + sal_Bool SAL_CALL exportImpl( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ); + + sal_Bool SAL_CALL importImpl( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ); + +public: + FilterDetect( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &rxContext) + : mxContext( rxContext ) {} + + virtual ~FilterDetect() {} + + //XExtendedFilterDetection + virtual ::rtl::OUString SAL_CALL detect( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& lDescriptor ); + + // XInitialization + + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ); +}; + + +::rtl::OUString FilterDetect_getImplementationName(); + +sal_Bool SAL_CALL FilterDetect_supportsService( const ::rtl::OUString& ServiceName ); + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL FilterDetect_getSupportedServiceNames( ); + +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > +SAL_CALL FilterDetect_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & rContext); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/FlatXml.cxx b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/FlatXml.cxx new file mode 100644 index 000000000..8b53c0ad7 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/FlatXml.cxx @@ -0,0 +1,331 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/implbase3.hxx> +#include <osl/diagnose.h> +#include <uno/lbnames.h> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <com/sun/star/xml/XImportFilter.hpp> +#include <com/sun/star/xml/XExportFilter.hpp> + +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XSeekable.hpp> + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::osl; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::xml; +using namespace ::com::sun::star::xml::sax; + +namespace XFlatXml { + +class XFlatXml : public WeakImplHelper3< XImportFilter, XExportFilter, XDocumentHandler> +{ +private: + // the UNO ServiceFactory + Reference< XMultiServiceFactory > m_rServiceFactory; + + // DocumentHandler interface of the css::xml::sax::Writer service + Reference < XExtendedDocumentHandler > m_rDocumentHandler; + + // controls pretty-printing + sal_Bool m_bPrettyPrint; + +public: + + // ctor... + XFlatXml( const Reference< XMultiServiceFactory > &r ) + : m_rServiceFactory(r) + , m_bPrettyPrint(sal_True) + {} + + // XImportFilter + virtual sal_Bool SAL_CALL importer( + const Sequence<PropertyValue>& aSourceData, + const Reference<XDocumentHandler>& xHandler, + const Sequence<OUString>& msUserData); + + // XExportFilter + virtual sal_Bool SAL_CALL exporter( + const Sequence<PropertyValue>& aSourceData, + const Sequence<OUString>& msUserData); + + // XDocumentHandler + virtual void SAL_CALL startDocument(); + virtual void SAL_CALL endDocument(); + virtual void SAL_CALL startElement(const OUString& str, const Reference<XAttributeList>& attriblist); + virtual void SAL_CALL endElement(const OUString& str); + virtual void SAL_CALL characters(const OUString& str); + virtual void SAL_CALL ignorableWhitespace(const OUString& str); + virtual void SAL_CALL processingInstruction(const OUString& str, const OUString& str2); + virtual void SAL_CALL setDocumentLocator(const Reference<XLocator>& doclocator); +}; + +sal_Bool XFlatXml::importer( + const Sequence<PropertyValue>& aSourceData, + const Reference<XDocumentHandler>& xHandler, + const Sequence<OUString>& msUserData) +{ + // get information from media descriptor + // the input stream that represents the imported file + // is most important here since we need to supply it to + // the sax parser that drives the supplied document handler + sal_Int32 nLength = aSourceData.getLength(); + OUString aName, aFileName, aURL; + Reference< XInputStream > xInputStream; + for ( sal_Int32 i = 0 ; i < nLength; i++) + { + aName = aSourceData[i].Name; + if ( aName == "InputStream" ) + aSourceData[i].Value >>= xInputStream; + else if ( aName == "FileName" ) + aSourceData[i].Value >>= aFileName; + else if ( aName == "URL" ) + aSourceData[i].Value >>= aURL; + } + + // we need an input stream + OSL_ASSERT(xInputStream.is()); + if (!xInputStream.is()) return sal_False; + + // rewind seekable stream + Reference< XSeekable > xSeek(xInputStream, UNO_QUERY); + if (xSeek.is()) + xSeek->seek(0); + + + // create SAX parser that will read the document file + // and provide events to xHandler passed to this call + Reference < XParser > xSaxParser( m_rServiceFactory->createInstance( + "com.sun.star.xml.sax.Parser"), UNO_QUERY ); + OSL_ASSERT(xSaxParser.is()); + if(!xSaxParser.is())return sal_False; + + // let the parser try to send the sax event to the document handler + try + { + InputSource aInput; + aInput.sSystemId = aURL; + aInput.sPublicId = aURL; + aInput.aInputStream = xInputStream; + xSaxParser->setDocumentHandler(xHandler); + xSaxParser->parseStream(aInput); + } + catch( Exception &exc) + { + // something went wrong + OSL_FAIL(rtl::OUStringToOString(exc.Message,RTL_TEXTENCODING_UTF8).getStr()); + return sal_False; + } + + // done + return sal_True; +} + +sal_Bool XFlatXml::exporter( + const Sequence<PropertyValue>& aSourceData, + const Sequence<OUString>& msUserData) +{ + + // read source data + // we are especially interested in the output stream + // since that is where our xml-writer will push the data + // from its data-source interface + OUString aName, sURL; + Reference<XOutputStream> rOutputStream; + sal_Int32 nLength = aSourceData.getLength(); + for ( sal_Int32 i = 0 ; i < nLength; i++) + { + aName = aSourceData[i].Name; + if ( aName == "OutputStream" ) + aSourceData[i].Value >>= rOutputStream; + else if ( aName == "URL" ) + aSourceData[i].Value >>= sURL; + } + + if (!m_rDocumentHandler.is()) { + // get the document writer + m_rDocumentHandler = Reference<XExtendedDocumentHandler>( + m_rServiceFactory->createInstance("com.sun.star.xml.sax.Writer"), + UNO_QUERY); + OSL_ASSERT(m_rDocumentHandler.is()); + if (!m_rDocumentHandler.is()) return sal_False; + } + // get data source interface ... + Reference< XActiveDataSource > rDataSource(m_rDocumentHandler, UNO_QUERY); + OSL_ASSERT(rDataSource.is()); + if (!rDataSource.is()) return sal_False; + OSL_ASSERT(rOutputStream.is()); + if (!rOutputStream.is()) return sal_False; + // ... and set output stream + rDataSource->setOutputStream(rOutputStream); + + return sal_True; +} + +// for the DocumentHandler implementation, we just proxy the +// events to the XML writer that we created upon the output stream +// that was provided by the XMLFilterAdapter +void XFlatXml::startDocument(){ + OSL_ASSERT(m_rDocumentHandler.is()); + m_rDocumentHandler->startDocument(); +} + +void XFlatXml::endDocument(){ + OSL_ASSERT(m_rDocumentHandler.is()); + m_rDocumentHandler->endDocument(); +} + +void XFlatXml::startElement(const OUString& str, const Reference<XAttributeList>& attriblist) +{ + OSL_ASSERT(m_rDocumentHandler.is()); + m_rDocumentHandler->startElement(str, attriblist); +} + +void XFlatXml::endElement(const OUString& str) +{ + OSL_ASSERT(m_rDocumentHandler.is()); + m_rDocumentHandler->endElement(str); +} + +void XFlatXml::characters(const OUString& str) +{ + OSL_ASSERT(m_rDocumentHandler.is()); + m_rDocumentHandler->characters(str); +} + +void XFlatXml::ignorableWhitespace(const OUString& str) +{ + OSL_ASSERT(m_rDocumentHandler.is()); + if (!m_bPrettyPrint) return; + m_rDocumentHandler->ignorableWhitespace(str); +} + +void XFlatXml::processingInstruction(const OUString& str, const OUString& str2) +{ + OSL_ASSERT(m_rDocumentHandler.is()); + m_rDocumentHandler->processingInstruction(str, str2); +} + +void XFlatXml::setDocumentLocator(const Reference<XLocator>& doclocator) +{ + OSL_ASSERT(m_rDocumentHandler.is()); + m_rDocumentHandler->setDocumentLocator(doclocator); +} + + +// Component management + +Reference< XInterface > SAL_CALL CreateInstance( const Reference< XMultiServiceFactory > &r) +{ + return Reference< XInterface >(( OWeakObject *)new XFlatXml(r)); +} + +Sequence< OUString > getSupportedServiceNames() +{ + static Sequence < OUString > *pNames = 0; + if( ! pNames ) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if( !pNames ) + { + static Sequence< OUString > seqNames(1); + seqNames.getArray()[0] = OUString( + "devguide.officedev.samples.filter.FlatXmlCpp"); + pNames = &seqNames; + } + } + return *pNames; +} + +} + +using namespace XFlatXml; +#define IMPLEMENTATION_NAME "devguide.officedev.samples.filter.FlatXmlCpp" + + +extern "C" +{ +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( + const char * pImplName, void * pServiceManager, void * pRegistryKey ) +{ + void * pRet = 0; + + if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0) + { + Reference< XSingleServiceFactory > xFactory( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + CreateInstance, getSupportedServiceNames() ) ); + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + return pRet; +} + +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( + char const ** ppEnvTypeName, uno_Environment **) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +} // extern "C" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/FlatXmlFilter_cpp.xcu b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/FlatXmlFilter_cpp.xcu new file mode 100644 index 000000000..7113a16e1 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/FlatXmlFilter_cpp.xcu @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . +--> +<!DOCTYPE oor:component-data SYSTEM "../../../../component-update.dtd"> +<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:package="org.openoffice.TypeDetection" oor:name="Filter"> + <node oor:name="Filters"> + <node oor:name="devguide_FlatXMLFilter_Cpp_calc" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_calc</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.sheet.SpreadsheetDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlCpp, ,com.sun.star.comp.Calc.XMLOasisImporter,com.sun.star.comp.Calc.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Calc</value> + <value xml:lang="en-US">DevGuide FlatXML Calc</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Cpp_draw" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_draw</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlCpp, ,com.sun.star.comp.DrawingLayer.XMLOasisImporter,com.sun.star.comp.DrawingLayer.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Draw</value> + <value xml:lang="en-US">DevGuide FlatXML Draw</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Cpp_impress" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_impress</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.presentation.PresentationDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlCpp, ,com.sun.star.comp.Impress.XMLOasisImporter,com.sun.star.comp.Impress.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Impress</value> + <value xml:lang="en-US">DevGuide FlatXML Impress</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Cpp_writer" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_writer</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlCpp, ,com.sun.star.comp.Writer.XMLOasisImporter,com.sun.star.comp.Writer.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Writer</value> + <value xml:lang="en-US">DevGuide FlatXML Writer</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Cpp_master" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_master</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.text.GlobalDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlCpp, ,com.sun.star.comp.Writer.XMLOasisImporter,com.sun.star.comp.Writer.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Master</value> + <value xml:lang="en-US">DevGuide FlatXML Master</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + </node> +</oor:component-data> diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/Makefile b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/Makefile new file mode 100644 index 000000000..73e4b7e2a --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_cpp/Makefile @@ -0,0 +1,153 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the C++ FlatXmlFilter component example of the Developers Guide. + +PRJ=../../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +COMP_NAME=FlatXmlFilter_cpp +COMP_IMPL_NAME=$(COMP_NAME).uno.$(SHAREDLIB_EXT) +OUT_COMP_INC = $(OUT_INC)/$(COMP_NAME) +OUT_COMP_GEN = $(OUT_MISC)/$(COMP_NAME) +OUT_COMP_SLO=$(OUT_SLO)/$(COMP_NAME) +COMP_PACKAGE = $(OUT_BIN)/$(COMP_NAME).$(UNOOXT_EXT) +COMP_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP_NAME).$(UNOOXT_EXT)") +COMP_UNOPKG_MANIFEST = $(OUT_COMP_GEN)/$(COMP_NAME)/META-INF/manifest.xml +COMP_COMPONENTS = $(OUT_COMP_GEN)/$(COMP_NAME).components + +COMP_REGISTERFLAG = $(OUT_MISC)/devguide_$(COMP_NAME)_register_component.flag + +CXXFILES = FlatXml.cxx + +SLOFILES = $(patsubst %.cxx,$(OUT_COMP_SLO)/%.$(OBJ_EXT),$(CXXFILES)) + +# Targets +.PHONY: ALL +ALL : \ + FlatXmlFilterCppExample + +include $(SETTINGS)/stdtarget.mk + +$(OUT_COMP_SLO)/%.$(OBJ_EXT) : %.cxx $(SDKTYPEFLAG) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(CC) $(CC_FLAGS) $(CC_INCLUDES) -I$(OUT_COMP_INC) $(CC_DEFINES) $(CC_OUTPUT_SWITCH)$(subst /,$(PS),$@) $< + +ifeq "$(OS)" "WIN" +$(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)) + $(LINK) $(COMP_LINK_FLAGS) /OUT:$@ \ + /MAP:$(OUT_COMP_GEN)/$(subst $(SHAREDLIB_EXT),map,$(@F)) $(SLOFILES) \ + $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) msvcprt.lib $(LIBO_SDK_LDFLAGS_STDLIBS) + $(LINK_MANIFEST) +else +$(SHAREDLIB_OUT)/%.$(SHAREDLIB_EXT) : $(SLOFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(LINK) $(COMP_LINK_FLAGS) $(LINK_LIBS) -o $@ $(SLOFILES) \ + $(CPPUHELPERLIB) $(CPPULIB) $(SALLIB) $(STC++LIB) +ifeq "$(OS)" "MACOSX" + $(INSTALL_NAME_URELIBS) $@ +endif +endif + +# rule for component package manifest +$(OUT_COMP_GEN)/%/manifest.xml : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@ + @echo $(OSEP)!DOCTYPE manifest:manifest PUBLIC "$(QM)-//OpenOffice.org//DTD Manifest 1.0//EN$(QM)" "$(QM)Manifest.dtd$(QM)"$(CSEP) >> $@ + @echo $(OSEP)manifest:manifest xmlns:manifest="$(QM)http://openoffice.org/2001/manifest$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.configuration-data$(QM)" >> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)FlatXmlFilter_cpp.xcu$(QM)"/$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.uno-components;platform=$(UNOPKG_PLATFORM)$(QM)">> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)$(COMP_NAME).components$(QM)"/$(CSEP)>> $@ + @echo $(OSEP)/manifest:manifest$(CSEP) >> $@ + +$(COMP_COMPONENTS) : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@ + @echo $(OSEP)components xmlns="$(QM)http://openoffice.org/2010/uno-components$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)component loader="$(QM)com.sun.star.loader.SharedLibrary$(QM)" uri="$(QM)$(UNOPKG_PLATFORM)/$(COMP_IMPL_NAME)$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)implementation name="$(QM)devguide.officedev.samples.filter.FlatXmlCpp$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)service name="$(QM)devguide.officedev.samples.filter.FlatXmlCpp$(QM)"/$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)/implementation$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)/component$(CSEP) >> $@ + @echo $(OSEP)/components$(CSEP) >> $@ + +# rule for component package file +$(COMP_PACKAGE) : $(SHAREDLIB_OUT)/$(COMP_IMPL_NAME) FlatXmlFilter_cpp.xcu $(COMP_UNOPKG_MANIFEST) $(COMP_COMPONENTS) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + -$(MKDIR) $(subst /,$(PS),$(OUT_COMP_GEN)/$(UNOPKG_PLATFORM)) + $(COPY) $(subst /,$(PS),$<) $(subst /,$(PS),$(OUT_COMP_GEN)/$(UNOPKG_PLATFORM)) + $(SDK_ZIP) $@ FlatXmlFilter_cpp.xcu + cd $(subst /,$(PS),$(OUT_COMP_GEN)) && $(SDK_ZIP) -u ../../bin/$(@F) $(COMP_NAME).components + cd $(subst /,$(PS),$(OUT_COMP_GEN)) && $(SDK_ZIP) -u ../../bin/$(@F) $(UNOPKG_PLATFORM)/$(<F) + cd $(subst /,$(PS),$(OUT_COMP_GEN)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xml + +$(COMP_REGISTERFLAG) : $(COMP_PACKAGE) +ifeq "$(SDK_AUTO_DEPLOYMENT)" "YES" + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(DEPLOYTOOL) $(COMP_PACKAGE_URL) + @echo flagged > $(subst /,$(PS),$@) +else + @echo -------------------------------------------------------------------------------- + @echo If you want to install your component automatically, please set the environment + @echo variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only + @echo possible if no office instance is running. + @echo -------------------------------------------------------------------------------- +endif + +FlatXmlFilterCppExample : $(COMP_REGISTERFLAG) + @echo -------------------------------------------------------------------------------- + @echo The C++ FlatXmlFilter component is installed if SDK_AUTO_DEPLOYMENT = YES. + @echo You can use the filters "$(QM)DevGuide FlatXML ...$(QM)" inside your office installation + @echo after you have installed the "$(QM)FlatXmlTypeDetection.uno.pkg"$(QM) as well. + @echo -------------------------------------------------------------------------------- + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_INC)) + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_GEN)) + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_SLO)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_PACKAGE_URL))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_COMPONENTS))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_REGISTERFLAG))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_TYPEFLAG))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(SHAREDLIB_OUT)/$(COMP_NAME).*)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXml.java b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXml.java new file mode 100644 index 000000000..6ba341977 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXml.java @@ -0,0 +1,267 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.uno.*; +import com.sun.star.lang.*; +import com.sun.star.beans.*; + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.registry.XRegistryKey; + +import com.sun.star.xml.*; +import com.sun.star.xml.sax.*; + +import com.sun.star.io.XInputStream; +import com.sun.star.io.XOutputStream; +import com.sun.star.io.XActiveDataSource; + + + +public class FlatXml implements XImportFilter, XExportFilter, XServiceName, + XServiceInfo, XDocumentHandler, XTypeProvider +{ + + /* + * private data members + */ + private final XMultiServiceFactory m_xServiceFactory; + private XExtendedDocumentHandler m_xHandler; + private static final boolean m_bPrettyPrint = true; + + private static final String __serviceName = "devguide.officedev.samples.filter.FlatXmlJava"; + private static final String __implName = "FlatXml"; + private static final String[] __supportedServiceNames = { + "devguide.officedev.samples.filter.FlatXmlJava" + }; + + public FlatXml(XMultiServiceFactory f) { + m_xServiceFactory = f; + } + + // --- XTypeProvider --- + public byte[] getImplementationId() { + return new byte[0]; + } + + // --- XServiceName --- + public String getServiceName() { + return __serviceName; + } + + // --- XServiceInfo --- + public boolean supportsService(String sName) { + for (int i = 0; i < __supportedServiceNames.length; i++) { + if (__supportedServiceNames[i].equals(sName)) return true; + } + return false; + } + public String getImplementationName() { + return this.getClass().getName(); + } + public String[] getSupportedServiceNames() { + return __supportedServiceNames; + } + + public com.sun.star.uno.Type[] getTypes() { + Type[] typeReturn = {}; + try { + typeReturn = new Type[] { + new Type( XTypeProvider.class ), + new Type( XExportFilter.class ), + new Type( XImportFilter.class ), + new Type( XServiceName.class ), + new Type( XServiceInfo.class ) + }; + } catch( java.lang.Exception exception ) { + return null; + } + return typeReturn; + } + + public boolean importer(PropertyValue[] aSourceData, XDocumentHandler xDocHandler, String[] msUserData) + throws com.sun.star.uno.RuntimeException, com.sun.star.lang.IllegalArgumentException + { + String sName = null; + String sFileName = null; + String sURL = null; + com.sun.star.io.XInputStream xin = null; + + try { + + for (int i = 0 ; i < aSourceData.length; i++) + { + sName = aSourceData[i].Name; + if (sName.equals("InputStream")) + xin = (XInputStream)AnyConverter.toObject(XInputStream.class, aSourceData[i].Value); + if (sName.equals("URL")) + sURL=(String)AnyConverter.toObject(String.class, aSourceData[i].Value); + if (sName.equals("FileName")) + sFileName=(String)AnyConverter.toObject(String.class, aSourceData[i].Value); + } + + Object tmpObj=m_xServiceFactory.createInstance("com.sun.star.xml.sax.Parser"); + if (tmpObj == null) return false; + + XParser xParser = UnoRuntime.queryInterface(XParser.class , tmpObj); + if (xParser == null) return false; + + InputSource aInput = new InputSource(); + aInput.sSystemId = sURL; + aInput.aInputStream =xin; + xParser.setDocumentHandler ( xDocHandler ); + xParser.parseStream ( aInput ); + } catch (com.sun.star.uno.Exception e){ + e.printStackTrace(); + return false; + } + + // done... + return true; + } + + public boolean exporter(PropertyValue[] aSourceData, String[] msUserData) + throws com.sun.star.uno.RuntimeException, com.sun.star.lang.IllegalArgumentException + { + try { + String sURL = null; + String sName = null; + XOutputStream xos = null; + + // get interesting values from sourceData + for (int i = 0 ; i < aSourceData.length; i++) + { + sName = aSourceData[i].Name; + if (sName.equals("OutputStream")) + xos = (XOutputStream)AnyConverter.toObject(XOutputStream.class, aSourceData[i].Value); + if (sName.equals("URL")) + sURL=(String)AnyConverter.toObject(String.class, aSourceData[i].Value); + } + + // prepare the XML writer + Object tmpObj = null; + if (m_xHandler == null) + { + tmpObj = m_xServiceFactory.createInstance("com.sun.star.xml.sax.Writer"); + if (tmpObj != null) + m_xHandler = UnoRuntime.queryInterface(XExtendedDocumentHandler.class, tmpObj); + } + if (m_xHandler == null) + return false; + + // Connect the provided output stream to the writer + XActiveDataSource xADSource = UnoRuntime.queryInterface( + XActiveDataSource.class, m_xHandler); + + if (xADSource != null && xos != null) + xADSource.setOutputStream(xos); + else + return false; + } catch (com.sun.star.uno.Exception e){ + return false; + } + + // done ... + return true; + } + + public void startDocument () + throws com.sun.star.xml.sax.SAXException + { + m_xHandler.startDocument(); + } + + public void endDocument() + throws com.sun.star.xml.sax.SAXException + { + m_xHandler.endDocument(); + } + + public void startElement (String str, com.sun.star.xml.sax.XAttributeList xattribs) + throws com.sun.star.xml.sax.SAXException + { + m_xHandler.startElement(str, xattribs); + } + + public void endElement(String str) + throws com.sun.star.xml.sax.SAXException + { + m_xHandler.endElement(str); + } + + public void characters(String str) + throws com.sun.star.xml.sax.SAXException + { + m_xHandler.characters(str); + } + + public void ignorableWhitespace(String str) + throws com.sun.star.xml.sax.SAXException + { + if (!m_bPrettyPrint) return; + else m_xHandler.ignorableWhitespace(str); + } + + public void processingInstruction(String aTarget, String aData) + throws com.sun.star.xml.sax.SAXException + { + m_xHandler.processingInstruction(aTarget, aData); + } + + public void setDocumentLocator(XLocator xLocator) + throws com.sun.star.xml.sax.SAXException + { + m_xHandler.setDocumentLocator(xLocator); + } + + + // component management + + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, XRegistryKey regKey) + { + XSingleServiceFactory xSingleServiceFactory = null; + if (implName.equals(__implName) ) { + try { + xSingleServiceFactory = FactoryHelper.getServiceFactory( + Class.forName(implName), __serviceName, multiFactory, regKey); + } catch (java.lang.ClassNotFoundException e) { + return null; + } + } + return xSingleServiceFactory; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXmlFilter_java.components b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXmlFilter_java.components new file mode 100644 index 000000000..87359c3ec --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXmlFilter_java.components @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<components xmlns="http://openoffice.org/2010/uno-components"> + <component loader="com.sun.star.loader.Java2" uri="FlatXmlFilter_java.uno.jar"> + <implementation name="FlatXml"> + <service name="devguide.officedev.samples.filter.FlatXmlJava"/> + </implementation> + </component> +</components> diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXmlFilter_java.xcu b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXmlFilter_java.xcu new file mode 100644 index 000000000..8bb6e2350 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/FlatXmlFilter_java.xcu @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . +--> +<!DOCTYPE oor:component-data SYSTEM "../../../../component-update.dtd"> +<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:package="org.openoffice.TypeDetection" oor:name="Filter"> + <node oor:name="Filters"> + <node oor:name="devguide_FlatXMLFilter_Java_calc" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_calc</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.sheet.SpreadsheetDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlJava, ,com.sun.star.comp.Calc.XMLOasisImporter,com.sun.star.comp.Calc.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Calc</value> + <value xml:lang="en-US">DevGuide FlatXML Calc</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Java_draw" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_draw</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlJava, ,com.sun.star.comp.DrawingLayer.XMLOasisImporter,com.sun.star.comp.DrawingLayer.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Draw</value> + <value xml:lang="en-US">DevGuide FlatXML Draw</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Java_impress" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_impress</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.presentation.PresentationDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlJava, ,com.sun.star.comp.Impress.XMLOasisImporter,com.sun.star.comp.Impress.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Impress</value> + <value xml:lang="en-US">DevGuide FlatXML Impress</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Java_writer" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_writer</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlJava, ,com.sun.star.comp.Writer.XMLOasisImporter,com.sun.star.comp.Writer.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Writer</value> + <value xml:lang="en-US">DevGuide FlatXML Writer</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + <node oor:name="devguide_FlatXMLFilter_Java_master" oor:op="replace"> + <prop oor:name="FileFormatVersion"><value>0</value></prop> + <prop oor:name="Type"><value>devguide_FlatXMLType_Cpp_master</value></prop> + <prop oor:name="DocumentService"><value>com.sun.star.text.GlobalDocument</value></prop> + <prop oor:name="UIComponent"/> + <prop oor:name="UserData"><value oor:separator=",">devguide.officedev.samples.filter.FlatXmlJava, ,com.sun.star.comp.Writer.XMLOasisImporter,com.sun.star.comp.Writer.XMLOasisExporter</value></prop> + <prop oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop> + <prop oor:name="TemplateName"/> + <prop oor:name="UIName"> + <!-- The x-no-translate entry is a marker to prevent l10n tooling from translation. If it is not necessary. --> + <value xml:lang="x-no-translate"></value> + <value xml:lang="de">DevGuide FlatXML Master</value> + <value xml:lang="en-US">DevGuide FlatXML Master</value> + </prop> + <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop> + </node> + </node> +</oor:component-data> diff --git a/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/Makefile b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/Makefile new file mode 100644 index 000000000..58366b7d5 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/FilterDevelopment/FlatXmlFilter_java/Makefile @@ -0,0 +1,142 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the Java FlatXMLFilter component example of the Developers Guide. + +PRJ=../../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +COMP_NAME=FlatXmlFilter_java +OUT_COMP_CLASS = $(OUT_CLASS)/$(COMP_NAME) +COMP_PACKAGE = $(OUT_BIN)/$(COMP_NAME).$(UNOOXT_EXT) +COMP_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP_NAME).$(UNOOXT_EXT)") +COMP_JAR_NAME = $(COMP_NAME).uno.jar +COMP_JAR = $(OUT_COMP_CLASS)/$(COMP_JAR_NAME) +COMP_MANIFESTFILE = $(OUT_COMP_CLASS)/$(COMP_NAME).uno.Manifest +COMP_UNOPKG_MANIFEST = $(OUT_COMP_CLASS)/$(COMP_NAME)/META-INF/manifest.xml +COMP_REGISTERFLAG = $(OUT_MISC)$(PS)devguide_$(COMP_NAME)_register_component.flag +COMP_COMPONENTS=$(COMP_NAME).components + +JAVAFILES = \ + FlatXml.java \ + +CLASSFILES = $(patsubst %.java,$(OUT_COMP_CLASS)/%.class,$(JAVAFILES)) + + +#$(COMP_NAME)_CLASSFILES = FlatXml.class FlatXml$(dlr)_FlatXml.class + +$(COMP_NAME)_CLASSFILES = *.class + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_COMP_CLASS)) + + +# Targets +.PHONY: ALL +ALL : \ + FlatXmlFilterJavaExample + +include $(SETTINGS)/stdtarget.mk + +$(OUT_COMP_CLASS)/%.Manifest : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo RegistrationClassName: FlatXml> $@ + +$(CLASSFILES) : $(JAVAFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_COMP_CLASS) $(JAVAFILES) + +# rule for component jar file +$(COMP_JAR) : $(COMP_MANIFESTFILE) $(CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(<F) $($(basename $(basename $(@F)))_CLASSFILES) + +# rule for component package manifest +$(OUT_COMP_CLASS)/%/manifest.xml : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@ + @echo $(OSEP)!DOCTYPE manifest:manifest PUBLIC "$(QM)-//OpenOffice.org//DTD Manifest 1.0//EN$(QM)" "$(QM)Manifest.dtd$(QM)"$(CSEP) >> $@ + @echo $(OSEP)manifest:manifest xmlns:manifest="$(QM)http://openoffice.org/2001/manifest$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.configuration-data$(QM)" >> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)FlatXmlFilter_java.xcu$(QM)"/$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.uno-components$(QM)">> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)$(COMP_COMPONENTS)$(QM)"/$(CSEP)>> $@ + @echo $(OSEP)/manifest:manifest$(CSEP) >> $@ + +# rule for component package file +$(COMP_PACKAGE) : $(COMP_JAR) FlatXmlFilter_java.xcu $(COMP_UNOPKG_MANIFEST) $(COMP_COMPONENTS) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_ZIP) $@ FlatXmlFilter_java.xcu + $(SDK_ZIP) -u $@ $(COMP_COMPONENTS) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_ZIP) -u ../../bin/$(@F) $(<F) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xml + +$(COMP_REGISTERFLAG) : $(COMP_PACKAGE) +ifeq "$(SDK_AUTO_DEPLOYMENT)" "YES" + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(DEPLOYTOOL) $(COMP_PACKAGE_URL) + @echo flagged > $(subst /,$(PS),$@) +else + @echo -------------------------------------------------------------------------------- + @echo If you want to install your component automatically, please set the environment + @echo variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only + @echo possible if no office instance is running. + @echo -------------------------------------------------------------------------------- +endif + +FlatXmlFilterJavaExample : $(COMP_REGISTERFLAG) + @echo -------------------------------------------------------------------------------- + @echo The Java FlatXmlFilter component is installed if SDK_AUTO_DEPLOYMENT = YES. + @echo You can use the filters "$(QM)DevGuide FlatXML ...$(QM)" inside your office installation + @echo after you have installed the "$(QM)FlatXmlTypeDetection.uno.pkg"$(QM) as well. + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_COMP_CLASS)/%.class + $(SDK_JAVA) -classpath "$(SDK_CLASSPATH)" $(basename $@) + +%.local: $(OUT_COMP_CLASS)/%.class + $(SDK_JAVA) -classpath "$(SDK_CLASSPATH)" $(basename $@) local + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_CLASS)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_PACKAGE_URL))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP_REGISTERFLAG))) diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/LinguisticExamples.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/LinguisticExamples.java new file mode 100644 index 000000000..9cbd481cb --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/LinguisticExamples.java @@ -0,0 +1,360 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// used interfaces +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.linguistic2.XLinguServiceManager; +import com.sun.star.linguistic2.XSpellChecker; +import com.sun.star.linguistic2.XHyphenator; +import com.sun.star.linguistic2.XThesaurus; +import com.sun.star.linguistic2.XSpellAlternatives; +import com.sun.star.linguistic2.XHyphenatedWord; +import com.sun.star.linguistic2.XPossibleHyphens; +import com.sun.star.linguistic2.XMeaning; +import com.sun.star.linguistic2.XSearchableDictionaryList; +import com.sun.star.linguistic2.XLinguServiceEventListener; +import com.sun.star.linguistic2.LinguServiceEvent; +import com.sun.star.beans.XPropertySet; +import com.sun.star.beans.PropertyValue; +import com.sun.star.lang.EventObject; +import com.sun.star.lang.Locale; +import com.sun.star.uno.UnoRuntime; + +public class LinguisticExamples +{ + // The remote office context + protected XComponentContext mxRemoteContext = null; + // The MultiServiceFactory interface of the Office + protected XMultiComponentFactory mxRemoteServiceManager = null; + + // The LinguServiceManager interface + protected XLinguServiceManager mxLinguSvcMgr = null; + + // The SpellChecker interface + protected XSpellChecker mxSpell = null; + + // The Hyphenator interface + protected XHyphenator mxHyph = null; + + // The Thesaurus interface + protected XThesaurus mxThes = null; + + // The DictionaryList interface + protected XSearchableDictionaryList mxDicList = null; + + // The LinguProperties interface + protected XPropertySet mxLinguProps = null; + + + public static void main(String args[]) + { + // Create an instance of the class and call its begin method + try { + LinguisticExamples aExample = new LinguisticExamples(); + aExample.Connect(); + aExample.Run(); + } catch (Exception e) { + System.err.println("failed to run examples"); + e.printStackTrace(); + } + } + + + public void Connect() + throws java.lang.Exception + { + // get the remote office context. If necessary a new office + // process is started + mxRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + mxRemoteServiceManager = mxRemoteContext.getServiceManager(); + } + + + /** Get the LinguServiceManager to be used. For example to access spell + checker, thesaurus and hyphenator, also the component may choose to + register itself as listener to it in order to get notified of relevant + events. */ + public boolean GetLinguSvcMgr() + throws com.sun.star.uno.Exception + { + if (mxRemoteContext != null && mxRemoteServiceManager != null) { + Object aObj = mxRemoteServiceManager.createInstanceWithContext( + "com.sun.star.linguistic2.LinguServiceManager", mxRemoteContext ); + mxLinguSvcMgr = UnoRuntime.queryInterface(XLinguServiceManager.class, aObj); + } + return mxLinguSvcMgr != null; + } + + + /** Get the SpellChecker to be used. + */ + public boolean GetSpell() + throws com.sun.star.uno.RuntimeException + { + if (mxLinguSvcMgr != null) + mxSpell = mxLinguSvcMgr.getSpellChecker(); + return mxSpell != null; + } + + /** Get the Hyphenator to be used. + */ + public boolean GetHyph() + throws com.sun.star.uno.RuntimeException + { + if (mxLinguSvcMgr != null) + mxHyph = mxLinguSvcMgr.getHyphenator(); + return mxHyph != null; + } + + /** Get the Thesaurus to be used. + */ + public boolean GetThes() + throws com.sun.star.uno.RuntimeException + { + if (mxLinguSvcMgr != null) + mxThes = mxLinguSvcMgr.getThesaurus(); + return mxThes != null; + } + + + public void Run() + throws Exception + { + GetLinguSvcMgr(); + + + // list of property values to used in function calls below. + // Only properties with values different from the (default) values + // in the LinguProperties property set need to be supllied. + // Thus we may stay with an empty list in order to use the ones + // from the property set. + PropertyValue[] aEmptyProps = new PropertyValue[0]; + + // use american english as language + Locale aLocale = new Locale("en","US",""); + + + + // another list of property values to used in function calls below. + // Only properties with values different from the (default) values + // in the LinguProperties property set need to be supllied. + PropertyValue[] aProps = new PropertyValue[1]; + aProps[0] = new PropertyValue(); + aProps[0].Name = "IsGermanPreReform"; + aProps[0].Value = Boolean.TRUE; + + + GetSpell(); + if (mxSpell != null) + { + // test with correct word + String aWord = "horseback"; + boolean bIsCorrect = mxSpell.isValid( aWord, aLocale, aEmptyProps ); + System.out.println( aWord + ": " + bIsCorrect ); + + // test with incorrect word + aWord = "course"; + bIsCorrect = mxSpell.isValid( aWord, aLocale , aEmptyProps ); + System.out.println( aWord + ": " + bIsCorrect ); + + + aWord = "house"; + XSpellAlternatives xAlt = mxSpell.spell( aWord, aLocale, aEmptyProps ); + if (xAlt == null) + System.out.println( aWord + " is correct." ); + else + { + System.out.println( aWord + " is not correct. A list of proposals follows." ); + String[] aAlternatives = xAlt.getAlternatives(); + if (aAlternatives.length == 0) + System.out.println( "no proposal found." ); + else + { + for (int i = 0; i < aAlternatives.length; ++i) + System.out.println( aAlternatives[i] ); + } + } + } + + + GetHyph(); + if (mxHyph != null) + { + // maximum number of characters to remain before the hyphen + // character in the resulting word of the hyphenation + short nMaxLeading = 6; + + XHyphenatedWord xHyphWord = mxHyph.hyphenate( "waterfall", + aLocale, nMaxLeading , + aEmptyProps ); + if (xHyphWord == null) + System.out.println( "no valid hyphenation position found" ); + else + { + System.out.println( "valid hyphenation pos found at " + + xHyphWord.getHyphenationPos() + + " in " + xHyphWord.getWord() ); + System.out.println( "hyphenation char will be after char " + + xHyphWord.getHyphenPos() + + " in " + xHyphWord.getHyphenatedWord() ); + } + + + //! Note: 'aProps' needs to have set 'IsGermanPreReform' to true! + xHyphWord = mxHyph.queryAlternativeSpelling( "Schiffahrt", + new Locale("de","DE",""), (short)4, aProps ); + if (xHyphWord == null) + System.out.println( "no alternative spelling found at specified position." ); + else + { + if (xHyphWord.isAlternativeSpelling()) + System.out.println( "alternative spelling detected!" ); + System.out.println( "valid hyphenation pos found at " + + xHyphWord.getHyphenationPos() + + " in " + xHyphWord.getWord() ); + System.out.println( "hyphenation char will be after char " + + xHyphWord.getHyphenPos() + + " in " + xHyphWord.getHyphenatedWord() ); + } + + + XPossibleHyphens xPossHyph = mxHyph.createPossibleHyphens("waterfall", + aLocale, + aEmptyProps ); + if (xPossHyph == null) + System.out.println( "no hyphenation positions found." ); + else + System.out.println( xPossHyph.getPossibleHyphens() ); + } + + + GetThes(); + if (mxThes != null) + { + XMeaning[] xMeanings = mxThes.queryMeanings("house", aLocale, + aEmptyProps ); + if (xMeanings == null) + System.out.println( "nothing found." ); + else + { + for (int i = 0; i < xMeanings.length; ++i) + { + System.out.println( "Meaning: " + xMeanings[i].getMeaning() ); + String[] aSynonyms = xMeanings[i].querySynonyms(); + for (int k = 0; k < aSynonyms.length; ++k) + System.out.println( " Synonym: " + aSynonyms[k] ); + } + } + } + + + + XLinguServiceEventListener aClient = new Client(); + + // get access to LinguProperties property set + Object aObj = mxRemoteServiceManager.createInstanceWithContext( + "com.sun.star.linguistic2.LinguProperties", mxRemoteContext); + XPropertySet aLinguProps = UnoRuntime.queryInterface( + XPropertySet.class,aObj); + + // set a spellchecker and hyphenator property value to a defined state + try { + aLinguProps.setPropertyValue("IsGermanPreReform", Boolean.TRUE); + } catch (Exception e) { + } + + // now add the client as listener to the service manager to + // get informed when spellchecking or hyphenation may produce + // different results then before. + mxLinguSvcMgr.addLinguServiceManagerListener(aClient); + + // change that property value in order to trigger a property change + // event that eventually results in the listeners + // 'processLinguServiceEvent' function being called + try { + aLinguProps.setPropertyValue("IsGermanPreReform", Boolean.FALSE); + } catch (Exception e) { + } + + //! keep the listener and the program alive until the event will + //! be launched. + //! There is a voluntary delay before launching the event! + // Of course this code would usually not be in a *real* client + // its + synchronized(this) { + try { + this.wait(4000); + } catch(Exception e) { + + } + } + + //! remove listener before program termination. + //! should not be omitted. + mxLinguSvcMgr.removeLinguServiceManagerListener(aClient); + + + System.exit(0); + } + + /** simple sample implementation of a clients XLinguServiceEventListener + * interface implementation + */ + private class Client + implements XLinguServiceEventListener + { + public void disposing ( EventObject aEventObj ) + { + //! any references to the EventObjects source have to be + //! released here now! + + System.out.println("object listened to will be disposed"); + } + + public void processLinguServiceEvent( LinguServiceEvent aServiceEvent ) + { + //! do here whatever you think needs to be done depending + //! on the event received (e.g. trigger background spellchecking + //! or hyphenation again.) + + System.out.println("Listener called"); + } + } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/Makefile b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/Makefile new file mode 100644 index 000000000..95b6204c0 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/Makefile @@ -0,0 +1,231 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevLinguistic examples of the Developers Guide. + +PRJ=../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevLinguisticExample +OUT_COMP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +COMP1_NAME=SampleHyphenator +COMP1_PACKAGE = $(OUT_BIN)/$(COMP1_NAME).$(UNOOXT_EXT) +COMP1_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP1_NAME).$(UNOOXT_EXT)") +COMP1_JAR_NAME = $(COMP1_NAME).uno.jar +COMP1_JAR = $(OUT_COMP_CLASS)/$(COMP1_JAR_NAME) +COMP1_MANIFESTFILE = $(OUT_COMP_CLASS)/$(COMP1_NAME).uno.Manifest +COMP1_UNOPKG_MANIFEST = $(OUT_COMP_CLASS)/$(COMP1_NAME)/META-INF/manifest.xml +COMP1_COMPONENTS=$(COMP1_NAME).components + +COMP2_NAME=SampleSpellChecker +COMP2_PACKAGE = $(OUT_BIN)/$(COMP2_NAME).$(UNOOXT_EXT) +COMP2_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP2_NAME).$(UNOOXT_EXT)") +COMP2_JAR_NAME = $(COMP2_NAME).uno.jar +COMP2_JAR = $(OUT_COMP_CLASS)/$(COMP2_JAR_NAME) +COMP2_MANIFESTFILE = $(OUT_COMP_CLASS)/$(COMP2_NAME).uno.Manifest +COMP2_UNOPKG_MANIFEST = $(OUT_COMP_CLASS)/$(COMP2_NAME)/META-INF/manifest.xml +COMP2_COMPONENTS=$(COMP2_NAME).components + +COMP3_NAME=SampleThesaurus +COMP3_PACKAGE = $(OUT_BIN)/$(COMP3_NAME).$(UNOOXT_EXT) +COMP3_PACKAGE_URL = $(subst \\,\,"$(COMP_PACKAGE_DIR)$(PS)$(COMP3_NAME).$(UNOOXT_EXT)") +COMP3_JAR_NAME = $(COMP3_NAME).uno.jar +COMP3_JAR = $(OUT_COMP_CLASS)/$(COMP3_JAR_NAME) +COMP3_MANIFESTFILE = $(OUT_COMP_CLASS)/$(COMP3_NAME).uno.Manifest +COMP3_UNOPKG_MANIFEST = $(OUT_COMP_CLASS)/$(COMP3_NAME)/META-INF/manifest.xml +COMP3_COMPONENTS=$(COMP2_NAME).components + +APP1_NAME=LinguisticExamples +APP1_JAR=$(OUT_COMP_CLASS)/$(APP1_NAME).jar + +REGISTERFLAG = $(OUT_MISC)/devguide_officedevlinguistic_register_component.flag + +JAVAFILES = \ + OneInstanceFactory.java \ + PropChgHelper.java \ + PropChgHelper_Hyph.java \ + PropChgHelper_Spell.java \ + XHyphenatedWord_impl.java \ + XMeaning_impl.java \ + XPossibleHyphens_impl.java \ + XSpellAlternatives_impl.java \ + SampleHyphenator.java \ + SampleSpellChecker.java \ + SampleThesaurus.java + +CLASSFILES = $(patsubst %.java,$(OUT_COMP_CLASS)/%.class,$(JAVAFILES)) + +$(COMP1_NAME)_CLASSFILES = XHyphenatedWord_impl.class \ + XPossibleHyphens_impl.class \ + PropChgHelper.class \ + PropChgHelper_Hyph.class \ + OneInstanceFactory.class \ + $(COMP1_NAME).class + +$(COMP2_NAME)_CLASSFILES = XSpellAlternatives_impl.class \ + PropChgHelper_Spell.class \ + PropChgHelper.class \ + OneInstanceFactory.class \ + $(COMP2_NAME).class + +$(COMP3_NAME)_CLASSFILES = XMeaning_impl.class \ + OneInstanceFactory.class \ + $(COMP3_NAME).class + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_COMP_CLASS)) + +.PHONY: ALL +ALL : $(EXAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(OUT_COMP_CLASS)/%.Manifest : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo RegistrationClassName: $(basename $(basename $(@F)))> $@ + +$(CLASSFILES) : $(JAVAFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_COMP_CLASS) $(JAVAFILES) + +# NOTE: because of gnu make problems with full qualified paths, the pattern +# rules for the component jars and the packages doesn't work proper and we +# defined explicit rules + +# rule for component package manifest +$(OUT_COMP_CLASS)/%/manifest.xml : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo $(OSEP)?xml version="$(QM)1.0$(QM)" encoding="$(QM)UTF-8$(QM)"?$(CSEP) > $@ + @echo $(OSEP)!DOCTYPE manifest:manifest PUBLIC "$(QM)-//OpenOffice.org//DTD Manifest 1.0//EN$(QM)" "$(QM)Manifest.dtd$(QM)"$(CSEP) >> $@ + @echo $(OSEP)manifest:manifest xmlns:manifest="$(QM)http://openoffice.org/2001/manifest$(QM)"$(CSEP) >> $@ + @echo $(SQM) $(SQM)$(OSEP)manifest:file-entry manifest:media-type="$(QM)application/vnd.sun.star.uno-components$(QM)" >> $@ + @echo $(SQM) $(SQM)manifest:full-path="$(QM)$(subst /META-INF,,$(subst $(OUT_COMP_CLASS)/,,$(@D))).components$(QM)"/$(CSEP) >> $@ + @echo $(OSEP)/manifest:manifest$(CSEP) >> $@ + +$(COMP1_JAR) : $(COMP1_MANIFESTFILE) $(CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(<F) $($(basename $(basename $(@F)))_CLASSFILES) + +$(COMP1_PACKAGE) : $(COMP1_JAR) $(COMP1_UNOPKG_MANIFEST) $(COMP1_COMPONENTS) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_ZIP) $@ $(COMP1_COMPONENTS) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_ZIP) -u ../../bin/$(@F) $(<F) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xml + +$(COMP2_JAR) : $(COMP2_MANIFESTFILE) $(CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(<F) $($(basename $(basename $(@F)))_CLASSFILES) + +$(COMP2_PACKAGE) : $(COMP2_JAR) $(COMP2_UNOPKG_MANIFEST) $(COMP2_COMPONENTS) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_ZIP) $@ $(COMP2_COMPONENTS) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_ZIP) -u ../../bin/$(@F) $(<F) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xml + +$(COMP3_JAR) : $(COMP3_MANIFESTFILE) $(CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(<F) $($(basename $(basename $(@F)))_CLASSFILES) + +$(COMP3_PACKAGE) : $(COMP3_JAR) $(COMP3_UNOPKG_MANIFEST) $(COMP3_COMPONENTS) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_ZIP) $@ $(COMP3_COMPONENTS) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_ZIP) -u ../../bin/$(@F) $(<F) + cd $(subst /,$(PS),$(OUT_COMP_CLASS)/$(subst .$(UNOOXT_EXT),,$(@F))) && $(SDK_ZIP) -u ../../../bin/$(@F) META-INF/manifest.xml + +$(REGISTERFLAG) : $(COMP1_PACKAGE) $(COMP2_PACKAGE) $(COMP3_PACKAGE) +ifeq "$(SDK_AUTO_DEPLOYMENT)" "YES" + -$(MKDIR) $(subst /,$(PS),$(@D)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + $(DEPLOYTOOL) $(COMP1_PACKAGE_URL) + $(DEPLOYTOOL) $(COMP2_PACKAGE_URL) + $(DEPLOYTOOL) $(COMP3_PACKAGE_URL) + @echo flagged > $(subst /,$(PS),$@) +else + @echo -------------------------------------------------------------------------------- + @echo If you want to install your component automatically, please set the environment + @echo variable SDK_AUTO_DEPLOYMENT = YES. But note that auto deployment is only + @echo possible if no office instance is running. + @echo -------------------------------------------------------------------------------- +endif + +$(OUT_COMP_CLASS)/%.class : %.java + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_COMP_CLASS) $< + +$(OUT_COMP_CLASS)/%.mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: $*>> $@ + +$(APP1_JAR) : $(OUT_COMP_CLASS)/$(APP1_NAME).mf $(OUT_COMP_CLASS)/$(APP1_NAME).class + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_COMP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(basename $(@F)).mf $(basename $(@F)).class $(basename $(@F))$(QUOTE)$$Client.class + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + + +$(EXAMPLE_NAME) : $(REGISTERFLAG) $(APP1_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following command to execute the example! + @echo - + @echo $(MAKE) $(APP1_NAME).run + @echo -------- + @echo Before you can run the examples the components "$(QM)$(COMP1_NAME)$(QM)", + @echo "$(QM)$(COMP2_NAME)$(QM)" and "$(QM)$(COMP3_NAME)$(QM)" must be deployed. + @echo The components will be automatically deployed if SDK_AUTO_DEPLOYMENT = YES. + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_COMP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_COMP_CLASS)) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP1_PACKAGE_URL))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP2_PACKAGE_URL))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(COMP3_PACKAGE_URL))) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$(REGISTERFLAG))) diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/OneInstanceFactory.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/OneInstanceFactory.java new file mode 100644 index 000000000..5e1fdd60b --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/OneInstanceFactory.java @@ -0,0 +1,155 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XInitialization; +import com.sun.star.beans.XPropertySet; +import com.sun.star.uno.XComponentContext; +import com.sun.star.uno.XInterface; +import com.sun.star.uno.UnoRuntime; + +import java.lang.reflect.Constructor; + + +// purpose of this class is to provide a service factory that instantiates +// the services only once (as long as this factory itself exists) +// and returns only reference to that instance. + + +public class OneInstanceFactory implements + XSingleComponentFactory, + XServiceInfo +{ + private final Class aMyClass; + private final String aSvcImplName; + private final String[] aSupportedSvcNames; + private XInterface xInstantiatedService; + + public OneInstanceFactory( + Class aMyClass, + String aSvcImplName, + String[] aSupportedSvcNames ) + { + this.aMyClass = aMyClass; + this.aSvcImplName = aSvcImplName; + this.aSupportedSvcNames = aSupportedSvcNames; + xInstantiatedService = null; + } + + + // XSingleComponentFactory + + public Object createInstanceWithContext( XComponentContext context ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + if (xInstantiatedService == null) + { + //!! the here used services all have exact one constructor!! + Constructor [] aCtor = aMyClass.getConstructors(); + try { + xInstantiatedService = (XInterface) aCtor[0].newInstance( (Object[])null ); + } + catch( Exception e ) { + } + + //!! workaround for services not always being created + //!! via 'createInstanceWithArguments' + XInitialization xIni = UnoRuntime.queryInterface( + XInitialization.class, createInstanceWithContext(context)); + if (xIni != null) + { + Object[] aArguments = new Object[]{ null, null }; + if (context != null) + { + XPropertySet xPropSet = UnoRuntime.queryInterface( + XPropertySet.class, + context.getServiceManager().createInstanceWithContext( + "com.sun.star.linguistic2.LinguProperties", + context ) ); + aArguments[0] = xPropSet; + } + xIni.initialize( aArguments ); + } + } + return xInstantiatedService; + } + + public Object createInstanceWithArgumentsAndContext( Object[] aArguments, XComponentContext context ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + if (xInstantiatedService == null) + { + XInitialization xIni = UnoRuntime.queryInterface( + XInitialization.class, createInstanceWithContext( context )); + if (xIni != null) + xIni.initialize( aArguments ); + } + return xInstantiatedService; + } + + + + // XServiceInfo + + public boolean supportsService( String aServiceName ) + throws com.sun.star.uno.RuntimeException + { + boolean bFound = false; + int nCnt = aSupportedSvcNames.length; + for (int i = 0; i < nCnt && !bFound; ++i) + { + if (aServiceName.equals( aSupportedSvcNames[i] )) + bFound = true; + } + return bFound; + } + + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return aSvcImplName; + } + + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return aSupportedSvcNames; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper.java new file mode 100644 index 000000000..46fcff061 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper.java @@ -0,0 +1,193 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.linguistic2.XLinguServiceEventBroadcaster; +import com.sun.star.linguistic2.XLinguServiceEventListener; +import com.sun.star.linguistic2.LinguServiceEvent; +import com.sun.star.beans.XPropertySet; +import com.sun.star.beans.XPropertyChangeListener; +import com.sun.star.beans.PropertyChangeEvent; +import com.sun.star.lang.EventObject; +import com.sun.star.uno.XInterface; + +import java.util.ArrayList; + +public class PropChgHelper implements + XPropertyChangeListener, + XLinguServiceEventBroadcaster +{ + private final XInterface xEvtSource; + private final String[] aPropNames; + private XPropertySet xPropSet; + private final ArrayList<XLinguServiceEventListener> aLngSvcEvtListeners; + + public PropChgHelper( + XInterface xEvtSource, + String[] aPropNames ) + { + this.xEvtSource = xEvtSource; + this.aPropNames = aPropNames; + xPropSet = null; + aLngSvcEvtListeners = new ArrayList<XLinguServiceEventListener>(); + } + + public XInterface GetEvtSource() + { + return xEvtSource; + } + + public XPropertySet GetPropSet() + { + return xPropSet; + } + + + + public void LaunchEvent( LinguServiceEvent aEvt ) + { + int nCnt = aLngSvcEvtListeners.size(); + for (int i = 0; i < nCnt; ++i) + { + XLinguServiceEventListener xLstnr = + aLngSvcEvtListeners.get(i); + if (xLstnr != null) + xLstnr.processLinguServiceEvent( aEvt ); + } + } + + public void AddAsListenerTo( XPropertySet xPropertySet ) + { + // do not listen any longer to the old property set (if any) + RemoveAsListener(); + + // set new property set to be used and register as listener to it + xPropSet = xPropertySet; + if (xPropSet != null) + { + int nLen = aPropNames.length; + for (int i = 0; i < nLen; ++i) + { + if (aPropNames[i].length() != 0) + { + try { + xPropSet.addPropertyChangeListener( + aPropNames[i], this ); + } + catch( Exception e ) { + } + } + } + } + } + + private void RemoveAsListener() + { + if (xPropSet != null) + { + int nLen = aPropNames.length; + for (int i = 0; i < nLen; ++i) + { + if (aPropNames[i].length() != 0) + { + try { + xPropSet.removePropertyChangeListener( + aPropNames[i], this ); + } + catch( Exception e ) { + } + } + } + + xPropSet = null; + } + } + + // __________ interface methods __________ + + + // XEventListener + + public void disposing( EventObject aSource ) + throws com.sun.star.uno.RuntimeException + { + if (aSource.Source == xPropSet) + { + RemoveAsListener(); + } + } + + + // XPropertyChangeListener + + public void propertyChange( PropertyChangeEvent aEvt ) + throws com.sun.star.uno.RuntimeException + { + // will be overridden in derived classes + } + + + // XLinguServiceEventBroadcaster + + public boolean addLinguServiceEventListener( + XLinguServiceEventListener xListener ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if (xListener != null) + { + bRes = aLngSvcEvtListeners.add( xListener ); + } + return bRes; + } + + public boolean removeLinguServiceEventListener( + XLinguServiceEventListener xListener ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if (xListener != null) + { + int nIdx = aLngSvcEvtListeners.indexOf( xListener ); + if (nIdx != -1) + { + aLngSvcEvtListeners.remove( nIdx ); + bRes = true; + } + } + return bRes; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper_Hyph.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper_Hyph.java new file mode 100644 index 000000000..0945e413f --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper_Hyph.java @@ -0,0 +1,81 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.linguistic2.LinguServiceEvent; +import com.sun.star.linguistic2.LinguServiceEventFlags; +import com.sun.star.beans.PropertyChangeEvent; +import com.sun.star.uno.XInterface; + +public class PropChgHelper_Hyph extends PropChgHelper +{ + public PropChgHelper_Hyph( + XInterface xEvtSource, + String[] aPropNames ) + { + super( xEvtSource, aPropNames ); + } + + + // XPropertyChangeListener + + @Override + public void propertyChange( PropertyChangeEvent aEvt ) + throws com.sun.star.uno.RuntimeException + { + { + short nLngSvcFlags = 0; + if (aEvt.PropertyName.equals( "IsIgnoreControlCharacters" )) + { + // nothing to be done + } + else if (aEvt.PropertyName.equals( "IsUseDictionaryList" ) || + aEvt.PropertyName.equals( "IsGermanPreReform" ) || + aEvt.PropertyName.equals( "HyphMinLeading" ) || + aEvt.PropertyName.equals( "HyphMinTrailing" ) || + aEvt.PropertyName.equals( "HyphMinWordLength" )) + { + nLngSvcFlags = LinguServiceEventFlags.HYPHENATE_AGAIN; + } + + if (nLngSvcFlags != 0) + { + LinguServiceEvent aEvent = new LinguServiceEvent( GetEvtSource(), nLngSvcFlags ); + LaunchEvent( aEvent ); + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper_Spell.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper_Spell.java new file mode 100644 index 000000000..edd0498db --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/PropChgHelper_Spell.java @@ -0,0 +1,105 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.linguistic2.LinguServiceEvent; +import com.sun.star.linguistic2.LinguServiceEventFlags; +import com.sun.star.beans.PropertyChangeEvent; +import com.sun.star.uno.XInterface; + +public class PropChgHelper_Spell extends PropChgHelper +{ + public PropChgHelper_Spell( + XInterface xEvtSource, + String[] aPropNames ) + { + super( xEvtSource, aPropNames ); + } + + + // XPropertyChangeListener + + @Override + public void propertyChange( PropertyChangeEvent aEvt ) + throws com.sun.star.uno.RuntimeException + { + { + short nLngSvcFlags = 0; + boolean bSCWA = false; // SPELL_CORRECT_WORDS_AGAIN ? + boolean bSWWA = false; // SPELL_WRONG_WORDS_AGAIN ? + + boolean bVal = ((Boolean) aEvt.NewValue).booleanValue(); + + if (aEvt.PropertyName.equals( "IsIgnoreControlCharacters" )) + { + // nothing to be done + } + else if (aEvt.PropertyName.equals( "IsGermanPreReform" )) + { + bSCWA = bSWWA = true; + } + else if (aEvt.PropertyName.equals( "IsUseDictionaryList" )) + { + bSCWA = bSWWA = true; + } + else if (aEvt.PropertyName.equals( "IsSpellUpperCase" )) + { + bSCWA = !bVal; // FALSE->TRUE change? + bSWWA = !bSCWA; // TRUE->FALSE change? + } + else if (aEvt.PropertyName.equals( "IsSpellWithDigits" )) + { + bSCWA = !bVal; // FALSE->TRUE change? + bSWWA = !bSCWA; // TRUE->FALSE change? + } + else if (aEvt.PropertyName.equals( "IsSpellCapitalization" )) + { + bSCWA = !bVal; // FALSE->TRUE change? + bSWWA = !bSCWA; // TRUE->FALSE change? + } + + if (bSCWA) + nLngSvcFlags |= LinguServiceEventFlags.SPELL_CORRECT_WORDS_AGAIN; + if (bSWWA) + nLngSvcFlags |= LinguServiceEventFlags.SPELL_WRONG_WORDS_AGAIN; + if (nLngSvcFlags != 0) + { + LinguServiceEvent aEvent = new LinguServiceEvent( GetEvtSource(), nLngSvcFlags ); + LaunchEvent( aEvent ); + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleHyphenator.components b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleHyphenator.components new file mode 100644 index 000000000..bf083b386 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleHyphenator.components @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<components xmlns="http://openoffice.org/2010/uno-components"> + <component loader="com.sun.star.loader.Java2" uri="SampleHyphenator.uno.jar"> + <implementation name="SampleHyphenator"> + <service name="com.sun.star.linguistic2.Hyphenator"/> + </implementation> + </component> +</components> diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleHyphenator.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleHyphenator.java new file mode 100644 index 000000000..930d42c32 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleHyphenator.java @@ -0,0 +1,514 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// uno +import com.sun.star.lib.uno.helper.ComponentBase; +import com.sun.star.uno.UnoRuntime; + +// factories +import com.sun.star.lang.XSingleComponentFactory; + +// supported Interfaces +import com.sun.star.linguistic2.XHyphenator; +import com.sun.star.linguistic2.XLinguServiceEventBroadcaster; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XServiceDisplayName; + +// Exceptions +import com.sun.star.uno.Exception; +import com.sun.star.lang.IllegalArgumentException; + +//used Interfaces +import com.sun.star.linguistic2.XLinguServiceEventListener; +import com.sun.star.linguistic2.XHyphenatedWord; +import com.sun.star.linguistic2.XPossibleHyphens; +import com.sun.star.lang.Locale; +import com.sun.star.beans.XPropertySet; +import com.sun.star.beans.PropertyValue; +import com.sun.star.uno.AnyConverter; +import java.util.ArrayList; + +public class SampleHyphenator extends ComponentBase implements + XHyphenator, + XLinguServiceEventBroadcaster, + XInitialization, + XServiceDisplayName, + XServiceInfo +{ + PropChgHelper_Hyph aPropChgHelper; + ArrayList<?> aEvtListeners; + boolean bDisposing; + + public SampleHyphenator() + { + // names of relevant properties to be used + String[] aProps = new String[] + { + "IsIgnoreControlCharacters", + "IsUseDictionaryList", + "IsGermanPreReform", + "HyphMinLeading", + "HyphMinTrailing", + "HyphMinWordLength" + }; + aPropChgHelper = new PropChgHelper_Hyph( this, aProps ); + aEvtListeners = new ArrayList<Object>(); + bDisposing = false; + } + + private boolean IsEqual( Locale aLoc1, Locale aLoc2 ) + { + return aLoc1.Language.equals( aLoc2.Language ) && + aLoc1.Country .equals( aLoc2.Country ) && + aLoc1.Variant .equals( aLoc2.Variant ); + } + + private boolean GetValueToUse( + String aPropName, + boolean bDefaultVal, + PropertyValue[] aProps ) + { + boolean bRes = bDefaultVal; + + try + { + // use temporary value if supplied + for (int i = 0; i < aProps.length; ++i) + { + if (aPropName.equals( aProps[i].Name )) + { + Object aObj = aProps[i].Value; + if (AnyConverter.isBoolean( aObj )) + { + bRes = AnyConverter.toBoolean( aObj ); + return bRes; + } + } + } + + // otherwise use value from property set (if available) + XPropertySet xPropSet = aPropChgHelper.GetPropSet(); + if (xPropSet != null) // should always be the case + { + Object aObj = xPropSet.getPropertyValue( aPropName ); + if (AnyConverter.isBoolean( aObj )) + bRes = AnyConverter.toBoolean( aObj ); + } + } + catch (Exception e) { + bRes = bDefaultVal; + } + + return bRes; + } + + private short GetValueToUse( + String aPropName, + short nDefaultVal, + PropertyValue[] aProps ) + { + short nRes = nDefaultVal; + + try + { + // use temporary value if supplied + for (int i = 0; i < aProps.length; ++i) + { + if (aPropName.equals( aProps[i].Name )) + { + Object aObj = aProps[i].Value; + if (AnyConverter.isShort( aObj )) + { + nRes = AnyConverter.toShort( aObj ); + return nRes; + } + } + } + + // otherwise use value from property set (if available) + XPropertySet xPropSet = aPropChgHelper.GetPropSet(); + if (xPropSet != null) // should always be the case + { + Object aObj = xPropSet.getPropertyValue( aPropName ); + if (AnyConverter.isShort( aObj )) + nRes = AnyConverter.toShort( aObj ); + } + } + catch (Exception e) { + nRes = nDefaultVal; + } + + return nRes; + } + + // __________ interface methods __________ + + + + //XSupportedLocales + + public Locale[] getLocales() + throws com.sun.star.uno.RuntimeException + { + Locale aLocales[] = + { + new Locale( "de", "DE", "" ), + new Locale( "en", "US", "" ) + }; + + return aLocales; + } + + public boolean hasLocale( Locale aLocale ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) || + IsEqual( aLocale, new Locale( "en", "US", "" ) )) + bRes = true; + return bRes; + } + + + //XHyphenator + + public XHyphenatedWord hyphenate( + String aWord, Locale aLocale, + short nMaxLeading, PropertyValue[] aProperties ) + throws com.sun.star.uno.RuntimeException, + IllegalArgumentException + { + if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) + return null; + + // linguistic is currently not allowed to throw exceptions + // thus we return null fwhich means 'word cannot be hyphenated' + if (!hasLocale( aLocale )) + return null; + + // get values of relevant properties that may be used. + //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' + //! are handled by the dispatcher! Thus there is no need to access + //! them here. + boolean bIsIgnoreControlCharacters = GetValueToUse( "IsIgnoreControlCharacters", true, aProperties ); + boolean bIsUseDictionaryList = GetValueToUse( "IsUseDictionaryList", true, aProperties ); + boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); + short nHyphMinLeading = GetValueToUse( "HyphMinLeading", (short)2, aProperties ); + short nHyphMinTrailing = GetValueToUse( "HyphMinTrailing", (short)2, aProperties ); + short nHyphMinWordLen = GetValueToUse( "HyphMinWordLength", (short)5, aProperties ); + + XHyphenatedWord xRes = null; + + if (aWord.length() >= nHyphMinWordLen) + { + String aHyphenatedWord = aWord; + short nHyphenationPos = -1; + short nHyphenPos = -1; + + //!! This code needs to be replaced by code calling the actual + //!! implementation of your hyphenator + if (IsEqual( aLocale, new Locale( "de", "DE", "" ) ) ) + { + if (bIsGermanPreReform && aWord.equals( "Schiffahrt" )) + { + // Note: there is only one position where the word + // can be hyphenated... + + aHyphenatedWord = "Schifffahrt"; + nHyphenationPos = 4; + nHyphenPos = 5; + } + else if (!bIsGermanPreReform && aWord.equals( "Schifffahrt" )) + { + nHyphenationPos = nHyphenPos = 5; + } + } + else if (IsEqual( aLocale, new Locale( "en", "US", "" ) ) ) + { + int nLast = aWord.length() - 1 - nHyphMinTrailing; + + if ( aWord.equals( "waterfall" ) ) + { + if (4 <= nLast) + nHyphenationPos = nHyphenPos = 4; + else + nHyphenationPos = nHyphenPos = 1; + } + else if ( aWord.equals( "driving" ) ) + { + nHyphenationPos = nHyphenPos = 3; + } + } + + // check if hyphenation pos is valid, + // a value of -1 indicates that hyphenation is not possible + if ( nHyphenationPos != -1 && + (nHyphenationPos > nHyphMinLeading) && + (nHyphenationPos < aWord.length() - nHyphMinTrailing)) + { + xRes = new XHyphenatedWord_impl(aWord, aLocale, + nHyphenationPos, aHyphenatedWord, nHyphenPos); + } + } + return xRes; + } + + public XHyphenatedWord queryAlternativeSpelling( + String aWord, Locale aLocale, + short nIndex, PropertyValue[] aProperties ) + throws com.sun.star.uno.RuntimeException, + IllegalArgumentException + { + if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) + return null; + + // linguistic is currently not allowed to throw exceptions + // thus we return null which means 'word cannot be hyphenated' + if (!hasLocale( aLocale )) + return null; + + // get values of relevant properties that may be used. + //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' + //! are handled by the dispatcher! Thus there is no need to access + //! them here. + boolean bIsIgnoreControlCharacters = GetValueToUse( "IsIgnoreControlCharacters", true, aProperties ); + boolean bIsUseDictionaryList = GetValueToUse( "IsUseDictionaryList", true, aProperties ); + boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); + short nHyphMinLeading = GetValueToUse( "HyphMinLeading", (short)2, aProperties ); + short nHyphMinTrailing = GetValueToUse( "HyphMinTrailing", (short)2, aProperties ); + short nHyphMinWordLen = GetValueToUse( "HyphMinWordLength", (short)5, aProperties ); + + XHyphenatedWord xRes = null; + + //!! This code needs to be replaced by code calling the actual + //!! implementation of your hyphenator + if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) ) + { + // there is an alternative spelling only when the + // word is hyphenated between the "ff" and old german spelling + // is set. + if (aWord.equals( "Schiffahrt" ) && + bIsGermanPreReform && nIndex == 4) + { + xRes = new XHyphenatedWord_impl(aWord, aLocale, + (short)4, "Schifffahrt", (short)5 ); + } + } + else if ( IsEqual( aLocale, new Locale( "en", "US", "" ) ) ) + { + // There are no alternative spellings in the English language + } + + return xRes; + } + + public XPossibleHyphens createPossibleHyphens( + String aWord, Locale aLocale, + PropertyValue[] aProperties ) + throws com.sun.star.uno.RuntimeException, + IllegalArgumentException + { + if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) + return null; + + // linguistic is currently not allowed to throw exceptions + // thus we return null which means 'word cannot be hyphenated' + if (!hasLocale( aLocale )) + return null; + + // get values of relevant properties that may be used. + //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' + //! are handled by the dispatcher! Thus there is no need to access + //! them here. + boolean bIsIgnoreControlCharacters = GetValueToUse( "IsIgnoreControlCharacters", true, aProperties ); + boolean bIsUseDictionaryList = GetValueToUse( "IsUseDictionaryList", true, aProperties ); + boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); + short nHyphMinLeading = GetValueToUse( "HyphMinLeading", (short)2, aProperties ); + short nHyphMinTrailing = GetValueToUse( "HyphMinTrailing", (short)2, aProperties ); + short nHyphMinWordLen = GetValueToUse( "HyphMinWordLength", (short)5, aProperties ); + + XPossibleHyphens xRes = null; + + //!! This code needs to be replaced by code calling the actual + //!! implementation of your hyphenator + if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) ) + { + if (bIsGermanPreReform && aWord.equals( "Schiffahrt" )) + { + short aPos[] = new short[] { (short) 4 }; + xRes = new XPossibleHyphens_impl(aWord, aLocale, + "Schiff=fahrt", aPos); + } + else if (!bIsGermanPreReform && aWord.equals( "Schifffahrt" )) + { + short aPos[] = new short[] { (short) 5 }; + xRes = new XPossibleHyphens_impl(aWord, aLocale, + "Schiff=fahrt", aPos); + } + } + else if ( IsEqual( aLocale, new Locale( "en", "US", "" ) ) ) + { + if ( aWord.equals( "waterfall" ) ) + { + short aPos[] = new short[] + { (short) 1, (short) 4 }; + xRes = new XPossibleHyphens_impl(aWord, aLocale, + "wa=ter=fall", aPos); + } + else if ( aWord.equals( "driving" ) ) + { + short aPos[] = new short[] + { (short) 3 }; + xRes = new XPossibleHyphens_impl(aWord, aLocale, + "driv=ing", aPos); + } + } + + return xRes; + } + + + //XLinguServiceEventBroadcaster + + public boolean addLinguServiceEventListener ( + XLinguServiceEventListener xLstnr ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if (!bDisposing && xLstnr != null) + bRes = aPropChgHelper.addLinguServiceEventListener( xLstnr ); + return bRes; + } + + public boolean removeLinguServiceEventListener( + XLinguServiceEventListener xLstnr ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if (!bDisposing && xLstnr != null) + bRes = aPropChgHelper.removeLinguServiceEventListener( xLstnr ); + return bRes; + } + + + // XServiceDisplayName + + public String getServiceDisplayName( Locale aLocale ) + throws com.sun.star.uno.RuntimeException + { + return "Java Samples"; + } + + + // XInitialization + + public void initialize( Object[] aArguments ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + int nLen = aArguments.length; + if (2 == nLen) + { + XPropertySet xPropSet = UnoRuntime.queryInterface( + XPropertySet.class, aArguments[0]); + // start listening to property changes + aPropChgHelper.AddAsListenerTo( xPropSet ); + } + } + + + + // XServiceInfo + + public boolean supportsService( String aServiceName ) + throws com.sun.star.uno.RuntimeException + { + String[] aServices = getSupportedServiceNames_Static(); + int i, nLength = aServices.length; + boolean bResult = false; + + for( i = 0; !bResult && i < nLength; ++i ) + bResult = aServiceName.equals( aServices[ i ] ); + + return bResult; + } + + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return _aSvcImplName; + } + + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return getSupportedServiceNames_Static(); + } + + // __________ static things __________ + + public static String _aSvcImplName = SampleHyphenator.class.getName(); + + public static String[] getSupportedServiceNames_Static() + { + String[] aResult = { "com.sun.star.linguistic2.Hyphenator" }; + return aResult; + } + + + /** + * Returns a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns a <code>XComponentServiceFactory</code> for creating the component + * @param aImplName the name of the implementation for which a service is desired + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleComponentFactory __getComponentFactory( + String aImplName ) + { + XSingleComponentFactory xSingleComponentFactory = null; + if( aImplName.equals( _aSvcImplName ) ) + { + xSingleComponentFactory = new OneInstanceFactory( + SampleHyphenator.class, _aSvcImplName, + getSupportedServiceNames_Static() ); + } + return xSingleComponentFactory; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleSpellChecker.components b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleSpellChecker.components new file mode 100644 index 000000000..bb489918b --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleSpellChecker.components @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<components xmlns="http://openoffice.org/2010/uno-components"> + <component loader="com.sun.star.loader.Java2" uri="SampleSpellChecker.uno.jar"> + <implementation name="SampleSpellChecker"> + <service name="com.sun.star.linguistic2.SpellChecker"/> + </implementation> + </component> +</components> diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleSpellChecker.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleSpellChecker.java new file mode 100644 index 000000000..dc7ddfddd --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleSpellChecker.java @@ -0,0 +1,457 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// uno +import com.sun.star.lib.uno.helper.ComponentBase; +import com.sun.star.uno.UnoRuntime; + +// factories +import com.sun.star.lang.XSingleComponentFactory; + +// supported Interfaces +import com.sun.star.linguistic2.XSpellChecker; +import com.sun.star.linguistic2.XLinguServiceEventBroadcaster; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XServiceDisplayName; + +// Exceptions +import com.sun.star.uno.Exception; +import com.sun.star.lang.IllegalArgumentException; + +//used Interfaces +import com.sun.star.linguistic2.XLinguServiceEventListener; +import com.sun.star.linguistic2.XSpellAlternatives; +import com.sun.star.linguistic2.SpellFailure; +import com.sun.star.lang.Locale; +import com.sun.star.beans.XPropertySet; +import com.sun.star.beans.PropertyValue; +import com.sun.star.uno.AnyConverter; +import java.util.ArrayList; + +public class SampleSpellChecker extends ComponentBase implements + XSpellChecker, + XLinguServiceEventBroadcaster, + XInitialization, + XServiceDisplayName, + XServiceInfo +{ + PropChgHelper_Spell aPropChgHelper; + ArrayList<?> aEvtListeners; + boolean bDisposing; + + public SampleSpellChecker() + { + // names of relevant properties to be used + String[] aProps = new String[] + { + "IsIgnoreControlCharacters", + "IsUseDictionaryList", + "IsGermanPreReform", + "IsSpellUpperCase", + "IsSpellWithDigits", + "IsSpellCapitalization" + }; + aPropChgHelper = new PropChgHelper_Spell( this, aProps ); + aEvtListeners = new ArrayList<Object>(); + bDisposing = false; + } + + private boolean IsEqual( Locale aLoc1, Locale aLoc2 ) + { + return aLoc1.Language.equals( aLoc2.Language ) && + aLoc1.Country .equals( aLoc2.Country ) && + aLoc1.Variant .equals( aLoc2.Variant ); + } + + private boolean GetValueToUse( + String aPropName, + boolean bDefaultVal, + PropertyValue[] aProps ) + { + boolean bRes = bDefaultVal; + + try + { + // use temporary value if supplied + for (int i = 0; i < aProps.length; ++i) + { + if (aPropName.equals( aProps[i].Name )) + { + Object aObj = aProps[i].Value; + if (AnyConverter.isBoolean( aObj )) + { + bRes = AnyConverter.toBoolean( aObj ); + return bRes; + } + } + } + + // otherwise use value from property set (if available) + XPropertySet xPropSet = aPropChgHelper.GetPropSet(); + if (xPropSet != null) // should always be the case + { + Object aObj = xPropSet.getPropertyValue( aPropName ); + if (AnyConverter.isBoolean( aObj )) + bRes = AnyConverter.toBoolean( aObj ); + } + } + catch (Exception e) { + bRes = bDefaultVal; + } + + return bRes; + } + + private boolean IsUpper( String aWord, Locale aLocale ) + { + java.util.Locale aLang = new java.util.Locale( + aLocale.Language, aLocale.Country, aLocale.Variant ); + return aWord.equals( aWord.toUpperCase( aLang ) ); + } + + private boolean HasDigits( String aWord ) + { + int nLen = aWord.length(); + for (int i = 0; i < nLen; ++i) + { + if (Character.isDigit( aWord.charAt(i) )) + return true; + } + return false; + } + + private short GetSpellFailure( + String aWord, + Locale aLocale, + PropertyValue[] aProperties ) + { + short nRes = -1; + + //!! This code needs to be replaced by code calling the actual + //!! implementation of your spellchecker + boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); + if (IsEqual( aLocale, new Locale( "de", "DE", "" ) )) + { + if (bIsGermanPreReform && aWord.equals( "Schifffahrt" )) + nRes = SpellFailure.SPELLING_ERROR; + else if (!bIsGermanPreReform && aWord.equals( "Schiffahrt" )) + nRes = SpellFailure.SPELLING_ERROR; + } + else if (IsEqual( aLocale, new Locale( "en", "US", "" ) )) + { + // words with 'u', 'U' and 'arizona' are defined to be incorrect + boolean bIsValid = !(aWord.indexOf( "u" ) != -1 || aWord.indexOf( "U" ) != -1) + && !aWord.equals( "arizona" ); + + if (!bIsValid) + { + // default value (no other SpellFailure type is applicable) + nRes = SpellFailure.SPELLING_ERROR; + + if (aWord.equals( "arizona" )) + nRes = SpellFailure.CAPTION_ERROR; + else if (aWord.equals( "house" )) + nRes = SpellFailure.SPELLING_ERROR; + else if (aWord.equals( "course" )) + nRes = SpellFailure.IS_NEGATIVE_WORD; + } + } + + return nRes; + } + + private XSpellAlternatives GetProposals( + String aWord, + Locale aLocale, + PropertyValue[] aProperties ) + { + short nType = SpellFailure.SPELLING_ERROR; + String[] aProposals = null; + + // get values of relevant properties that may be used. + //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' + //! are handled by the dispatcher! Thus there is no need to access + //! them here. + boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); + boolean bIsSpellWithDigits = GetValueToUse( "IsSpellWithDigits", false, aProperties ); + boolean bIsSpellUpperCase = GetValueToUse( "IsSpellUpperCase", false, aProperties ); + boolean bIsSpellCapitalization = GetValueToUse( "IsSpellCapitalization", true, aProperties ); + + //!! This code needs to be replaced by code calling the actual + //!! implementation of your spellchecker + if (IsEqual( aLocale, new Locale( "de", "DE", "" ) )) + { + if (bIsGermanPreReform && aWord.equals( "Schifffahrt" )) + { + nType = SpellFailure.SPELLING_ERROR; + aProposals = new String[]{ "Schiffahrt" }; + } + else if (!bIsGermanPreReform && aWord.equals( "Schiffahrt" )) + { + nType = SpellFailure.SPELLING_ERROR; + aProposals = new String[]{ "Schifffahrt" }; + } + } + else if (IsEqual( aLocale, new Locale( "en", "US", "" ) )) + { + if (aWord.equals( "arizona" )) + { + nType = SpellFailure.CAPTION_ERROR; + aProposals = new String[]{ "Arizona" }; + } + else if (aWord.equals( "house" )) + { + nType = SpellFailure.SPELLING_ERROR; + aProposals = new String[]{ "horse", "home" }; + } + else if (aWord.equals( "course" )) + { + nType = SpellFailure.IS_NEGATIVE_WORD; + aProposals = new String[]{ "line", "plan", "approach" }; + } + } + + // always return a result if word is incorrect, + // proposals may be empty though. + return new XSpellAlternatives_impl( aWord, aLocale, + nType, aProposals ); + } + + // __________ interface methods __________ + + + + //XSupportedLocales + + public Locale[] getLocales() + throws com.sun.star.uno.RuntimeException + { + Locale aLocales[] = + { + new Locale( "de", "DE", "" ), + new Locale( "en", "US", "" ) + }; + + return aLocales; + } + + public boolean hasLocale( Locale aLocale ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if ( IsEqual( aLocale, new Locale( "de", "DE", "" ) ) || + IsEqual( aLocale, new Locale( "en", "US", "" ) )) + bRes = true; + return bRes; + } + + + + //XSpellChecker + + public boolean isValid( + String aWord, Locale aLocale, + PropertyValue[] aProperties ) + throws com.sun.star.uno.RuntimeException, + IllegalArgumentException + { + if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) + return true; + + // linguistic is currently not allowed to throw exceptions + // thus we return null which means 'word cannot be spelled' + if (!hasLocale( aLocale )) + return true; + + // get values of relevant properties that may be used. + //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' + //! are handled by the dispatcher! Thus there is no need to access + //! them here. + boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); + boolean bIsSpellWithDigits = GetValueToUse( "IsSpellWithDigits", false, aProperties ); + boolean bIsSpellUpperCase = GetValueToUse( "IsSpellUpperCase", false, aProperties ); + boolean bIsSpellCapitalization = GetValueToUse( "IsSpellCapitalization", true, aProperties ); + + short nFailure = GetSpellFailure( aWord, aLocale, aProperties ); + if (nFailure != -1) + { + // postprocess result for errors that should be ignored + if ( (!bIsSpellUpperCase && IsUpper( aWord, aLocale )) + || (!bIsSpellWithDigits && HasDigits( aWord )) + || (!bIsSpellCapitalization + && nFailure == SpellFailure.CAPTION_ERROR) + ) + nFailure = -1; + } + + return nFailure == -1; + } + + + public XSpellAlternatives spell( + String aWord, Locale aLocale, + PropertyValue[] aProperties ) + throws com.sun.star.uno.RuntimeException, + IllegalArgumentException + { + if (IsEqual( aLocale, new Locale() ) || aWord.length() == 0) + return null; + + // linguistic is currently not allowed to throw exceptions + // thus we return null fwhich means 'word cannot be spelled' + if (!hasLocale( aLocale )) + return null; + + XSpellAlternatives xRes = null; + if (!isValid( aWord, aLocale, aProperties )) + { + xRes = GetProposals( aWord, aLocale, aProperties ); + } + return xRes; + } + + + + //XLinguServiceEventBroadcaster + + public boolean addLinguServiceEventListener ( + XLinguServiceEventListener xLstnr ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if (!bDisposing && xLstnr != null) + bRes = aPropChgHelper.addLinguServiceEventListener( xLstnr ); + return bRes; + } + + public boolean removeLinguServiceEventListener( + XLinguServiceEventListener xLstnr ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if (!bDisposing && xLstnr != null) + bRes = aPropChgHelper.removeLinguServiceEventListener( xLstnr ); + return bRes; + } + + + // XServiceDisplayName + + public String getServiceDisplayName( Locale aLocale ) + throws com.sun.star.uno.RuntimeException + { + return "Java Samples"; + } + + + // XInitialization + + public void initialize( Object[] aArguments ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + int nLen = aArguments.length; + if (2 == nLen) + { + XPropertySet xPropSet = UnoRuntime.queryInterface( + XPropertySet.class, aArguments[0]); + // start listening to property changes + aPropChgHelper.AddAsListenerTo( xPropSet ); + } + } + + + // XServiceInfo + + public boolean supportsService( String aServiceName ) + throws com.sun.star.uno.RuntimeException + { + String[] aServices = getSupportedServiceNames_Static(); + int i, nLength = aServices.length; + boolean bResult = false; + + for( i = 0; !bResult && i < nLength; ++i ) + bResult = aServiceName.equals( aServices[ i ] ); + + return bResult; + } + + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return _aSvcImplName; + } + + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return getSupportedServiceNames_Static(); + } + + // __________ static things __________ + + public static String _aSvcImplName = SampleSpellChecker.class.getName(); + + public static String[] getSupportedServiceNames_Static() + { + String[] aResult = { "com.sun.star.linguistic2.SpellChecker" }; + return aResult; + } + + + /** + * Returns 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 aImplName the name of the implementation for which a service is desired + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleComponentFactory __getComponentFactory( + String aImplName ) + { + XSingleComponentFactory xSingleComponentFactory = null; + if( aImplName.equals( _aSvcImplName ) ) + { + xSingleComponentFactory = new OneInstanceFactory( + SampleSpellChecker.class, _aSvcImplName, + getSupportedServiceNames_Static() ); + } + return xSingleComponentFactory; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleThesaurus.components b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleThesaurus.components new file mode 100644 index 000000000..025f42451 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleThesaurus.components @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<components xmlns="http://openoffice.org/2010/uno-components"> + <component loader="com.sun.star.loader.Java2" uri="SampleThesaurus.uno.jar"> + <implementation name="SampleThesaurus"> + <service name="com.sun.star.linguistic2.Thesaurus"/> + </implementation> + </component> +</components> diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleThesaurus.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleThesaurus.java new file mode 100644 index 000000000..f5c437095 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/SampleThesaurus.java @@ -0,0 +1,293 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// uno +import com.sun.star.lib.uno.helper.ComponentBase; +import com.sun.star.uno.UnoRuntime; + +// factories +import com.sun.star.lang.XSingleComponentFactory; + +// supported Interfaces +import com.sun.star.linguistic2.XThesaurus; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XServiceDisplayName; + +// Exceptions +import com.sun.star.uno.Exception; +//used Interfaces +import com.sun.star.linguistic2.XMeaning; +import com.sun.star.lang.Locale; +import com.sun.star.beans.XPropertySet; +import com.sun.star.beans.PropertyValue; +import com.sun.star.uno.AnyConverter; +import java.util.ArrayList; + +public class SampleThesaurus extends ComponentBase implements + XThesaurus, + XInitialization, + XServiceDisplayName, + XServiceInfo +{ + PropChgHelper aPropChgHelper; + ArrayList<?> aEvtListeners; + boolean bDisposing; + + public SampleThesaurus() + { + // names of relevant properties to be used + String[] aProps = new String[] + { + "IsIgnoreControlCharacters", + "IsUseDictionaryList", + "IsGermanPreReform", + }; + + // this service has no listeners thus we may use the base class, + // which is here basically used only to keep track of the + // property set (and its lifetime) since it gets used in the + // 'GetValueToUse' function + aPropChgHelper = new PropChgHelper( this, aProps ); + + aEvtListeners = new ArrayList<Object>(); + bDisposing = false; + } + + private boolean IsEqual( Locale aLoc1, Locale aLoc2 ) + { + return aLoc1.Language.equals( aLoc2.Language ) && + aLoc1.Country .equals( aLoc2.Country ) && + aLoc1.Variant .equals( aLoc2.Variant ); + } + + private boolean GetValueToUse( + String aPropName, + boolean bDefaultVal, + PropertyValue[] aProps ) + { + boolean bRes = bDefaultVal; + + try + { + // use temporary value if supplied + for (int i = 0; i < aProps.length; ++i) + { + if (aPropName.equals( aProps[i].Name )) + { + Object aObj = aProps[i].Value; + if (AnyConverter.isBoolean( aObj )) + { + bRes = AnyConverter.toBoolean( aObj ); + return bRes; + } + } + } + + // otherwise use value from property set (if available) + XPropertySet xPropSet = aPropChgHelper.GetPropSet(); + if (xPropSet != null) // should always be the case + { + Object aObj = xPropSet.getPropertyValue( aPropName ); + if (AnyConverter.isBoolean( aObj )) + bRes = AnyConverter.toBoolean( aObj ); + } + } + catch (Exception e) { + bRes = bDefaultVal; + } + + return bRes; + } + + // __________ interface methods __________ + + + + //XSupportedLocales + + public Locale[] getLocales() + throws com.sun.star.uno.RuntimeException + { + Locale aLocales[] = + { + new Locale( "en", "US", "" ) + }; + + return aLocales; + } + + public boolean hasLocale( Locale aLocale ) + throws com.sun.star.uno.RuntimeException + { + boolean bRes = false; + if (IsEqual( aLocale, new Locale( "en", "US", "" ) )) + bRes = true; + return bRes; + } + + + //XThesaurus + + public XMeaning[] queryMeanings( + String aTerm, Locale aLocale, + PropertyValue[] aProperties ) + throws com.sun.star.lang.IllegalArgumentException, + com.sun.star.uno.RuntimeException + { + if (IsEqual( aLocale, new Locale() ) || aTerm.length() == 0) + return null; + + // linguistic is currently not allowed to throw exceptions + // thus we return null fwhich means 'word cannot be looked up' + if (!hasLocale( aLocale )) + return null; + + // get values of relevant properties that may be used. + //! The values for 'IsIgnoreControlCharacters' and 'IsUseDictionaryList' + //! are handled by the dispatcher! Thus there is no need to access + //! them here. + boolean bIsGermanPreReform = GetValueToUse( "IsGermanPreReform", false, aProperties ); + + XMeaning[] aRes = null; + + //!! This code needs to be replaced by code calling the actual + //!! implementation of your thesaurus + if (aTerm.equals( "house" ) && + IsEqual( aLocale, new Locale( "en", "US", "" ) ) ) + { + aRes = new XMeaning[] + { + new XMeaning_impl( "a building where one lives", + new String[]{ "home", "place", "dwelling" } ), + new XMeaning_impl( "a group of people sharing common ancestry", + new String[]{ "family", "clan", "kindred" } ), + new XMeaning_impl( "to provide with lodging", + new String[]{ "room", "board", "put up" } ) + }; + } + + return aRes; + } + + + + // XServiceDisplayName + + public String getServiceDisplayName( Locale aLocale ) + throws com.sun.star.uno.RuntimeException + { + return "Java Samples"; + } + + + // XInitialization + + public void initialize( Object[] aArguments ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + int nLen = aArguments.length; + if (2 == nLen) + { + XPropertySet xPropSet = UnoRuntime.queryInterface( + XPropertySet.class, aArguments[0]); + // start listening to property changes + aPropChgHelper.AddAsListenerTo( xPropSet ); + } + } + + + // XServiceInfo + + public boolean supportsService( String aServiceName ) + throws com.sun.star.uno.RuntimeException + { + String[] aServices = getSupportedServiceNames_Static(); + int i, nLength = aServices.length; + boolean bResult = false; + + for( i = 0; !bResult && i < nLength; ++i ) + bResult = aServiceName.equals( aServices[ i ] ); + + return bResult; + } + + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return _aSvcImplName; + } + + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return getSupportedServiceNames_Static(); + } + + // __________ static things __________ + + public static String _aSvcImplName = SampleThesaurus.class.getName(); + + public static String[] getSupportedServiceNames_Static() + { + String[] aResult = { "com.sun.star.linguistic2.Thesaurus" }; + return aResult; + } + + + /** + * Returns 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 aImplName the name of the implementation for which a service is desired + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleComponentFactory __getComponentFactory( + String aImplName ) + { + XSingleComponentFactory xSingleComponentFactory = null; + if( aImplName.equals( _aSvcImplName ) ) + { + xSingleComponentFactory = new OneInstanceFactory( + SampleThesaurus.class, _aSvcImplName, + getSupportedServiceNames_Static() ); + } + return xSingleComponentFactory; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XHyphenatedWord_impl.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XHyphenatedWord_impl.java new file mode 100644 index 000000000..47963441b --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XHyphenatedWord_impl.java @@ -0,0 +1,100 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.lang.Locale; + +public class XHyphenatedWord_impl implements + com.sun.star.linguistic2.XHyphenatedWord +{ + private String aWord; + private String aHyphenatedWord; + private final short nHyphenPos; + private final short nHyphenationPos; + private Locale aLang; + private final boolean bIsAltSpelling; + + public XHyphenatedWord_impl( + String aWord, + Locale aLang, + short nHyphenationPos, + String aHyphenatedWord, + short nHyphenPos ) + { + this.aWord = aWord; + this.aLang = aLang; + this.nHyphenationPos = nHyphenationPos; + this.aHyphenatedWord = aHyphenatedWord; + this.nHyphenPos = nHyphenPos; + this.bIsAltSpelling = (aWord != aHyphenatedWord); + + //!! none of these cases should ever occur! + //!! values provided only for safety + if (this.aWord == null) + this.aWord = ""; + if (this.aLang == null) + this.aLang = new Locale(); + if (this.aHyphenatedWord == null) + this.aHyphenatedWord = ""; + } + + + // XHyphenatedWord + public String getWord() throws com.sun.star.uno.RuntimeException + { + return aWord; + } + public Locale getLocale() throws com.sun.star.uno.RuntimeException + { + return aLang; + } + public short getHyphenationPos() throws com.sun.star.uno.RuntimeException + { + return nHyphenationPos; + } + public String getHyphenatedWord() throws com.sun.star.uno.RuntimeException + { + return aHyphenatedWord; + } + public short getHyphenPos() throws com.sun.star.uno.RuntimeException + { + return nHyphenPos; + } + public boolean isAlternativeSpelling() throws com.sun.star.uno.RuntimeException + { + return bIsAltSpelling; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XMeaning_impl.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XMeaning_impl.java new file mode 100644 index 000000000..5e30ef22e --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XMeaning_impl.java @@ -0,0 +1,71 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + + + +public class XMeaning_impl implements + com.sun.star.linguistic2.XMeaning +{ + private String aMeaning; + private String[] aSynonyms; + + public XMeaning_impl ( String aMeaning, String[] aSynonyms ) + { + this.aMeaning = aMeaning; + this.aSynonyms = aSynonyms; + + //!! none of these cases should ever occur! + //!! values provided only for safety + if (this.aMeaning == null) + this.aMeaning = ""; + + // a meaning without synonyms may be OK though. + // still for safety an empty existing array has to be provided. + if (this.aSynonyms == null) + this.aSynonyms = new String[]{}; + } + + // XMeaning + public String getMeaning() throws com.sun.star.uno.RuntimeException + { + return aMeaning; + } + public String[] querySynonyms() throws com.sun.star.uno.RuntimeException + { + return aSynonyms; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XPossibleHyphens_impl.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XPossibleHyphens_impl.java new file mode 100644 index 000000000..e64752029 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XPossibleHyphens_impl.java @@ -0,0 +1,92 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.lang.Locale; + +public class XPossibleHyphens_impl implements + com.sun.star.linguistic2.XPossibleHyphens +{ + private String aWord; + private String aHyphWord; + private short[] aOrigHyphenPos; + private Locale aLang; + + public XPossibleHyphens_impl( + String aWord, + Locale aLang, + String aHyphWord, + short[] aOrigHyphenPos) + { + this.aWord = aWord; + this.aLang = aLang; + this.aHyphWord = aHyphWord; + this.aOrigHyphenPos = aOrigHyphenPos; + + //!! none of these cases should ever occur! + //!! values provided only for safety + if (this.aWord == null) + this.aWord = ""; + if (this.aLang == null) + this.aLang = new Locale(); + if (this.aHyphWord == null) + this.aHyphWord = ""; + + // having no hyphenation positions is OK though. + // still for safety an empty existing array has to be provided. + if (this.aOrigHyphenPos == null) + this.aOrigHyphenPos = new short[]{}; + } + + // XPossibleHyphens + public String getWord() throws com.sun.star.uno.RuntimeException + { + return aWord; + } + + public Locale getLocale() throws com.sun.star.uno.RuntimeException + { + return aLang; + } + public String getPossibleHyphens() throws com.sun.star.uno.RuntimeException + { + return aHyphWord; + } + public short[] getHyphenationPositions() throws com.sun.star.uno.RuntimeException + { + return aOrigHyphenPos; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XSpellAlternatives_impl.java b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XSpellAlternatives_impl.java new file mode 100644 index 000000000..d2e9ecbea --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Linguistic/XSpellAlternatives_impl.java @@ -0,0 +1,94 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.lang.Locale; + + +public class XSpellAlternatives_impl implements + com.sun.star.linguistic2.XSpellAlternatives +{ + private String aWord; + private Locale aLanguage; + private String[] aAlt; // list of alternatives, may be empty. + private final short nType; // type of failure + + public XSpellAlternatives_impl( + String aWord, + Locale aLanguage, + short nFailureType, + String[] aAlt ) + { + this.aWord = aWord; + this.aLanguage = aLanguage; + this.aAlt = aAlt; + this.nType = nFailureType; + + //!! none of these cases should ever occur! + //!! values provided only for safety + if (this.aWord == null) + this.aWord = ""; + if (this.aLanguage == null) + this.aLanguage = new Locale(); + + // having no alternatives is OK though. + // still for safety an empty existing array has to be provided. + if (this.aAlt == null) + this.aAlt = new String[]{}; + } + + // XSpellAlternatives + public String getWord() throws com.sun.star.uno.RuntimeException + { + return aWord; + } + public Locale getLocale() throws com.sun.star.uno.RuntimeException + { + return aLanguage; + } + public short getFailureType() throws com.sun.star.uno.RuntimeException + { + return nType; + } + public short getAlternativesCount() throws com.sun.star.uno.RuntimeException + { + return (short) aAlt.length; + } + public String[] getAlternatives() throws com.sun.star.uno.RuntimeException + { + return aAlt; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Makefile b/odk/examples/DevelopersGuide/OfficeDev/Makefile new file mode 100644 index 000000000..88c4df966 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Makefile @@ -0,0 +1,105 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDev examples of the Developers Guide. + +PRJ=../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevExamples +OUT_APP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +APP1_NAME=ContextMenuInterceptor +APP1_JAR=$(OUT_APP_CLASS)/$(APP1_NAME).jar +APP2_NAME=Number_Formats +APP2_JAR=$(OUT_APP_CLASS)/$(APP2_NAME).jar + +APP1_JAVAFILES = \ + MenuElement.java \ + OfficeConnect.java \ + ContextMenuInterceptor.java \ + +APP1_CLASSFILES = $(patsubst %.java,$(OUT_APP_CLASS)/%.class,$(APP1_JAVAFILES)) +APP1_CLASSNAMES = $(patsubst %.java,%.class,$(APP1_JAVAFILES)) + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_APP_CLASS)) + + +# Targets +.PHONY: ALL +ALL : $(EXAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(OUT_APP_CLASS)/%.class : %.java + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $< + +$(OUT_APP_CLASS)/%.mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: $*>> $@ + +$(APP1_JAR) : $(OUT_APP_CLASS)/$(APP1_NAME).mf $(APP1_CLASSFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(basename $(@F)).mf $(APP1_CLASSNAMES) + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + +$(APP2_JAR) : $(OUT_APP_CLASS)/$(APP2_NAME).mf $(OUT_APP_CLASS)/$(APP2_NAME).class + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(basename $(@F)).mf $(basename $(@F)).class + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + + +$(EXAMPLE_NAME) : $(APP1_JAR) $(APP2_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following commands to execute the examples! + @echo - + @echo $(MAKE) $(APP1_NAME).run + @echo $(MAKE) $(APP2_NAME).run + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_APP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_CLASS)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/MenuElement.java b/odk/examples/DevelopersGuide/OfficeDev/MenuElement.java new file mode 100644 index 000000000..c3e8f751a --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/MenuElement.java @@ -0,0 +1,58 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.uno.UnoRuntime; + +// A helper class to determine the menu element type +public class MenuElement +{ + public static boolean IsMenuEntry( com.sun.star.beans.XPropertySet xMenuElement ) { + com.sun.star.lang.XServiceInfo xServiceInfo = + UnoRuntime.queryInterface( + com.sun.star.lang.XServiceInfo.class, xMenuElement ); + + return xServiceInfo.supportsService( "com.sun.star.ui.ActionTrigger" ); + } + + public static boolean IsMenuSeparator( com.sun.star.beans.XPropertySet xMenuElement ) { + com.sun.star.lang.XServiceInfo xServiceInfo = + UnoRuntime.queryInterface( + com.sun.star.lang.XServiceInfo.class, xMenuElement ); + + return xServiceInfo.supportsService( "com.sun.star.ui.ActionTriggerSeparator" ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/Number_Formats.java b/odk/examples/DevelopersGuide/OfficeDev/Number_Formats.java new file mode 100644 index 000000000..dedd084e5 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/Number_Formats.java @@ -0,0 +1,245 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import com.sun.star.beans.PropertyValue; +import com.sun.star.container.XIndexAccess; +import com.sun.star.frame.XComponentLoader; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.sheet.XSpreadsheet; +import com.sun.star.sheet.XSpreadsheets; +import com.sun.star.sheet.XSpreadsheetDocument; +import com.sun.star.table.XCell; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + + +// __________ Implementation __________ + +/** Create a spreadsheet document and provide access to a sheet framework that + is then used to modify some number formats. + */ +public class Number_Formats +{ + // __________ public members and methods __________ + + + + + public static void main( String args[] ) + { + try + { + Number_Formats aSample = new Number_Formats( args ); + aSample.doFunction(); + } + catch( Exception ex ) + { + System.err.println( "Sample caught exception! " + ex ); + ex.printStackTrace(); + System.exit(1); + } + + System.out.println( "Sample done." ); + System.exit(0); + } + + + + public void doFunction() throws RuntimeException, Exception + { + // Assume: + // com.sun.star.sheet.XSpreadsheetDocument maSpreadsheetDoc; + // com.sun.star.sheet.XSpreadsheet maSheet; + + // Query the number formats supplier of the spreadsheet document + com.sun.star.util.XNumberFormatsSupplier xNumberFormatsSupplier = + UnoRuntime.queryInterface( + com.sun.star.util.XNumberFormatsSupplier.class, maSpreadsheetDoc ); + + // Get the number formats from the supplier + com.sun.star.util.XNumberFormats xNumberFormats = + xNumberFormatsSupplier.getNumberFormats(); + + // Query the XNumberFormatTypes interface + com.sun.star.util.XNumberFormatTypes xNumberFormatTypes = + UnoRuntime.queryInterface( + com.sun.star.util.XNumberFormatTypes.class, xNumberFormats ); + + // Get the number format index key of the default currency format, + // note the empty locale for default locale + com.sun.star.lang.Locale aLocale = new com.sun.star.lang.Locale(); + int nCurrencyKey = xNumberFormatTypes.getStandardFormat( + com.sun.star.util.NumberFormat.CURRENCY, aLocale ); + + // Get cell range B3:B11 + com.sun.star.table.XCellRange xCellRange = + maSheet.getCellRangeByPosition( 1, 2, 1, 10 ); + + // Query the property set of the cell range + com.sun.star.beans.XPropertySet xCellProp = + UnoRuntime.queryInterface( + com.sun.star.beans.XPropertySet.class, xCellRange ); + + // Set number format to default currency + xCellProp.setPropertyValue( "NumberFormat", Integer.valueOf(nCurrencyKey) ); + + // Get cell B3 + com.sun.star.table.XCell xCell = maSheet.getCellByPosition( 1, 2 ); + + // Query the property set of the cell + xCellProp = UnoRuntime.queryInterface( + com.sun.star.beans.XPropertySet.class, xCell ); + + // Get the number format index key of the cell's properties + int nIndexKey = ((Integer) xCellProp.getPropertyValue( "NumberFormat" )).intValue(); + if ( nIndexKey != nCurrencyKey ) + System.out.println( "Number format doesn't match!" ); + + // Get the properties of the number format + com.sun.star.beans.XPropertySet xProp = xNumberFormats.getByKey( nIndexKey ); + + // Get the format code string of the number format's properties + String aFormatCode = (String) xProp.getPropertyValue( "FormatString" ); + System.out.println( "FormatString: `" + aFormatCode + "'" ); + + // Create an arbitrary format code + aFormatCode = "\"wonderful \"" + aFormatCode; + + // Test if it's already present + nIndexKey = xNumberFormats.queryKey( aFormatCode, aLocale, false ); + + // If not, add to number formats collection + if ( nIndexKey == -1 ) + { + try + { + nIndexKey = xNumberFormats.addNew( aFormatCode, aLocale ); + } + catch( com.sun.star.util.MalformedNumberFormatException ex ) + { + System.err.println( "Bad number format code: " + ex ); + ex.printStackTrace(); + nIndexKey = -1; + } + } + + // Set the new format at the cell + if ( nIndexKey != -1 ) + xCellProp.setPropertyValue( "NumberFormat", Integer.valueOf(nIndexKey) ); + + + // Set column containing the example values to optimal width to show + // the new format of cell B3 + com.sun.star.table.XColumnRowRange xColRowRange = + UnoRuntime.queryInterface(com.sun.star.table.XColumnRowRange.class, + maSheet); + + com.sun.star.container.XIndexAccess xIndexAccess = + UnoRuntime.queryInterface(com.sun.star.container.XIndexAccess.class, + xColRowRange.getColumns()); + + com.sun.star.beans.XPropertySet xColPropSet = + UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, + xIndexAccess.getByIndex(1)); + + xColPropSet.setPropertyValue( "OptimalWidth", Boolean.TRUE ); + } + + + + public Number_Formats( String[] args ) throws java.lang.Exception + { + // get the remote office context. If necessary a new office + // process is started + XComponentContext aOfficeContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + XMultiComponentFactory aServiceManager = aOfficeContext.getServiceManager(); + + // create a new spreadsheet document + XComponentLoader aLoader = UnoRuntime.queryInterface( + XComponentLoader.class, aServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", aOfficeContext) ); + + maSpreadsheetDoc = UnoRuntime.queryInterface( + XSpreadsheetDocument.class, + aLoader.loadComponentFromURL( "private:factory/scalc", + "_blank", + 0, + new PropertyValue[ 0 ] ) ); + + if ( !initSpreadsheet() ) + System.exit( 0 ); + } + + + // __________ private members and methods __________ + + private final XSpreadsheetDocument maSpreadsheetDoc; + private XSpreadsheet maSheet; // the first sheet + + + + + /** init the first sheet + */ + private boolean initSpreadsheet() + { + boolean bOk = true; + XSpreadsheets aSheets = maSpreadsheetDoc.getSheets(); + try + { + XIndexAccess aSheetsIA = UnoRuntime.queryInterface( XIndexAccess.class, aSheets ); + maSheet = UnoRuntime.queryInterface(XSpreadsheet.class, aSheetsIA.getByIndex( 0 )); + + // enter some values in B3:B11 + for( int iCounter=1; iCounter < 10; iCounter++ ) + { + XCell aCell = maSheet.getCellByPosition( 1, 1 + iCounter ); + aCell.setValue( iCounter ); + } + } + catch( Exception ex ) + { + System.err.println( "Couldn't initialize Spreadsheet Document: " + ex ); + ex.printStackTrace(); + bOk = false; + } + return bOk; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/OfficeConnect.java b/odk/examples/DevelopersGuide/OfficeDev/OfficeConnect.java new file mode 100644 index 000000000..d8db72aad --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/OfficeConnect.java @@ -0,0 +1,140 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +// __________ Imports __________ + +import com.sun.star.uno.UnoRuntime; + +// __________ Implementation __________ + +/** + * support ONE singleton uno connection to a running office installation! + * Can be used to open/use/close connection to uno environment of an already running office. + * ctor isn't available from outside. You should call static function "getConnection()" + * to open or use internal set connection which is created one times only. + * + */ +public class OfficeConnect +{ + + + /** + * At first call we create static connection object and get the remote office + * context and the remote office service manager. A new office process is + * started if necessary. + * Then - and for all further requests we return these static connection member. + */ + public static synchronized OfficeConnect createConnection() + throws java.lang.Exception + { + if (maConnection == null) + { + maConnection = new OfficeConnect(); + } + return maConnection; + } + + + + + + + + /** + * ctor + * We try to open the connection in our ctor ... transparently for the user. + * We made it private to support singleton pattern of these implementation. + * see getConnection() for further information + */ + private OfficeConnect() throws java.lang.Exception + { + // get the remote office context. If necessary a new office + // process is started + mxOfficeContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + mxServiceManager = mxOfficeContext.getServiceManager(); + } + + + + /** + * create uno components inside remote office process + * After connection of these process to a running office we have access to remote service manager of it. + * So we can use it to create all existing services. Use this method to create components by name and + * get her interface. Casting of it to right target interface is part of your implementation. + * + * @param aType describe class type of created service + * Returned object can be casted directly to this one. + * Uno query was done by this method automatically. + * @param sServiceSpecifier name of service which should be created + * @return Description of the Returned Value + */ + public <T> T createRemoteInstance(Class<T> aType, String sServiceSpecifier) + { + T aResult = null; + try + { + aResult = UnoRuntime.queryInterface( + aType, mxServiceManager.createInstanceWithContext( + sServiceSpecifier, mxOfficeContext)); + } + catch (com.sun.star.uno.Exception ex) + { + System.err.println("Couldn't create Service of type " + sServiceSpecifier + ": " + ex); + ex.printStackTrace(); + System.exit(0); + } + return aResult; + } + + + + + + + + /** + * member + */ + // singleton connection instance + private static OfficeConnect maConnection; + + // reference to remote office context + private final com.sun.star.uno.XComponentContext mxOfficeContext; + // reference to remote service manager + private final com.sun.star.lang.XMultiComponentFactory mxServiceManager; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/PathSettings/Makefile b/odk/examples/DevelopersGuide/OfficeDev/PathSettings/Makefile new file mode 100644 index 000000000..bc55266ef --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/PathSettings/Makefile @@ -0,0 +1,91 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevPathSettingsTest example of the Developers Guide. + +PRJ=../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevPathSettingsTest +OUT_APP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +APP1_NAME=PathSettingsTest +APP1_JAR=$(OUT_APP_CLASS)/$(APP1_NAME).jar + +SDK_CLASSPATH=$(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_APP_CLASS)) + + +# Targets +.PHONY: ALL +ALL : $(EXAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(OUT_APP_CLASS)/%.class : %.java + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $< + +$(OUT_APP_CLASS)/%.mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: $*>> $@ + +$(OUT_APP_CLASS)/%.jar : $(OUT_APP_CLASS)/%.mf $(OUT_APP_CLASS)/%.class + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $*.mf $*.class + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + +$(APP1_JAR) : $(OUT_APP_CLASS)/$(APP1_NAME).mf $(OUT_APP_CLASS)/$(APP1_NAME).class + +$(EXAMPLE_NAME) : $(APP1_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following commands to execute the examples! + @echo - + @echo $(MAKE) $(APP1_NAME).run + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_APP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_CLASS)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/PathSettings/PathSettingsTest.java b/odk/examples/DevelopersGuide/OfficeDev/PathSettings/PathSettingsTest.java new file mode 100644 index 000000000..f8a17a16b --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/PathSettings/PathSettingsTest.java @@ -0,0 +1,164 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.beans.XPropertySet; +import com.sun.star.util.thePathSettings; + +/* + * Provides example code how to access and use the + * path pathsettings service. + */ +public class PathSettingsTest { + + /* + * List of pre-defined path variables supported by + * the path settings service. + */ + private static String[] predefinedPathProperties = { + "Addin", + "AutoCorrect", + "AutoText", + "Backup", + "Basic", + "Bitmap", + "Config", + "Dictionary", + "Favorite", + "Filter", + "Gallery", + "Graphic", + "Help", + "Linguistic", + "Module", + "Palette", + "Plugin", + "Storage", + "Temp", + "Template", + "UIConfig", + "UserConfig", + "UserDictionary", + "Work" + }; + + /* + * @param args the command line arguments + */ + public static void main(String[] args) { + + XComponentContext xRemoteContext = null; + XPropertySet xPathSettingsService = null; + + try { + // get the remote office context. If necessary a new office + // process is started + xRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + + Object pathSubst = thePathSettings.get( xRemoteContext ); + xPathSettingsService = UnoRuntime.queryInterface( + XPropertySet.class, pathSubst); + + /* Work with path settings */ + workWithPathSettings( xPathSettingsService ); + } + catch (java.lang.Exception e){ + e.printStackTrace(); + } + finally { + System.exit(0); + } + } + + /* + * Retrieve and set path properties from path settings service + * @param xPathSettingsService the path settings service + */ + public static void workWithPathSettings( XPropertySet xPathSettingsService ) + { + if ( xPathSettingsService != null ) { + for ( int i=0; i<predefinedPathProperties.length; i++ ) { + try { + /* Retrieve values for path properties from path settings + * service*/ + Object aValue = xPathSettingsService.getPropertyValue( + predefinedPathProperties[i] ); + + // getPropertyValue returns an Object, you have to cast + // it to type that you need + String aPath = (String)aValue; + System.out.println( "Property="+ predefinedPathProperties[i] + + " Path=" + aPath ); + } + catch ( com.sun.star.beans.UnknownPropertyException e) { + System.err.println( "UnknownPropertyException has been thrown accessing "+predefinedPathProperties[i]); + } + catch ( com.sun.star.lang.WrappedTargetException e ) { + System.err.println( "WrappedTargetException has been thrown accessing "+predefinedPathProperties[i]); + } + } + + // Try to modify the work path property. After running this example + // you should see the new value of "My Documents" in the path options + // tab page, accessible via "Tools - Options - [Star|Open]Office - + // Paths". + // If you want to revert the changes, you can also do it with the + // path tab page. + try { + xPathSettingsService.setPropertyValue( "Work", "$(temp)" ); + String aValue = (String)xPathSettingsService.getPropertyValue( "Work" ); + System.out.println( "\nNote: The example changes your current " + +"setting of the work path!\nThe work path " + +"should be now=" + aValue ); + } + catch ( com.sun.star.beans.UnknownPropertyException e) { + System.err.println( "UnknownPropertyException has been thrown accessing PathSettings service"); + } + catch ( com.sun.star.lang.WrappedTargetException e ) { + System.err.println( "WrappedTargetException has been thrown accessing PathSettings service"); + } + catch ( com.sun.star.beans.PropertyVetoException e ) { + System.err.println( "PropertyVetoException has been thrown accessing PathSettings service"); + } + catch ( com.sun.star.lang.IllegalArgumentException e ) { + System.err.println( "IllegalArgumentException has been thrown accessing PathSettings service"); + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/PathSubstitution/Makefile b/odk/examples/DevelopersGuide/OfficeDev/PathSubstitution/Makefile new file mode 100644 index 000000000..20bb65687 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/PathSubstitution/Makefile @@ -0,0 +1,91 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevPathSettingsTest example of the Developers Guide. + +PRJ=../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevPathSubstitutionTest +OUT_APP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +APP1_NAME=PathSubstitutionTest +APP1_JAR=$(OUT_APP_CLASS)/$(APP1_NAME).jar + +SDK_CLASSPATH=$(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_APP_CLASS)) + + +# Targets +.PHONY: ALL +ALL : $(EXAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(OUT_APP_CLASS)/%.class : %.java + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $< + +$(OUT_APP_CLASS)/%.mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: $*>> $@ + +$(OUT_APP_CLASS)/%.jar : $(OUT_APP_CLASS)/%.mf $(OUT_APP_CLASS)/%.class + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $*.mf $*.class + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + +$(APP1_JAR) : $(OUT_APP_CLASS)/$(APP1_NAME).mf $(OUT_APP_CLASS)/$(APP1_NAME).class + +$(EXAMPLE_NAME) : $(APP1_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following commands to execute the examples! + @echo - + @echo $(MAKE) $(APP1_NAME).run + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_APP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_CLASS)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/PathSubstitution/PathSubstitutionTest.java b/odk/examples/DevelopersGuide/OfficeDev/PathSubstitution/PathSubstitutionTest.java new file mode 100644 index 000000000..98fd919c9 --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/PathSubstitution/PathSubstitutionTest.java @@ -0,0 +1,116 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.util.XStringSubstitution; + +public class PathSubstitutionTest { + + /* + * List of pre-defined path variables supported by + * the path substitution service. + */ + private static String[] predefinedPathVariables = { + "$(home)","$(inst)","$(prog)","$(temp)","$(user)", "$(username)", + "$(work)","$(path)","$(langid)","$(vlang)" + }; + + /* + * @param args the command line arguments + */ + public static void main(String[] args) { + + XComponentContext xRemoteContext = null; + XMultiComponentFactory xRemoteServiceManager = null; + XStringSubstitution xPathSubstService = null; + + try { + // get the remote office context. If necessary a new office + // process is started + xRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + xRemoteServiceManager = xRemoteContext.getServiceManager(); + + Object pathSubst = xRemoteServiceManager.createInstanceWithContext( + "com.sun.star.comp.framework.PathSubstitution", xRemoteContext ); + xPathSubstService = UnoRuntime.queryInterface( + XStringSubstitution.class, pathSubst); + + /* Work with path variables */ + workWithPathVariables( xPathSubstService ); + } + catch (java.lang.Exception e){ + e.printStackTrace(); + } + finally { + System.exit(0); + } + } + + public static void workWithPathVariables( XStringSubstitution xPathSubstService ) + { + if ( xPathSubstService != null ) { + for ( int i=0; i<predefinedPathVariables.length; i++ ) { + try { + /* Retrieve values for pre-defined path variables */ + String aValue = xPathSubstService.getSubstituteVariableValue( + predefinedPathVariables[i] ); + System.out.println( "Variable: "+ predefinedPathVariables[i] + + " value=" + aValue ); + } + catch ( com.sun.star.container.NoSuchElementException e) { + System.err.println( "NoSuchElementException has been thrown accessing "+predefinedPathVariables[i]); + } + } + + // Check the resubstitution function + try { + String aPath = xPathSubstService.getSubstituteVariableValue( + predefinedPathVariables[0] ); // Use $(home) as starting point + aPath += "/test"; // extend the path + System.out.println( "Path="+aPath ); + String aResubstPath = xPathSubstService.reSubstituteVariables( aPath ); + System.out.println( "Resubstituted path="+aResubstPath ); + } + catch ( com.sun.star.container.NoSuchElementException e ) { + System.err.println( "NoSuchElementException has been thrown accessing "+predefinedPathVariables[0]); + } + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/Makefile b/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/Makefile new file mode 100644 index 000000000..ae3d607cf --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/Makefile @@ -0,0 +1,96 @@ +#************************************************************************* +# +# The Contents of this file are made available subject to the terms of +# the BSD license. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of Sun Microsystems, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#************************************************************************** + +# Builds the OfficeDevClipboard example of the Developers Guide. + +PRJ=../../../.. +SETTINGS=$(PRJ)/settings + +include $(SETTINGS)/settings.mk +include $(SETTINGS)/std.mk + +# Define non-platform/compiler specific settings +EXAMPLE_NAME=OfficeDevTerminationTest +OUT_APP_CLASS = $(OUT_CLASS)/$(EXAMPLE_NAME) + +APP1_NAME=TerminationTest +APP1_JAR=$(OUT_APP_CLASS)/$(APP1_NAME).jar + +APP1_JAVAFILES = \ + TerminateListener.java \ + TerminationTest.java + +APP1_CLASSFILES = $(patsubst %.java,$(OUT_APP_CLASS)/%.class,$(APP1_JAVAFILES)) +APP1_CLASSNAMES = $(patsubst %.java,%.class,$(APP1_JAVAFILES)) + +SDK_CLASSPATH = $(subst $(EMPTYSTRING) $(PATH_SEPARATOR),$(PATH_SEPARATOR),$(CLASSPATH)\ + $(PATH_SEPARATOR)$(OUT_APP_CLASS)) + + +# Targets +.PHONY: ALL +ALL : $(EXAMPLE_NAME) + +include $(SETTINGS)/stdtarget.mk + +$(APP1_CLASSFILES) : $(APP1_JAVAFILES) + -$(MKDIR) $(subst /,$(PS),$(@D)) + $(SDK_JAVAC) $(JAVAC_FLAGS) -classpath "$(SDK_CLASSPATH)" -d $(OUT_APP_CLASS) $^ + +$(OUT_APP_CLASS)/%.mf : + -$(MKDIR) $(subst /,$(PS),$(@D)) + @echo Main-Class: com.sun.star.lib.loader.Loader> $@ + $(ECHOLINE)>> $@ + @echo Name: com/sun/star/lib/loader/Loader.class>> $@ + @echo Application-Class: $*>> $@ + +$(APP1_JAR) : $(OUT_APP_CLASS)/$(APP1_NAME).mf $(APP1_CLASSFILES) + -$(DEL) $(subst \\,\,$(subst /,$(PS),$@)) + -$(MKDIR) $(subst /,$(PS),$(@D)) + +cd $(subst /,$(PS),$(OUT_APP_CLASS)) && $(SDK_JAR) cvfm $(@F) $(basename $(@F)).mf $(APP1_CLASSNAMES) + +$(SDK_JAR) uvf $@ $(SDK_JAVA_UNO_BOOTSTRAP_FILES) + +$(EXAMPLE_NAME) : $(APP1_JAR) + @echo -------------------------------------------------------------------------------- + @echo Please use the following command to execute the example! + @echo - + @echo $(MAKE) $(APP1_NAME).run + @echo -------------------------------------------------------------------------------- + +%.run: $(OUT_APP_CLASS)/%.jar + $(SDK_JAVA) -Dcom.sun.star.lib.loader.unopath="$(OFFICE_PROGRAM_PATH)" -jar $< + +.PHONY: clean +clean : + -$(DELRECURSIVE) $(subst /,$(PS),$(OUT_APP_CLASS)) diff --git a/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/TerminateListener.java b/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/TerminateListener.java new file mode 100644 index 000000000..fd902daee --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/TerminateListener.java @@ -0,0 +1,59 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.frame.TerminationVetoException; +import com.sun.star.frame.XTerminateListener; + +public class TerminateListener implements XTerminateListener { + + public void notifyTermination(com.sun.star.lang.EventObject eventObject) { + System.out.println("about to terminate..."); + } + + public void queryTermination(com.sun.star.lang.EventObject eventObject) + throws TerminationVetoException { + + // test if we can terminate now + if (TerminationTest.isAtWork()) { + System.out.println("Terminate while we are at work? You can't mean it serious ;-)!"); + throw new TerminationVetoException(); + } + } + + public void disposing(com.sun.star.lang.EventObject eventObject) { + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/TerminationTest.java b/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/TerminationTest.java new file mode 100644 index 000000000..3d0fdde2e --- /dev/null +++ b/odk/examples/DevelopersGuide/OfficeDev/TerminationTest/TerminationTest.java @@ -0,0 +1,100 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.frame.XDesktop; + +public class TerminationTest { + + private static boolean atWork = false; + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + + XComponentContext xRemoteContext = null; + XMultiComponentFactory xRemoteServiceManager = null; + XDesktop xDesktop = null; + + try { + // get the remote office context. If necessary a new office + // process is started + xRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap(); + System.out.println("Connected to a running office ..."); + xRemoteServiceManager = xRemoteContext.getServiceManager(); + + Object desktop = xRemoteServiceManager.createInstanceWithContext( + "com.sun.star.frame.Desktop", xRemoteContext); + xDesktop = UnoRuntime.queryInterface(XDesktop.class, desktop); + + TerminateListener terminateListener = new TerminateListener(); + xDesktop.addTerminateListener(terminateListener); + + atWork = true; + // try to terminate while we are at work + boolean terminated = xDesktop.terminate(); + System.out.println("The Office " + + (terminated ? + "has been terminated" : + "is still running, we are at work")); + + // no longer at work + atWork = false; + // once more: try to terminate + terminated = xDesktop.terminate(); + System.out.println("The Office " + + (terminated ? + "has been terminated" : + "is still running. Someone else prevents termination, " + + "e.g. the quickstarter")); + } + catch (java.lang.Exception e){ + e.printStackTrace(); + } + finally { + System.exit(0); + } + + + } + public static boolean isAtWork() { + return atWork; + } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |