2022-05-22

72: Use Any Dialog from Non-Basic Macro or Non-Macro for LibreOffice/OpenOffice

<The previous article in this series | The table of contents of this series | The next article in this series>

Any dialog can be invoked and handled from non-Basic (Java, C++, C#, Python, etc.) macro or non-macro. Events can be received from the dialog.

Topics


About: UNO (Universal Network Objects)
About: LibreOffice
About: Apache OpenOffice
About: the Java programming language
About: C++
About: C#
About: the Python programming language

The table of contents of this article


Starting Context



Target Context


  • The reader will know how to invoke and handle any dialog and receive events from the dialog, from non-Basic macro or non-macro.

Orientation


There is an article on how to create any external UNO client in Java, C++, C#, or Python, in a just-connecting way.

There is an article on how to create any external UNO client in Java, C++, C#, or Python, in a connection-aware way.

There is an article on how to create any user/application-owned Python macro for LibreOffice/Apache OpenOffice.

There is an article on how to create any in-document Python macro for LibreOffice/Apache OpenOffice.

There is an article on how to create any LibreOffice/Apache OpenOffice extension that contains Python macros.

There is an article on using Python instead of Basic for LibreOffice/Apache OpenOffice.


Main Body

Stage Direction
Here are Special-Student-7, Lenard (a Python programmer), and Jane (a Python programmer) in front of a computer.


1: You Do Not Need Basic in Order to Use Dialogs


Special-Student-7
I frequently encourage you to use Python instead of Basic for LibreOffice or Apache OpenOffice, but some people may be thinking that they need to use Basic in order to use dialogs.

No, they do not need Basic for that.

Lenard
Oh? I thought they did. They are Basic dialogs, right?

Special-Student-7
No, they are not particularly Basic dialogs technically speaking, although they have been categorized misleadingly so.

Lenard
Dialogs are managed in the Basic IDE!

Jane
That squalid Basic IDE . . .

Special-Student-7
It is as though dialogs are exclusively for Basic, but no, they can be used from any UNO programming language, like Java, C++, C#, or Python.

Jane
It is good, because we Python people do not want to use Basic.


2: Designing Any Dialog


Special-Student-7
Probably, you will design a dialog with the Basic IDE.

Jane
That squalid Basic IDE . . .

Special-Student-7
In fact, the dialog design is stored in an XML file, which you can edit with your favorite text editor, but I usually do not expect you to edit it with a text editor from scratch.

Jane
Well, if the specifications are well-documented, I may try.

Special-Student-7
But if you know where the XML file is, you can copy it around, especially into your LibreOffice or Apache OpenOffice extension.

Lenard
Tell me where it is, now!

Special-Student-7
If you have created the dialog as user-owned, the XML file will be in the '~/.config/libreoffice/4/user/basic/%the library directory%' directory or a like in Linux or in the 'C:\Users\%the user directory%\Appdata\Roaming\LibreOffice\4\user\basic\%the library directory%' directory or a like in Microsoft Windows.

The 'dialog.xlb' file in the same directory is also needed with the contents possibly needed to be modified.

Lenard
How modified?

Special-Student-7
The dialog name needs to be appropriately set there.


3: Using the Dialog


Special-Student-7
Let us use the dialog from Java, C++, C#, and Python.

A UNO objects context to the office instance is supposed to have been gotten as 'l_underlyingRemoteUnoObjectsContextInXComponentContext'. If you are creating an external UNO client, there is an article on how to get it in Java (in a just-connecting way or in a connection-aware way), C++ (in a just-connecting way or in a connection-aware way), C# (in a just-connecting way or in a connection-aware way), or Python (in a just-connecting way or in a connection-aware way).


3-1: Getting a Dialogs Provider


Special-Student-7
1st, we need to get a dialogs provider.

In fact, how to do so depends on whether the dialogs are non-in-document or in-document.

This is how to do so for any non-in-document dialogs, in each programming language.

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

~
import com.sun.star.awt.XDialogProvider2;
~
import com.sun.star.uno.UnoRuntime;
~

public class Test1Test {
	~
	
	public static void main (String [] a_argumentsArray) {
		~
				~
				XDialogProvider2 l_underlyingUnoDialogProviderInXDialogProvider2 = UnoRuntime.queryInterface (XDialogProvider2.class, l_underlyingRemoteUnoObjectsContextInXComponentContext.getServiceManager ().createInstanceWithContext ("com.sun.star.awt.DialogProvider", l_underlyingRemoteUnoObjectsContextInXComponentContext));
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.hpp Start
~
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace dialogInvokingTest1 {
				class Test1Test {
					~
					public:
						static int main (int const & a_argumentsNumber, char const * const a_argumentsArray []);
				};
			}
		}
	}
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.hpp End

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start
#include <com/sun/star/awt/XDialogProvider2.hpp>
~
#include <com/sun/star/uno/Reference.hxx>
~
#include "theBiasPlanet/unoUtilities/stringsHandling/UnoExtendedStringHandler.hpp"
~
using namespace ::std;
~
using namespace ::com::sun::star::awt;
~
using namespace ::com::sun::star::uno;
~
using namespace ::theBiasPlanet::unoUtilities::stringsHandling;
~

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						~
						Reference <XDialogProvider2> l_underlyingUnoDialogProviderInXDialogProvider2 (l_underlyingRemoteUnoObjectsContextInXComponentContext->getServiceManager ()->createInstanceWithContext (UnoExtendedStringHandler::getOustring (string ("com.sun.star.awt.DialogProvider")), l_underlyingRemoteUnoObjectsContextInXComponentContext), UNO_QUERY);
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			using System;
			~
			using unoidl.com.sun.star.awt;
			~
			
			public class Test1Test {
				~
				public void main (String [] a_argumentsArray) {
					~
								~
								XDialogProvider2 l_underlyingUnoDialogProvider = (XDialogProvider2) (l_underlyingRemoteUnoObjectsContext.getServiceManager ().createInstanceWithContext ("com.sun.star.awt.DialogProvider", l_underlyingRemoteUnoObjectsContext));
				}
			}
		}
	}
}


@Python Source Code
from typing import cast
~
from com.sun.star.awt import XDialogProvider2
~

class Test1Test:
	~
	
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				l_underlyingUnoDialogProviderInXDialogProvider2: XDialogProvider2 = cast (XDialogProvider2, l_underlyingRemoteUnoObjectsContextInXComponentContext.getServiceManager ().createInstanceWithContext ("com.sun.star.awt.DialogProvider", l_underlyingRemoteUnoObjectsContextInXComponentContext))

This is how to do so for any in-document dialogs, in each programming language, where 'l_underlyingUnoDocumentInXModel' is the document UNO object in a 'com.sun.star.frame.XModel' UNO proxy, 'Standard' is the library name, and 'Test1Dialog' is the dialog name (yes, we have to get a dialogs provider per dialog type in this case).

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

~
import com.sun.star.awt.XDialogProvider2;
~
import com.sun.star.beans.XPropertySet;
~
import com.sun.star.container.XNameAccess;
import com.sun.star.container.XNameContainer;
~
import com.sun.star.io.XInputStreamProvider;
~
import com.sun.star.lang.EventObject;
~
import com.sun.star.lib.uno.helper.WeakBase;
~
import com.sun.star.reflection.InvocationTargetException;
import com.sun.star.script.ScriptEvent;
import com.sun.star.script.XLibraryContainer;
import com.sun.star.script.XScriptListener;
~
import com.sun.star.uno.UnoRuntime;
~

public class Test1Test {
	private static class UnoScriptListener extends WeakBase implements XScriptListener {
		@Override
		public void firing (ScriptEvent a_event) {
			System.out.println (String.format ("### UnoScriptListener.firing: %s", a_event));
		}
		
		@Override
		public Object approveFiring (ScriptEvent a_event) throws InvocationTargetException {
			System.out.println (String.format ("### UnoScriptListener.approveFiring: %s", a_event));
			return null;
		}
		
		@Override
		public void disposing (EventObject a_eventSource) {
			System.out.println (String.format ("### UnoScriptListener.disposing: %s", a_eventSource));
		}
	}
	
	~
	
	public static void main (String [] a_argumentsArray) {
		~
					~
					XDialogProvider2 l_underlyingUnoDialogProviderInXDialogProvider2 = null;
					~
					XNameAccess l_underlyingUnoDialogLibrariesInXNameAccess = UnoRuntime.queryInterface (XNameAccess.class, ( (com.sun.star.uno.Any) (UnoRuntime.queryInterface (XPropertySet.class, l_underlyingUnoDocumentInXModel).getPropertyValue ("DialogLibraries"))).getObject ());
					UnoRuntime.queryInterface (XLibraryContainer.class, l_underlyingUnoDialogLibrariesInXNameAccess).loadLibrary ("Standard");
					XNameAccess l_underlyingUnoDialogLibraryInXNameAccess = UnoRuntime.queryInterface (XNameAccess.class, ( (com.sun.star.uno.Any) l_underlyingUnoDialogLibrariesInXNameAccess.getByName ("Standard")).getObject ());
					XInputStreamProvider l_underlyingUnoDialogStreamInXInputStreamProvider = UnoRuntime.queryInterface (XInputStreamProvider.class, ( (com.sun.star.uno.Any) l_underlyingUnoDialogLibraryInXNameAccess.getByName ("Test1Dialog")).getObject ());
					Object [] l_unoServiceArguments = new Object [4];
					l_unoServiceArguments [0] = l_underlyingUnoDocumentInXModel;
					l_unoServiceArguments [1] = l_underlyingUnoDialogStreamInXInputStreamProvider.createInputStream ();
					l_unoServiceArguments [2] = UnoRuntime.queryInterface (XNameContainer.class, l_underlyingUnoDialogLibraryInXNameAccess);
					l_unoServiceArguments [3] = new UnoScriptListener ();
					l_underlyingUnoDialogProviderInXDialogProvider2 = UnoRuntime.queryInterface (XDialogProvider2.class, l_underlyingRemoteUnoObjectsContextInXComponentContext.getServiceManager ().createInstanceWithArgumentsAndContext ("com.sun.star.awt.DialogProvider", l_unoServiceArguments, l_underlyingRemoteUnoObjectsContextInXComponentContext));
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.hpp Start

	#include <cppuhelper/compbase1.hxx>
	~
	#include <com/sun/star/lang/EventObject.hpp>
	~
	#include <com/sun/star/script/XScriptListener.hpp>
	~
	using namespace ::cppu;
	~
	using namespace ::com::sun::star::script;
	~
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace dialogInvokingTest1 {
				class Test1Test {
					private:
						class UnoScriptListener: public WeakImplHelper1 <XScriptListener> {
							public:
								void firing (ScriptEvent const & a_event) override;
								Any approveFiring (ScriptEvent const & a_event) override;
								void disposing (::com::sun::star::lang::EventObject const & a_eventSource) override;
						};
						~
					public:
						static int main (int const & a_argumentsNumber, char const * const a_argumentsArray []);
				};
			}
		}
	}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.hpp End

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start

#include "theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.hpp"
#include <string>
#include <com/sun/star/awt/XDialogProvider2.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/io/XInputStreamProvider.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/script/XScriptListener.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Reference.hxx>
~
#include "theBiasPlanet/unoUtilities/stringsHandling/UnoExtendedStringHandler.hpp"
~

using namespace ::std;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::uno;
~
using namespace ::theBiasPlanet::unoUtilities::stringsHandling;
~

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
							~
							Reference <XNameAccess> l_underlyingUnoDialogLibrariesInXNameAccess (* ( (Reference <XInterface> *) (Reference <XPropertySet> (l_underlyingUnoDocumentInXModel, UNO_QUERY)->getPropertyValue (UnoExtendedStringHandler::getOustring (string ("DialogLibraries"))).getValue ())), UNO_QUERY);
							Reference <XLibraryContainer> (l_underlyingUnoDialogLibrariesInXNameAccess, UNO_QUERY)->loadLibrary (UnoExtendedStringHandler::getOustring (string ("Standard")));
							Reference <XNameAccess> l_underlyingUnoDialogLibraryInXNameAccess (* ( (Reference <XInterface> *) l_underlyingUnoDialogLibrariesInXNameAccess->getByName (UnoExtendedStringHandler::getOustring (string ("Standard"))).getValue ()), UNO_QUERY);
							Reference <XInputStreamProvider> l_underlyingUnoDialogStreamInXInputStreamProvider (* ( (Reference <XInterface> *) l_underlyingUnoDialogLibraryInXNameAccess->getByName (UnoExtendedStringHandler::getOustring (string ("Test1Dialog"))).getValue ()), UNO_QUERY);
							Sequence <Any> l_unoServiceArguments (4);
							l_unoServiceArguments [0] = Any (l_underlyingUnoDocumentInXModel);
							l_unoServiceArguments [1] = Any (l_underlyingUnoDialogStreamInXInputStreamProvider->createInputStream ());
							l_unoServiceArguments [2] = Any (Reference <XNameContainer> (l_underlyingUnoDialogLibraryInXNameAccess, UNO_QUERY));
							l_unoServiceArguments [3] = Any (Reference <XScriptListener> (new UnoScriptListener ()));
							Reference <XDialogProvider2> l_underlyingUnoDialogProviderInXDialogProvider2 (l_underlyingRemoteUnoObjectsContextInXComponentContext->getServiceManager ()->createInstanceWithArgumentsAndContext (UnoExtendedStringHandler::getOustring (string ("com.sun.star.awt.DialogProvider")), l_unoServiceArguments, l_underlyingRemoteUnoObjectsContextInXComponentContext), UNO_QUERY);
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			using System;
			~
			using unoidl.com.sun.star.awt;
			using unoidl.com.sun.star.beans;
			using unoidl.com.sun.star.container;
			using unoidl.com.sun.star.io;
			~
			using unoidl.com.sun.star.script;
			using unoidl.com.sun.star.uno;
			~
			public class Test1Test {
				private class UnoScriptListener: WeakBase, XScriptListener {
					public void firing (ScriptEvent a_event) {
						Console.Out.WriteLine (String.Format ("### UnoScriptListener.firing: %s", a_event));
					}
					
					public uno.Any approveFiring (ScriptEvent a_event) {
						Console.Out.WriteLine (String.Format ("### UnoScriptListener.approveFiring: %s", a_event));
						return new uno.Any ();
					}
					
					public void disposing (EventObject a_eventSource) {
						Console.Out.WriteLine (String.Format ("### UnoScriptListener.disposing: %s", a_eventSource));
					}
				}
				~
				public void main (String [] a_argumentsArray) {
					~
								~
								XDialogProvider2 l_underlyingUnoDialogProviderInXDialogProvider2 = null;
								~
									XNameAccess l_underlyingUnoDialogLibrariesInXNameAccess = (XNameAccess) ( (uno.Any) ( (XPropertySet) (l_underlyingUnoDocumentInXModel)).getPropertyValue ("DialogLibraries")).Value;
									( (XLibraryContainer) l_underlyingUnoDialogLibrariesInXNameAccess).loadLibrary ("Standard");
									XNameAccess l_underlyingUnoDialogLibraryInXNameAccess = (XNameAccess) ( (uno.Any) l_underlyingUnoDialogLibrariesInXNameAccess.getByName ("Standard")).Value;
									XInputStreamProvider l_underlyingUnoDialogStreamInXInputStreamProvider = (XInputStreamProvider) ( (uno.Any) l_underlyingUnoDialogLibraryInXNameAccess.getByName ("Test1Dialog")).Value;
									uno.Any [] l_unoServiceArguments = new uno.Any [4];
									l_unoServiceArguments [0] = new uno.Any (l_underlyingUnoDocumentInXModel.GetType (), l_underlyingUnoDocumentInXModel);
									l_unoServiceArguments [1] = new uno.Any (l_underlyingUnoDocumentInXModel.GetType (), l_underlyingUnoDialogStreamInXInputStreamProvider.createInputStream ());
									l_unoServiceArguments [2] = new uno.Any (l_underlyingUnoDocumentInXModel.GetType (), (XNameContainer) l_underlyingUnoDialogLibraryInXNameAccess);
									l_unoServiceArguments [3] = new uno.Any (l_underlyingUnoDocumentInXModel.GetType (), new UnoScriptListener ());
									l_underlyingUnoDialogProviderInXDialogProvider2 = (XDialogProvider2) l_underlyingRemoteUnoObjectsContextInXComponentContext.getServiceManager ().createInstanceWithArgumentsAndContext ("com.sun.star.awt.DialogProvider", l_unoServiceArguments, l_underlyingRemoteUnoObjectsContextInXComponentContext);
				}
			}
		}
	}
}


@Python Source Code
from typing import cast
~
from com.sun.star.awt import XDialogProvider2
~
from com.sun.star.container import XNameAccess
from com.sun.star.container import XNameContainer
~
from com.sun.star.io import XInputStreamProvider
from com.sun.star.lang import EventObject
from com.sun.star.script import ScriptEvent
from com.sun.star.script import XLibraryContainer
from com.sun.star.script import XScriptListener
~
from uno import Any as UnoAny

class Test1Test:
	class UnoScriptListener (UnoBase, XScriptListener):
		def firing (a_this: "Test1Test.UnoScriptListener", a_event: ScriptEvent)-> None:
			sys.stdout.write ("### UnoScriptListener.firing: {0:s}\n".format (str (a_event)))
			sys.stdout.flush ()
		
		def approveFiring (a_this: "Test1Test.UnoScriptListener", a_event: ScriptEvent)-> object:
			sys.stdout.write ("### UnoScriptListener.approveFiring: {0:s}\n".format (str (a_event)))
			sys.stdout.flush ()
			return None
		
		def disposing (a_this: "Test1Test.UnoScriptListener", a_eventSource: EventObject)-> None:
			None
	~
	
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				l_underlyingUnoDialogProviderInXDialogProvider2: XDialogProvider2 = None
				~
					l_underlyingUnoDialogLibrariesInXNameAccess: XNameAccess = cast (XNameAccess, cast (XPropertySet, l_underlyingUnoDocumentInXModel).getPropertyValue ("DialogLibraries"))
					cast (XLibraryContainer, l_underlyingUnoDialogLibrariesInXNameAccess).loadLibrary ("Standard")
					l_underlyingUnoDialogLibraryInXNameAccess: XNameAccess = cast (XNameAccess, l_underlyingUnoDialogLibrariesInXNameAccess.getByName ("Standard"))
					l_underlyingUnoDialogStreamInXInputStreamProvider: XInputStreamProvider = cast (XInputStreamProvider, l_underlyingUnoDialogLibraryInXNameAccess.getByName ("Test1Dialog"))
					l_unoServiceArguments: List [object] = [None] * 4
					l_unoServiceArguments [0] = l_underlyingUnoDocumentInXModel
					l_unoServiceArguments [1] = l_underlyingUnoDialogStreamInXInputStreamProvider.createInputStream ()
					l_unoServiceArguments [2] = cast (XNameContainer, l_underlyingUnoDialogLibraryInXNameAccess)
					l_unoServiceArguments [3] = Test1Test.UnoScriptListener ()
					l_underlyingUnoDialogProviderInXDialogProvider2 = cast (XDialogProvider2, l_underlyingRemoteUnoObjectsContextInXComponentContext.getServiceManager ().createInstanceWithArgumentsAndContext ("com.sun.star.awt.DialogProvider", l_unoServiceArguments, l_underlyingRemoteUnoObjectsContextInXComponentContext))


3-2: Instantiating the Dialog


Special-Student-7
Let us instantiate the dialog in each programming language.

Again, how to do so depends on whether the dialogs are non-in-document or in-document.

This is how to do so for any non-in-document dialogs, in each programming language, where 'Standard' is the library name and 'Test1Dialog' is the dialog name.

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

~
import com.sun.star.awt.XDialog;
~

public class Test1Test {
	~
	public static void main (String [] a_argumentsArray) {
		~
				~
				XDialog l_underlyingUnoDialogInXDialog = l_underlyingUnoDialogProviderInXDialogProvider2.createDialog ("vnd.sun.star.script:Standard.Test1Dialog?language=Basic&location=application");
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start

#include <com/sun/star/awt/XDialog.hpp>
~

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						~
						Reference <XDialogProvider2> l_underlyingUnoDialogProviderInXDialogProvider2 (l_underlyingRemoteUnoObjectsContextInXComponentContext->getServiceManager ()->createInstanceWithContext (UnoExtendedStringHandler::getOustring (string ("com.sun.star.awt.DialogProvider")), l_underlyingRemoteUnoObjectsContextInXComponentContext), UNO_QUERY);
						Reference <XDialog> l_underlyingUnoDialogInXDialog (l_underlyingUnoDialogProviderInXDialogProvider2->createDialog (UnoExtendedStringHandler::getOustring (string ("vnd.sun.star.script:Standard.Test1Dialog?language=Basic&location=application"))));
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			
			public class Test1Test {
				~
				public void main (String [] a_argumentsArray) {
					~
								~
								XDialog l_underlyingUnoDialog = l_underlyingUnoDialogProvider.createDialog ("vnd.sun.star.script:Standard.Test1Dialog?language=Basic&location=application");
				}
			}
		}
	}
}

@Python Source Code
from com.sun.star.awt import XDialog
~

class Test1Test:
	~
	
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				l_underlyingUnoDialogInXDialog: XDialog = l_underlyingUnoDialogProviderInXDialogProvider2.createDialog ("vnd.sun.star.script:Standard.Test1Dialog?language=Basic&location=application")

This is how to do so for any in-document dialogs, in each programming language, where the library name or the dialog name is not specified, because they are already determined for the dialogs provider.

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

~
import com.sun.star.awt.XDialog;
~

public class Test1Test {
	~
	public static void main (String [] a_argumentsArray) {
		~
				~
				XDialog l_underlyingUnoDialogInXDialog = null;
				~
					~
					l_underlyingUnoDialogInXDialog = l_underlyingUnoDialogProviderInXDialogProvider2.createDialog ("");
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start

#include <com/sun/star/awt/XDialog.hpp>
~

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						~
						Reference <XDialog> l_underlyingUnoDialogInXDialog;
						~
							l_underlyingUnoDialogInXDialog.set (l_underlyingUnoDialogProviderInXDialogProvider2->createDialog (UnoExtendedStringHandler::getOustring (string (""))));
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			
			public class Test1Test {
				~
				public void main (String [] a_argumentsArray) {
					~
								~
								XDialog l_underlyingUnoDialogInXDialog = null;
								~
									l_underlyingUnoDialogInXDialog = l_underlyingUnoDialogProviderInXDialogProvider2.createDialog ("");
				}
			}
		}
	}
}

@Python Source Code
from com.sun.star.awt import XDialog
~

class Test1Test:
	~
	
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				l_underlyingUnoDialogInXDialog: XDialog = None
				~
					l_underlyingUnoDialogInXDialog = l_underlyingUnoDialogProviderInXDialogProvider2.createDialog ("");

Jane
Well, "vnd.sun.star.script:Standard.Test1Dialog?language=Basic&location=application" is the URL of the dialog.


3-3: Handling the Dialog


Special-Student-7
"l_underlyingUnoDialogInXDialog" represents the dialog instance, and you can handle the dialog instance via it.

Usually, you will want to handle some controls on the dialog.

Any control can be gotten like this, where "TextField1" is the control name.

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

~
import com.sun.star.awt.XControl;
import com.sun.star.awt.XControlContainer;
~

public class Test1Test {
	~
	public static void main (String [] a_argumentsArray) {
		~
				~
				XControl l_underlyingUnoControlInXControl = null;
				~
				l_underlyingUnoControlInXControl = UnoRuntime.queryInterface (XControlContainer.class, l_underlyingUnoDialogInXDialog).getControl ("TextField1");
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start

#include <com/sun/star/awt/XControl.hpp>
#include <com/sun/star/awt/XControlContainer.hpp>
~

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						~
						Reference <XControl> l_underlyingUnoControlInXControl;
						~
						l_underlyingUnoControlInXControl = Reference <XControlContainer> (l_underlyingUnoDialogInXDialog, UNO_QUERY)->getControl ("TextField1");
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			
			public class Test1Test {
				~
				public void main (String [] a_argumentsArray) {
					~
								~
								XControl l_underlyingUnoControl = null;
								~
								l_underlyingUnoControl = ( (XControlContainer) l_underlyingUnoDialog).getControl ("TextField1");
				}
			}
		}
	}
}

@Python Source Code
from com.sun.star.awt import XControl
from com.sun.star.awt import XControlContainer
~

class Test1Test:
	~
	
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				l_underlyingUnoControlInXControl: XControl = None
				~
				l_underlyingUnoControlInXControl = (cast (XControlContainer, l_underlyingUnoDialogInXDialog)).getControl ("TextField1")

The control has implemented some UNO interfaces depending on what kind of control it is.

For example, any 'TextField' control has implemented these UNO interfaces: 'com.sun.star.awt.XControl', 'com.sun.star.awt.XWindow2', 'com.sun.star.awt.XView', 'com.sun.star.beans.XPropertiesChangeListener', 'com.sun.star.lang.XServiceInfo', 'com.sun.star.accessibility.XAccessible', 'com.sun.star.util.XModeChangeBroadcaster', 'com.sun.star.awt.XUnitConversion', 'com.sun.star.awt.XStyleSettingsSupplier', 'com.sun.star.lang.XTypeProvider', 'com.sun.star.uno.XWeak', 'com.sun.star.uno.XAggregation', 'com.sun.star.awt.XTextComponent', 'com.sun.star.awt.XTextListener', 'com.sun.star.awt.XLayoutConstrains', 'com.sun.star.awt.XTextLayoutConstrains', and 'com.sun.star.lang.XTypeProvider'.

Jane
So, I can handle each control via the UNO interfaces.

Special-Student-7
For example, this gets and sets the contents of a 'TextField' control.

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

~
import com.sun.star.awt.XTextComponent;
~

public class Test1Test {
	~
	public static void main (String [] a_argumentsArray) {
		~
				~
				UnoRuntime.queryInterface (XTextComponent.class, l_underlyingUnoControlInXControl).setText ("Hi, bro!");
				System.out.println (String.format ("### TextField1 text: %s", UnoRuntime.queryInterface (XTextComponent.class, l_underlyingUnoControlInXControl).getText ()));
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start

#include <com/sun/star/awt/XTextComponent.hpp>
~

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						~
						Reference <XTextComponent> (l_underlyingUnoControlInXControl, UNO_QUERY)->setText (UnoExtendedStringHandler::getOustring (string ("Hi, bro!")));
						cout << "### TextField1 text: " << UnoExtendedStringHandler::getString (Reference <XTextComponent> (l_underlyingUnoControlInXControl, UNO_QUERY)->getText ()) << endl << flush;
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			
			public class Test1Test {
				~
				public void main (String [] a_argumentsArray) {
					~
								~
								( (XTextComponent) l_underlyingUnoControl).setText ("Hi, bro!");
								Console.Out.WriteLine (String.format ("### TextField1 text: {0:s}", ( (XTextComponent) l_underlyingUnoControl).getText ()));
				}
			}
		}
	}
}

@Python Source Code
from com.sun.star.uno import XComponentContext
~

class Test1Test:
	~
	
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				(cast (XTextComponent, l_underlyingUnoControlInXControl)).setText ("Hi, bro!")
				sys.stdout.write ("### TextField1 text: {0:s}\n".format ( (cast (XTextComponent, l_underlyingUnoControlInXControl)).getText ()))

Lenard
That looks easy, but you have chosen an easy example.

How can I set the contents of a control of another kind, for example, an 'Image' control?

Special-Student-7
As this article is about the basics of using dialogs, such details of various kinds of controls will be studied in the next article.

Lenard
Will also 'Option Button' be studied?

Special-Student-7
It will.

Lenard
Also 'Tree Control'?

Special-Student-7
Yes.

Lenard
Also 'File Selection'?

Special-Student-7
. . . All the kinds of controls shown in the Basic IDE will be handled in some typical ways, probably.


3-4: Registering Events Listeners into the Dialog


Jane
Just handling a control actively isn't enough, you know; my program has to receive events.

Special-Student-7
I know; you can register an events listener via a UNO interface like 'com.sun.star.awt.XButton' implemented by the control.

For example, this registers an actions listener into a 'Button' control.

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

import com.sun.star.awt.ActionEvent;
~
import com.sun.star.awt.XActionListener;
~
import com.sun.star.awt.XButton;
~
import com.sun.star.lang.EventObject;
~
import com.sun.star.lib.uno.helper.WeakBase;
~

public class Test1Test {
	~
	private static class UnoButtonEventsListener extends WeakBase implements XActionListener {
		@Override
		public void actionPerformed (ActionEvent a_event) {
			System.out.println (String.format ("### UnoButtonEventsListener.actionPerformed: %s", a_event));
		}
		
		@Override
		public void disposing (EventObject a_eventSource) {
		}
	}
	~
	public static void main (String [] a_argumentsArray) {
		~
				~
				UnoButtonEventsListener l_unoButtonEventsListener = new UnoButtonEventsListener ();
				~
				UnoRuntime.queryInterface (XButton.class, l_underlyingUnoControlInXControl).addActionListener (l_unoButtonEventsListener);
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.hpp Start

	#include <cppuhelper/compbase1.hxx>
	#include <com/sun/star/awt/ActionEvent.hpp>
	~
	#include <com/sun/star/awt/XActionListener.hpp>
	~
	#include <com/sun/star/lang/EventObject.hpp>
	~
	using namespace ::cppu;
	~
	using namespace ::com::sun::star::lang;
	~
	namespace theBiasPlanet {
		namespace unoUtilitiesTests {
			namespace dialogInvokingTest1 {
				class Test1Test {
						~
						class UnoButtonEventsListener: public WeakImplHelper1 <XActionListener> {
							public:
								void actionPerformed (ActionEvent const & a_event) override;
								void disposing (EventObject const & a_eventSource) override;
						};
						~
				};
			}
		}
	}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.hpp End

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start

#include <com/sun/star/awt/XButton.hpp>
~

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			void Test1Test::UnoButtonEventsListener::actionPerformed (ActionEvent const & a_event) {
				cout << string ("### UnoButtonEventsListener.actionPerformed: ") << a_event.ActionCommand << endl << flush;
			}
			
			void Test1Test::UnoButtonEventsListener::disposing (EventObject const & a_eventSource) {
			}
			
			~
			
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						~
						Reference <XActionListener> l_unoButtonEventsListener (new UnoButtonEventsListener ());
						~
						Reference <XButton> (l_underlyingUnoControlInXControl, UNO_QUERY)->addActionListener (l_unoButtonEventsListener);
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			using uno;
			~
			using unoidl.com.sun.star.lang;
			~
			
			public class Test1Test {
				~
				
				private class UnoButtonEventsListener: WeakBase, XActionListener {
					public void actionPerformed (ActionEvent a_event) {
						Console.Out.WriteLine (String.Format ("### UnoButtonEventsListener.actionPerformed: {0:s}", a_event));
					}
					
					public void disposing (EventObject a_eventSource) {
					}
				}
				
				~
				
				public void main (String [] a_argumentsArray) {
					~
								~
								UnoButtonEventsListener l_unoButtonEventsListener = new UnoButtonEventsListener ();
								~
								( (XButton) l_underlyingUnoControl).addActionListener (l_unoButtonEventsListener);
				}
			}
		}
	}
}

@Python Source Code
from unohelper import Base as UnoBase
from com.sun.star.awt import ActionEvent
~
from com.sun.star.awt import XActionListener
from com.sun.star.awt import XButton
~
from com.sun.star.lang import EventObject
~

class Test1Test:
	~
	class UnoButtonEventsListener (UnoBase, XActionListener):
		def actionPerformed (a_this: "Test1Test.UnoButtonEventsListener", a_event: ActionEvent)-> None:
			sys.stdout.write ("### UnoButtonEventsListener.actionPerformed: {0:s}\n".format (str (a_event)))
			sys.stdout.flush ()
		
		def disposing (a_this: "Test1Test.UnoButtonEventsListener", a_eventSource: EventObject)-> None:
			None
	~
	
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				l_unoButtonEventsListener: "Test1Test.UnoButtonEventsListener" = Test1Test.UnoButtonEventsListener ()
				~
				(cast (XButton, l_underlyingUnoControlInXControl)).addActionListener (l_unoButtonEventsListener)


3-5: Showing the Dialog


Special-Student-7
We have instantiated the dialog, but the instance is not shown yet.

This shows the instance.

@Java Source Code
package theBiasPlanet.unoUtilitiesTests.dialogInvokingTest1;

~

public class Test1Test {
	~
	public static void main (String [] a_argumentsArray) {
		~
				~
				l_underlyingUnoDialogInXDialog.execute ();
	}
}

@C++ Source Code
// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp Start

namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			int Test1Test::main (int const & a_argumentsNumber, char const * const a_argumentsArray []) {
				~
						~
						l_underlyingUnoDialogInXDialog->execute ();
			}
		}
	}
}

// theBiasPlanet/unoUtilitiesTests/dialogInvokingTest1/Test1Test.cpp End

@C# Source Code
namespace theBiasPlanet {
	namespace unoUtilitiesTests {
		namespace dialogInvokingTest1 {
			~
			
			public class Test1Test {
				~
				public void main (String [] a_argumentsArray) {
					~
								l_underlyingUnoDialog.execute ();
				}
			}
		}
	}
}


@Python Source Code
~

class Test1Test:
	~
	@staticmethod
	def main (a_arguments: List [str]) -> None:
		~
				~
				l_underlyingUnoDialogInXDialog.execute ()

Lenard
It's good actually! I don't need Basic any more!


4: If Dialog Is Too Poor for You


Jane
It's good indeed, but the dialogs functionality is not so rich.

Special-Student-7
If the dialogs functionality is too poor for you, a way is to use Java Swing.

Jane
We are not Java programmers, you know.

Special-Student-7
I know, but Python GUIs systems will not be able to be used directly from any Python macro, as far as I know.

Jane
When you say "directly" . . .

Special-Student-7
You can always invoke an external Python process that shows GUIs.

Jane
But the macro can't handle the GUIs or listen to events, that way, can it?

Special-Student-7
It is possible by relaying requests and events via UNO, but the problem is that the GUIs cannot be guaranteed to be shown over the office GUI.

Jane
Ah, the GUIs may be shown under the office GUI, invisible to eyes.

Special-Student-7
On the other hand, Java Swing can be used directly from the office JVM.

Jane
Why can't Python GUIs be used directly from any Python macro?

Special-Student-7
That is because the Python GUIs system events loop interferes with the office events loop.

Jane
Why only Python GUIs systems?

Special-Student-7
It is rather that only Java Swing does not interfere with the office events loop.

Jane
Anyway, what are you telling us to do? We are not Java programmers!

Special-Student-7
What I am saying is that if you can prepare or make a Java programmer prepare a GUI in a Java UNO component in the office JVM, your Python macro can use it via UNO.

Jane
Can my Python macro receive events?

Special-Student-7
Yes, it can.

Jane
Hmm . . .

Special-Student-7
Let us see that contrivance in a future article.

Jane
How about that "invoke an external Python process that shows GUIs" thing?

Special-Student-7
Let us see also that contrivance in a future article.


References


<The previous article in this series | The table of contents of this series | The next article in this series>