From 59f8cd34c283ebfe7bf3061fc1c82e6d743518a6 Mon Sep 17 00:00:00 2001
From: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
Date: Thu, 7 Apr 2016 11:55:05 +0200
Subject: [PATCH] Add example dialog

---
 dialog/ActionOneDialog.xdl                    |  12 ++
 package.properties                            |   4 +-
 .../example/comp/StarterProjectImpl.java      |   4 +-
 .../example/dialog/ActionOneDialog.java       |  43 ++++++
 .../example/helper/DialogHelper.java          | 139 ++++++++++++++++++
 .../example/helper/FileHelper.java            |  59 ++++++++
 6 files changed, 258 insertions(+), 3 deletions(-)
 create mode 100644 dialog/ActionOneDialog.xdl
 create mode 100644 source/org/libreoffice/example/dialog/ActionOneDialog.java
 create mode 100644 source/org/libreoffice/example/helper/FileHelper.java

diff --git a/dialog/ActionOneDialog.xdl b/dialog/ActionOneDialog.xdl
new file mode 100644
index 0000000..8bf5705
--- /dev/null
+++ b/dialog/ActionOneDialog.xdl
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE dlg:window PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "dialog.dtd">
+<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="ActionOneDialog" dlg:left="87" dlg:top="26" dlg:width="230" dlg:height="106" dlg:closeable="true" dlg:moveable="true" dlg:title="Action One">
+ <dlg:bulletinboard>
+  <dlg:text dlg:id="Label1" dlg:tab-index="0" dlg:left="6" dlg:top="6" dlg:width="206" dlg:height="21" dlg:value="Import this dialog file in LibreOffice to add your own widgets"/>
+  <dlg:text dlg:id="Label2" dlg:tab-index="1" dlg:left="-88" dlg:top="64" dlg:width="11" dlg:height="2" dlg:value="Label2"/>
+  <dlg:text dlg:id="Label3" dlg:tab-index="2" dlg:left="6" dlg:top="34" dlg:width="214" dlg:height="38" dlg:value="You can do that by navigating to&#x0a;Tools-&gt;Macros-&gt;Manage Dialogs,&#x0a;then create a new dialog and import this file using the &quot;Import Dialog&quot; button on the toolbar.&#x0a;When finished, export it again using the toolbar button &quot;Export Dialog&quot;."/>
+  <dlg:button dlg:id="CommandButtonClose" dlg:tab-index="3" dlg:left="173" dlg:top="88" dlg:width="51" dlg:height="13" dlg:value="Close">
+   <script:event script:event-name="on-performaction" script:macro-name="vnd.sun.star.UNO:actionOk" script:language="UNO"/>
+  </dlg:button>
+ </dlg:bulletinboard>
+</dlg:window>
\ No newline at end of file
diff --git a/package.properties b/package.properties
index 79369ec..cfffe3d 100644
--- a/package.properties
+++ b/package.properties
@@ -1,3 +1,3 @@
 #Written by the OOEclipseIntegration
-#Wed Apr 06 16:28:26 CEST 2016
-contents=description, description/desc_en.txt, images, images/actionOne_16.png, images/actionOne_26.png, registry, registry/org, registry/org/openoffice, registry/org/openoffice/Office, registry/org/openoffice/Office/Accelerators.xcu, registry/org/openoffice/Office/Addons.xcu, registry/org/openoffice/Office/UI, registry/org/openoffice/Office/UI/WriterWindowState.xcu
+#Thu Apr 07 11:36:27 CEST 2016
+contents=description, description/desc_en.txt, dialog, dialog/ActionOneDialog.xdl, images, images/actionOne_16.png, images/actionOne_26.png, registry, registry/org, registry/org/openoffice, registry/org/openoffice/Office, registry/org/openoffice/Office/Accelerators.xcu, registry/org/openoffice/Office/Addons.xcu, registry/org/openoffice/Office/UI, registry/org/openoffice/Office/UI/WriterWindowState.xcu
diff --git a/source/org/libreoffice/example/comp/StarterProjectImpl.java b/source/org/libreoffice/example/comp/StarterProjectImpl.java
index e401999..912c44c 100644
--- a/source/org/libreoffice/example/comp/StarterProjectImpl.java
+++ b/source/org/libreoffice/example/comp/StarterProjectImpl.java
@@ -3,6 +3,7 @@ package org.libreoffice.example.comp;
 import com.sun.star.uno.XComponentContext;
 import com.sun.star.lib.uno.helper.Factory;
 
+import org.libreoffice.example.dialog.ActionOneDialog;
 import org.libreoffice.example.helper.DialogHelper;
 
 import com.sun.star.lang.XSingleComponentFactory;
@@ -63,7 +64,8 @@ public final class StarterProjectImpl extends WeakBase
     {
     	switch (action) {
     	case "actionOne":
-    		DialogHelper.showInfoMessage(m_xContext, null, action);
+    		ActionOneDialog actionOneDialog = new ActionOneDialog(m_xContext);
+    		actionOneDialog.show();
     		break;
     	default:
     		DialogHelper.showErrorMessage(m_xContext, null, "Unknown action: " + action);
diff --git a/source/org/libreoffice/example/dialog/ActionOneDialog.java b/source/org/libreoffice/example/dialog/ActionOneDialog.java
new file mode 100644
index 0000000..f3f398f
--- /dev/null
+++ b/source/org/libreoffice/example/dialog/ActionOneDialog.java
@@ -0,0 +1,43 @@
+package org.libreoffice.example.dialog;
+
+import org.libreoffice.example.helper.DialogHelper;
+
+import com.sun.star.awt.XDialog;
+import com.sun.star.awt.XDialogEventHandler;
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.uno.XComponentContext;
+
+
+public class ActionOneDialog implements XDialogEventHandler {
+	
+	private XDialog dialog;
+	private static final String actionOk = "actionOk";
+	private String[] supportedActions = new String[] { actionOk };
+	
+	public ActionOneDialog(XComponentContext xContext) {
+		this.dialog = DialogHelper.createDialog("ActionOneDialog.xdl", xContext, this);
+	}
+
+	public void show() {
+		dialog.execute();
+	}
+	
+	private void onOkButtonPressed() {
+		dialog.endExecute();
+	}
+	
+	@Override
+	public boolean callHandlerMethod(XDialog dialog, Object eventObject, String methodName) throws WrappedTargetException {
+		if (methodName.equals(actionOk)) {
+			onOkButtonPressed();
+			return true; // Event was handled
+		}
+		return false; // Event was not handled
+	}
+
+	@Override
+	public String[] getSupportedMethodNames() {
+		return supportedActions;
+	}
+
+}
diff --git a/source/org/libreoffice/example/helper/DialogHelper.java b/source/org/libreoffice/example/helper/DialogHelper.java
index 153533c..a6df22c 100644
--- a/source/org/libreoffice/example/helper/DialogHelper.java
+++ b/source/org/libreoffice/example/helper/DialogHelper.java
@@ -1,17 +1,156 @@
 package org.libreoffice.example.helper;
 
+import java.io.File;
+
 import com.sun.star.awt.MessageBoxType;
+import com.sun.star.awt.Point;
+import com.sun.star.awt.XButton;
+import com.sun.star.awt.XComboBox;
+import com.sun.star.awt.XControl;
+import com.sun.star.awt.XControlContainer;
+import com.sun.star.awt.XControlModel;
 import com.sun.star.awt.XDialog;
+import com.sun.star.awt.XDialogEventHandler;
+import com.sun.star.awt.XDialogProvider2;
+import com.sun.star.awt.XFixedText;
+import com.sun.star.awt.XListBox;
 import com.sun.star.awt.XMessageBox;
 import com.sun.star.awt.XMessageBoxFactory;
+import com.sun.star.awt.XTextComponent;
 import com.sun.star.awt.XToolkit;
+import com.sun.star.awt.XWindow;
 import com.sun.star.awt.XWindowPeer;
+import com.sun.star.beans.PropertyVetoException;
+import com.sun.star.beans.UnknownPropertyException;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.lang.WrappedTargetException;
 import com.sun.star.uno.Exception;
 import com.sun.star.uno.UnoRuntime;
 import com.sun.star.uno.XComponentContext;
 
 public class DialogHelper {
 	
+	/**
+	 * Create a dialog from an xdl file.
+	 *
+	 * @param xdlFile
+	 *            The filename in the `dialog` folder
+	 * @param context
+	 * @return XDialog
+	 */
+	public static XDialog createDialog(String xdlFile, XComponentContext context, XDialogEventHandler handler) {
+		Object oDialogProvider;
+		try {
+			oDialogProvider = context.getServiceManager().createInstanceWithContext("com.sun.star.awt.DialogProvider2",
+					context);
+			XDialogProvider2 xDialogProv = (XDialogProvider2) UnoRuntime.queryInterface(XDialogProvider2.class,
+					oDialogProvider);
+			File dialogFile = FileHelper.getDialogFilePath(xdlFile, context);
+			return xDialogProv.createDialogWithHandler(convertToURL(context, dialogFile), handler);
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	/** Returns a URL to be used with XDialogProvider to create a dialog */
+	public static String convertToURL(XComponentContext xContext, File dialogFile) {
+		String sURL = null;
+		try {
+			com.sun.star.ucb.XFileIdentifierConverter xFileConverter = (com.sun.star.ucb.XFileIdentifierConverter) UnoRuntime
+					.queryInterface(com.sun.star.ucb.XFileIdentifierConverter.class, xContext.getServiceManager()
+							.createInstanceWithContext("com.sun.star.ucb.FileContentProvider", xContext));
+			sURL = xFileConverter.getFileURLFromSystemPath("", dialogFile.getAbsolutePath());
+		} catch (com.sun.star.uno.Exception ex) {
+			return null;
+		}
+		return sURL;
+	}
+
+	/** Returns a button (XButton) from a dialog */
+	public static XButton getButton(XDialog dialog, String componentId) {
+		XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
+				dialog);
+		Object control = xDlgContainer.getControl(componentId);
+		return (XButton) UnoRuntime.queryInterface(XButton.class, control);
+	}
+
+	/** Returns a text field (XTextComponent) from a dialog */
+	public static XTextComponent getEditField(XDialog dialog, String componentId) {
+		XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
+				dialog);
+		Object control = xDlgContainer.getControl(componentId);
+		return (XTextComponent) UnoRuntime.queryInterface(XTextComponent.class, control);
+	}
+
+	/** Returns a Combo box (XComboBox) from a dialog */
+	public static XComboBox getCombobox(XDialog dialog, String componentId) {
+		XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
+				dialog);
+		Object control = xDlgContainer.getControl(componentId);
+		return (XComboBox) UnoRuntime.queryInterface(XComboBox.class, control);
+	}
+	
+	/** Returns a List box (XListBox) from a dialog */
+	public static XListBox getListBox(XDialog dialog, String componentId) {
+		XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
+				dialog);
+		Object control = xDlgContainer.getControl(componentId);
+		return (XListBox) UnoRuntime.queryInterface(XListBox.class, control);
+	}
+
+	/** Returns a label (XFixedText) from a dialog */
+	public static XFixedText getLabel(XDialog dialog, String componentId) {
+		XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
+				dialog);
+		Object control = xDlgContainer.getControl(componentId);
+		return (XFixedText) UnoRuntime.queryInterface(XFixedText.class, control);
+	}
+
+	public static void EnableButton(XDialog dialog, String componentId, boolean enable) {
+		XControlContainer xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class,
+				dialog);
+		// retrieve the control that we want to disable or enable
+		XControl xControl = UnoRuntime.queryInterface(XControl.class, xDlgContainer.getControl(componentId));
+		XPropertySet xModelPropertySet = UnoRuntime.queryInterface(XPropertySet.class, xControl.getModel());
+		try {
+			xModelPropertySet.setPropertyValue("Enabled", Boolean.valueOf(enable));
+		} catch (IllegalArgumentException | UnknownPropertyException | PropertyVetoException
+				| WrappedTargetException e) {
+			return;
+		}
+	}
+	
+	/** Set the focus to an input field */
+	public static void SetFocus(XTextComponent editField) {
+		XWindow xControlWindow = UnoRuntime.queryInterface(XWindow.class, editField);
+		xControlWindow.setFocus();
+	}
+
+	public static void setPosition(XDialog dialog, int posX, int posY) {
+		XControlModel xDialogModel = UnoRuntime.queryInterface(XControl.class, dialog).getModel();
+		XPropertySet xPropSet = UnoRuntime.queryInterface(XPropertySet.class, xDialogModel);
+		try {
+			xPropSet.setPropertyValue("PositionX", posX);
+			xPropSet.setPropertyValue("PositionY", posY);
+		} catch (com.sun.star.lang.IllegalArgumentException | UnknownPropertyException | PropertyVetoException
+				| WrappedTargetException e) {
+			return;
+		}
+	}
+
+	public static Point getPosition(XDialog dialog) {
+		int posX = 0;
+		int posY = 0;
+		XControlModel xDialogModel = UnoRuntime.queryInterface(XControl.class, dialog).getModel();
+		XPropertySet xPropSet = UnoRuntime.queryInterface(XPropertySet.class, xDialogModel);
+		try {
+			posX = (int) xPropSet.getPropertyValue("PositionX");
+			posY = (int) xPropSet.getPropertyValue("PositionY");
+		} catch (UnknownPropertyException | WrappedTargetException e) {
+		}
+		return new Point(posX, posY);
+	}
+	
 	public static void showInfoMessage(XComponentContext context, XDialog dialog, String message) {
 		showMessageBox(context, dialog, MessageBoxType.INFOBOX, "Info", message);
 	}
diff --git a/source/org/libreoffice/example/helper/FileHelper.java b/source/org/libreoffice/example/helper/FileHelper.java
new file mode 100644
index 0000000..e9596a2
--- /dev/null
+++ b/source/org/libreoffice/example/helper/FileHelper.java
@@ -0,0 +1,59 @@
+package org.libreoffice.example.helper;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import com.sun.star.deployment.PackageInformationProvider;
+import com.sun.star.deployment.XPackageInformationProvider;
+import com.sun.star.uno.Exception;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.XURLTransformer;
+
+public class FileHelper {
+	
+	final static String DIALOG_RESOURCES = "dialog/";
+	
+	/**
+	 * Returns a path to a dialog file
+	 */
+	public static File getDialogFilePath(String xdlFile, XComponentContext xContext) {
+		return getFilePath(DIALOG_RESOURCES + xdlFile, xContext);
+	}
+	
+	/**
+	 * Returns a file path for a file in the installed extension, or null on failure.
+	 */
+	public static File getFilePath(String file, XComponentContext xContext) {
+		XPackageInformationProvider xPackageInformationProvider = PackageInformationProvider.get(xContext);
+        String location = xPackageInformationProvider.getPackageLocation("org.libreoffice.example.starterproject");
+        Object oTransformer;
+		try {
+			oTransformer = xContext.getServiceManager().createInstanceWithContext("com.sun.star.util.URLTransformer", xContext);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+        XURLTransformer xTransformer = (XURLTransformer)UnoRuntime.queryInterface(XURLTransformer.class, oTransformer);
+        com.sun.star.util.URL[] oURL = new com.sun.star.util.URL[1];
+        oURL[0] = new com.sun.star.util.URL();
+        oURL[0].Complete = location + "/" + file;
+        xTransformer.parseStrict(oURL);
+        URL url;
+        try {
+			url = new URL(oURL[0].Complete);
+		} catch (MalformedURLException e1) {
+			return null;
+		}
+        File f;
+		try {
+			f = new File(url.toURI());
+		} catch (URISyntaxException e1) {
+			return null;
+		}
+        return f;
+	}
+
+}