Playing with Window Toolkit AWT

From Apache OpenOffice Wiki
Jump to: navigation, search

Edit-find-replace.png This article needs to be checked for accuracy and style.

Documentation note.png This chapter is old : written long before discovering the new Dialog for components in Developer's Guide. At the moment I have only managed such Dialogs in components but I hope to work and see if it is not possible to use them in binaries executable.

Danny Brewer's Explanations

There are two different things here. Actually three.

  1. Dialogs
  2. AWT
  3. Forms

Forms are much higher level than the other two.

Of the first two, Dialogs are something using the UnoDialogControl and its model. You can also create AWT windows with controls.

AWT windows are modeless, and are not tied to any other window.

AWT windows are not the same thing as dialogs.

Generally, dialogs are operated modally by calling execute() on the dialog.

I have also had some success with operating dialogs modelessly. Just unhide the dialog, and it can be used modelessly. One drawback is that the modeless dialog seems to be tied to some concept of a "parent" window. I'm not sure, but I think that tends to be whatever window was in front when you created the dialog. So for example, you could create a modeless dialog that allows you to work with your document, but that modeless dialog's behavior appears to be tied to that document. Bring the modeless dialog to the front, and its document also comes to the front.

The MessageBox Windows

The starting code is roughly the same as previously (examples/DevelopersGuide/ProfUNO/CppBinding/). We examine also the “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/Addons/ProtocolHandlerAddon_cpp” example where we find a MessageBox window. The corresponding code is given here (see also com.sun.star.awt.XWindowPeer, com.sun.star.awt.XMessageBox, com.sun.star.frame.XFrame, com.sun.star.awt.XToolkit interfaces and com.sun.star.awt.WindowDescriptor structure and com.sun.star.awt.WindowAttribute constants ) :

//Listing 1 MessageBox Windows (deprecated)
// C++
// Don't forget to add : #include <com/sun/star/awt/WindowDescriptor.hpp>
// Don't forget to add "com.sun.star.awt.WindowDescriptor \" in the makefile
// Don't forget to add : #include <com/sun/star/awt/WindowAttribute.hpp>
// Don't forget to add "com.sun.star.awt.WindowAttribute \" in the makefile
// Don't forget to add : #include <com/sun/star/awt/XWindowPeer.hpp>
// Don't forget to add "com.sun.star.awt.XWindowPeer \" in the makefile
// Don't forget to add : #include <com/sun/star/awt/XMessageBox.hpp>
// Don't forget to add "com.sun.star.awt.XMessageBox \" in the makefile
 
/**
  * Show a message box with the UNO based toolkit
  */
static void ShowMessageBox( const Reference< XToolkit >& rToolkit, 
               const Reference< XFrame >& rFrame, const OUString& aTitle, const OUString& aMsgText )
{
    if ( rFrame.is() && rToolkit.is() )
    {
        // describe window properties.
        WindowDescriptor                aDescriptor;
        aDescriptor.Type              = WindowClass_MODALTOP;
        aDescriptor.WindowServiceName = OUString( RTL_CONSTASCII_USTRINGPARAM( "infobox" ));
        aDescriptor.ParentIndex       = -1;
        aDescriptor.Parent            = Reference< XWindowPeer >
						( rFrame->getContainerWindow(), UNO_QUERY );
        aDescriptor.Bounds            = Rectangle(300,200,300,200);
        aDescriptor.WindowAttributes  = WindowAttribute::BORDER | 
                                          WindowAttribute::MOVEABLE | WindowAttribute::CLOSEABLE;
 
        Reference< XWindowPeer > xPeer = rToolkit->createWindow( aDescriptor );
        if ( xPeer.is() )
        {
            Reference< XMessageBox > xMsgBox( xPeer, UNO_QUERY );
            if ( xMsgBox.is() )
            {
                xMsgBox->setCaptionText( aTitle );
                xMsgBox->setMessageText( aMsgText );
                xMsgBox->execute();
            }
        }
    }
}

Similar script in PyUNO from the Python Samples included in <openoffice.org version>/share/Scripts/python/MsgBox.py:

from com.sun.star.awt import Rectangle
from com.sun.star.awt import WindowDescriptor
 
from com.sun.star.awt.WindowClass import MODALTOP
from com.sun.star.awt.VclWindowPeerAttribute import OK, OK_CANCEL, YES_NO, YES_NO_CANCEL, \
                              RETRY_CANCEL, DEF_OK, DEF_CANCEL, DEF_RETRY, DEF_YES, DEF_NO
 
def TestMessageBox():
	doc = XSCRIPTCONTEXT.getDocument()
	parentwin = doc.CurrentController.Frame.ContainerWindow
 
	s = "This is a test"
	t = "Test"
	res = MessageBox(parentwin, s, t, "querybox", YES_NO_CANCEL + DEF_NO)
 
	s = res
	MessageBox(parentwin, s, t, "infobox")
 
 
 
# Show a message box with the UNO based toolkit
def MessageBox(ParentWin, MsgText, MsgTitle, MsgType="messbox", MsgButtons=OK):
 
	MsgType = MsgType.lower()
 
	#available msg types
	MsgTypes = ("messbox", "infobox", "errorbox", "warningbox", "querybox")
 
	if MsgType not in MsgTypes:
		MsgType = "messbox"
 
	#describe window properties.
	aDescriptor = WindowDescriptor()
	aDescriptor.Type = MODALTOP
	aDescriptor.WindowServiceName = MsgType
	aDescriptor.ParentIndex = -1
	aDescriptor.Parent = ParentWin
	#aDescriptor.Bounds = Rectangle()
	aDescriptor.WindowAttributes = MsgButtons
 
	tk = ParentWin.getToolkit()
	msgbox = tk.createWindow(aDescriptor)
 
	msgbox.setMessageText(MsgText)
	if MsgTitle :
		msgbox.setCaptionText(MsgTitle)
 
	return msgbox.execute()
 
 
g_exportedScripts = TestMessageBox,


To understand the WindowAttribute::BORDER and other constants, we first have a look at the IDL file “WindowAttribute.idl” describing the windows' attributes (com.sun.star.awt.WindowAttribute) :

//Listing 2 WindowAttribute IDL File 
// IDL
module com {  module sun {  module star {  module awt {
constants WindowAttribute
{
	const long SHOW = 1; 
	const long FULLSIZE = 2; 
	const long OPTIMUMSIZE = 4; 
	const long MINSIZE = 8; 
	const long BORDER = 16; 
	const long SIZEABLE = 32; 
	const long MOVEABLE = 64; 
	const long CLOSEABLE = 128; 
	const long SYSTEMDEPENDENT = 256;  
};
}; }; }; };

We have a look at com.sun.star.awt.XMessageBox IDL file :

//Listing 3 XMessageBox Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
/** gives access to a message box.
    @deprecated
 */
interface XMessageBox: com::sun::star::uno::XInterface
{
	[oneway] void setCaptionText( [in] string aText );
	string getCaptionText();
	[oneway] void setMessageText( [in] string aText );
	string getMessageText();
	short execute();
};
}; }; }; };

where we learn this interface is deprecated. We give now a complete main in a listing to learn how to use the previous ShowMessageBox procedure :

//Listing 4 Complete Program showing a Message Box Window
//C++
int main( ) {
//retrieve an instance of the remote service manager
    Reference< XMultiServiceFactory > rOfficeServiceManager;
    rOfficeServiceManager = ooConnect();
    if( rOfficeServiceManager.is() ){
        printf( "Connected sucessfully to the office\n" );
    }
 
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//query for the XComponentLoader interface
    Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
    if( rComponentLoader.is() ){
        	printf( "XComponentloader successfully instanciated\n" );
    	}
// Don't forget to add : #include <com/sun/star/awt/XToolkit.hpp>
// Don't forget to add "com.sun.star.awt.XToolkit \" in the makefile
// Query the XTollkit Interface
	Reference< XToolkit >rToolkit = Reference< XToolkit >
		( rOfficeServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "com.sun.star.awt.Toolkit" ))), UNO_QUERY );
 
	if (rToolkit.is()) {
	  printf ("OK...\n");
	} else printf("Toolkit Error\n");
 
	Reference< XDesktop > rDesktop(Desktop,UNO_QUERY);
	Reference< XFrame > rFrame=rDesktop->getCurrentFrame();
	if (rFrame.is()) printf("rFrame ... OK\n"); else printf("rFrame Error\n");
 
	ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Hello") ,
				OUString::createFromAscii("Your First Message\n OK ?")  );
 
    return 0;
}

(See also com.sun.star.awt.XToolkit interface and com.sun.star.awt.Toolkit service). We can draw three important things from this code :

  • the way we can use such an IDL file (given above) with constants in C++ : it's not the first time we encounter this kind of IDL file,
  • the way we can access an interface through a service with a createInstance and UNO_QUERY simultaneously (see how do we obtain rToolkit)
  • we see also how we obtain a frame from a com.sun.star.frame.Desktop service.

We will present later a Desktop Helper using this message box code. (See here)

A very simple Window

We give now a listing to construct a very simple windows using UNO toolkit (See also com.sun.star.awt.XToolkit , com.sun.star.frame.XFrame and com.sun.star.frame.XDesktop interfaces) :

//Listing 5 Constructing a simple Window
// C++
main( ) {
    Reference< XMultiServiceFactory > rOfficeServiceManager;
    rOfficeServiceManager = ooConnect();
 
    if( rOfficeServiceManager.is() ){
        printf( "Connected sucessfully to the office\n" );
    }
 
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//query for the XComponentLoader interface
    Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
    if( rComponentLoader.is() ){
        	printf( "XComponentloader successfully instanciated\n" );
 
    	}
 
// Don't forget to add : #include <com/sun/star/awt/XToolkit.hpp>
// Don't forget to add "com.sun.star.awt.XToolkit \" in the makefile
// Query the XTollkit Interface
	Reference< XToolkit >rToolkit = Reference< XToolkit >( rOfficeServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "com.sun.star.awt.Toolkit" ))), UNO_QUERY );
 
	if (rToolkit.is()) {
	  printf ("OK...\n");
	} else printf("Toolkit Error\n");
 
	Reference< XDesktop > rDesktop(Desktop,UNO_QUERY);
 
// *** essai fenetre
	if ( rToolkit.is() )
    	{
        // describe window properties.
        WindowDescriptor                aDescriptor;
        aDescriptor.Type              = WindowClass_TOP;
        aDescriptor.WindowServiceName = OUString( RTL_CONSTASCII_USTRINGPARAM(""));
        aDescriptor.ParentIndex       = -1;
		aDescriptor.Parent            = rToolkit->getDesktopWindow();
        aDescriptor.Bounds            = Rectangle(100,200,300,400);
        aDescriptor.WindowAttributes  = WindowAttribute::BORDER | WindowAttribute::MOVEABLE 						| WindowAttribute::SHOW	| WindowAttribute::CLOSEABLE 
						| WindowAttribute::SIZEABLE;
	Reference< XWindowPeer > xWindowPeer  = rToolkit->createWindow( aDescriptor );
	Reference< XWindow > xWindow(xWindowPeer,UNO_QUERY);
	xWindowPeer->setBackground(0xFF00FF);
 
// At this point, if you stop the program, you will have a new OOo window on the screen, 
//but you cannot do anything  with it.  You cannot even close it!
	// create a new frame
	Reference< XFrame > xFrame =Reference< XFrame >( rOfficeServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "com.sun.star.frame.Frame" ))), UNO_QUERY );
	xFrame->initialize(xWindow);
	Reference < XFramesSupplier > xFramesSupplier(Desktop,UNO_QUERY);
	xFrame->setCreator(xFramesSupplier);
	xFrame->setName(OUString::createFromAscii("Window 1"));
	getchar();
	}
    return 0;
}

The file picker dialog

We want provide a dialog box for searching a file and returning its name. We start from a Bernard Marcelly's book example. When working with file picker dialog, we are concerned with three IDL files. Here is the first one (com.sun.star.ui.dialogs.XFilePicker) :

//Listing 6 XFilePicker Interface : IDL File 
// IDL
module com { module sun { module star { module ui { module dialogs {
interface XFilePicker: com::sun::star::ui::dialogs::XExecutableDialog
{
	void setMultiSelectionMode( [in] boolean bMode );
	void setDefaultName( [in] string aName );
	void setDisplayDirectory( [in] string aDirectory )
		raises( ::com::sun::star::lang::IllegalArgumentException );
	string getDisplayDirectory();
	sequence< string > getFiles();
};
}; }; }; }; };

The beginning of this file indicates we are concerned with com.sun.star.ui.dialogs.XExecutableDialog too because of inheritance :

//Listing 7 XExecutableDialog Interface : IDL File 
// IDL
module com { module sun { module star { module ui { module dialogs {
interface XExecutableDialog: com::sun::star::uno::XInterface
{
	void setTitle( [in] string aTitle );
	short execute();
};
}; }; }; }; };

and what is more difficult to see is we are also concerned with com.sun.star.ui.dialogs.ExecutableDialogresults IDL constants:

//Listing 8 ExecutableDialogresults values : IDL File 
// IDL
module com { module sun { module star { module ui { module dialogs {
constants ExecutableDialogResults
{
	const short CANCEL = 0;
	const short OK     = 1;
};
}; }; }; }; };

The way to obtain the FilePicker dialog can be explained as follow. First you have to obtain a com.sun.star.ui.dialogs.XFilePicker interface. After we use a setDisplayDirectory for an example, then execute the dialog box and finally get the first of chosen files.

//Listing 9 a File Picker Dialog
// LINUX C++ (Only the file path is LINUX-like)
// based on Bernard Marcelly's  Example (Book p512)
// Don't forget #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
				OUString::createFromAscii("/home/smoutou/"),sDocUrl);
 
// Don't forget to add : using namespace com::sun::star::ui::dialogs;
// Don't forget to add : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.XFilePicker \" in the makefile
// Query the XFilePicker interface
 
	Reference< XFilePicker > rFilePicker = Reference< XFilePicker >
					( rOfficeServiceManager->createInstance(
                          OUString( RTL_CONSTASCII_USTRINGPARAM(
                          "com.sun.star.ui.dialogs.FilePicker" ))), UNO_QUERY );
 
	rFilePicker->setDisplayDirectory( sDocUrl);
	short result=rFilePicker->execute();
 
// Don't forget to add : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

It is possible to modify the filter names with the com.sun.star.ui.dialogs.XFilterManager interface. Here is the corresponding IDL file :

//Listing 10 XFilterManager Interface : IDL File 
// IDL
module com { module sun { module star { module ui { module dialogs {
interface XFilterManager: com::sun::star::uno::XInterface
{
	void appendFilter( [in] string aTitle, [in] string aFilter )
		raises( ::com::sun::star::lang::IllegalArgumentException );
	void setCurrentFilter( [in] string aTitle )
		raises( ::com::sun::star::lang::IllegalArgumentException );
	string getCurrentFilter( );
};
}; }; }; }; };

and now a C++ example which use this interface :

//Listing 11 Using the File Picker
// LINUX C++
// Don't forget #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
						OUString::createFromAscii("/home/smoutou/"),sDocUrl);
// Don't forget to add : using namespace com::sun::star::ui::dialogs;
// Don't forget to add : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.XFilePicker \" in the makefile
//	Reference< XFilePicker > rFilePicker(rDesktop,UNO_QUERY);
	Reference< XFilePicker > rFilePicker = Reference< XFilePicker >
					( rOfficeServiceManager->createInstance(
                                 OUString( RTL_CONSTASCII_USTRINGPARAM(
                                 "com.sun.star.ui.dialogs.FilePicker" ))), UNO_QUERY );
 
	rFilePicker->setDisplayDirectory( sDocUrl);
 
// Don't forget to add : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.XFilterManager \" in the makefile
	Reference< XFilterManager > rFilterManager (rFilePicker, UNO_QUERY);
	rFilterManager->appendFilter(OUString::createFromAscii("Texts"),
					OUString::createFromAscii("*.txt"));
	rFilterManager->appendFilter(OUString::createFromAscii("Docs OpenOffice"),
					OUString::createFromAscii("*.sxw;*.sxc"));
	rFilterManager->setCurrentFilter(OUString::createFromAscii("Docs OpenOffice"));
	short result=rFilePicker->execute();
 
// Don't forget to add : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

See also com.sun.star.ui.dialogs.XFilePicker and com.sun.star.ui.dialogs.XFilterManager interfaces and com.sun.star.ui.dialogs.ExecutableDialogResults constants.


It's time to show how to construct a save as Dialog.

Save as Dialog

We again start from a Bernard Marcelly's example. Our problem is to translate these OOoBasic lines :

'Listing 12 Save Dialog
REM  *****  BASIC  *****
FP=CreateUnoService("com.sun.star.ui.dialogs.FilePicker")
Dim FPtype(0) As Integer
FPtype(0)=com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_SIMPLE
With FP
	.initialize(FPtype())
....
End With

particularly the « initialize » method. At first, we look for the constant to transform the previous FilePicker dialog. The constants are defined in the com.sun.star.ui.dialogs.TemplateDescription file as descibed below (see how to use UNO constants with C++) :

//Listing 13 TemplateDescription Constants : IDL File 
// IDL
module com { module sun { module star { module ui { module dialogs {
constants TemplateDescription
{
	const short FILEOPEN_SIMPLE                                = 0;
	const short FILESAVE_SIMPLE                                = 1;
	const short FILESAVE_AUTOEXTENSION_PASSWORD                = 2;
	const short FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS  = 3;
	const short FILESAVE_AUTOEXTENSION_SELECTION               = 4;
	const short FILESAVE_AUTOEXTENSION_TEMPLATE                = 5;
	const short FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE           = 6;
	const short FILEOPEN_PLAY                                  = 7;
	const short FILEOPEN_READONLY_VERSION                      = 8;
	const short FILEOPEN_LINK_PREVIEW				           = 9;
	const short FILESAVE_AUTOEXTENSION			               = 10;
};
}; }; }; }; };

Looking for initialize method, we have a look in com.sun.star.ui.dialogs.FilePicker service :

//Listing 14 FilePiker service : IDL File 
// IDL
module com { module sun { module star { module ui { module dialogs {
interface XFilePicker;
interface XFilePickerNotifier;
interface XFilePickerControlAccess;
interface XFilterManager;
interface XFilePreview;
interface XFilterGroupManager;
 
service FilePicker
{
	[optional, property] string HelpURL;
	interface XFilePicker;
	interface XFilePickerNotifier;
	interface XFilterManager;
	[optional] interface XFilePreview;
	[optional] interface XFilePickerControlAccess;
	[optional] interface XFilterGroupManager;
	[optional] interface com::sun::star::lang::XInitialization;
	[optional] interface com::sun::star::util::XCancellable;
	interface com::sun::star::lang::XComponent;
	interface com::sun::star::lang::XServiceInfo;
	interface com::sun::star::lang::XTypeProvider;
};
}; }; }; }; };

where you see an com.sun.star.lang.XInitialization interface. Therefore we give the XInitialization.idl file :

//Listing 15 XInitialisation Interface : IDL File 
// IDL
module com {  module sun {  module star {  module lang {
interface XInitialization: com::sun::star::uno::XInterface
{ 
	void initialize( [in] sequence<any> aArguments ) 
			raises( com::sun::star::uno::Exception ); 
 
}; 
}; }; }; };

It's OK, we get it. We see we have to pass an any sequence to the initialize procedure. It's time to write the C++ corresponding code.

//Listing 16 Invoking the Save Dialog
	// LINUX C++
	// inspired by Bernard Marcelly's Example p515
// Don't forget #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
						OUString::createFromAscii("/home/smoutou/"),sDocUrl);
// Don't forget to add : using namespace com::sun::star::ui::dialogs;
// Don't forget to add : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.XFilePicker \" in the makefile
//	Reference< XFilePicker > rFilePicker(rDesktop,UNO_QUERY);
	Reference< XFilePicker > rFilePicker = Reference< XFilePicker >
					( rOfficeServiceManager->createInstance(
                               OUString( RTL_CONSTASCII_USTRINGPARAM(
                               "com.sun.star.ui.dialogs.FilePicker" ))), UNO_QUERY );
 
	rFilePicker->setDisplayDirectory( sDocUrl);
 
// Don't forget to add : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.XFilterManager \" in the makefile
	Reference< XFilterManager > rFilterManager (rFilePicker, UNO_QUERY);
 
// Don't forget to add : #include <com/sun/star/lang/XInitialization.hpp>
// Don't forget to add "com.sun.star.lang.XInitialization \" in the makefile
	Reference< XInitialization > rInitialize (rFilePicker, UNO_QUERY);
	Sequence < Any > info(1);
 
// Don't forget to add : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.TemplateDescription \" in the makefile
	info[0] <<=  (short) TemplateDescription::FILESAVE_SIMPLE;
	rInitialize-> initialize(info);
 
	rFilterManager->appendFilter(OUString::createFromAscii("Texts"),
					OUString::createFromAscii("*.txt"));
	rFilterManager->appendFilter(OUString::createFromAscii("Docs OpenOffice"),
					OUString::createFromAscii("*.sxw;*.sxc"));
	rFilterManager->setCurrentFilter(OUString::createFromAscii("Docs OpenOffice"));
	short result=rFilePicker->execute();
 
// Don't forget to add : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// Don't forget to add "com.sun.star.ui.dialogs.ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

This code uses com.sun.star.ui.dialogs.XFilePicker, com.sun.star.ui.dialogs.XFilterManager, com.sun.star.lang.XInitialization interfaces and com.sun.star.ui.dialogs.ExecutableDialogResults UNO constants.

We are interesting now with generalising our previous work with Dialog Box.

Run Time Dialog Box

Read also Developer's Guide and OOoBasic and Dialogs.

After the previous examples inspired by Bernard Marcelly's book, it's time to start with an example inspired from Andrew Pitonyak's book. OOoBasic is particulary difficult to translate in these situations. We then choose to start from a Java example in : <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/BasicAndDialogs/CreatingDialogs with the file SampleDialog.java For this example we use GAP's helper provided here.

Documentation note.png Dialogs tackled in this section are runtime dialogs. Since recent evolution of OpenOffice, it is possible to run OOoBasic Dialog (I mean conceived with Basic IDE) with all programming language. But the only SDK's examples available are for components and in Java, and at the moment, I have no time to explore if it is possible with C++ automation examples and in C++.

We give now the complete code. Because it's a lot of code you have to look at com.sun.star.awt.XActionListener, com.sun.star.awt.XControlContainer, com.sun.star.lang.XMultiServiceFactory, com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader, com.sun.star.uno.XComponentContext, com.sun.star.lang.XMultiComponentFactory, com.sun.star.beans.XPropertySet, com.sun.star.container.XNameContainer, com.sun.star.awt.XButton, com.sun.star.awt.XToolkit, com.sun.star.awt.XWindow, com.sun.star.ui.dialogs.XDialog interfaces, and com.sun.star.awt.ActionEvent event, and also com.sun.star.frame.Desktop, com.sun.star.awt.UnoControlDialogModel, com.sun.star.awt.UnoControlButtonModel services) :

//Listing 17 Our first Run Time Dialog Box
// C++ (GAP example)
#include "SimpleOOConnection.cpp"
...
// First an event listener for the Button
// Don't forget the #include <cppuhelper/implbase1.hxx>
typedef ::cppu::WeakImplHelper1< ::com::sun::star::awt::XActionListener > ActionListenerHelper;
/** action listener
*/
class ActionListenerImpl : public ActionListenerHelper
{
private :
	int _nCounts;
	Reference< XControlContainer > _xControlCont;
	//XControlContainer _xControlCont;
 
public :
ActionListenerImpl(const Reference< XControlContainer >& xControlCont) {
	_xControlCont = xControlCont;
	_nCounts = 0;
}
 
// XEventListener
virtual void SAL_CALL disposing (const com::sun::star::lang::EventObject& aEventObj )
                                            throw(::com::sun::star::uno::RuntimeException) {
//	_xControlCont = NULL;
	cout << "object listened to will be disposed"<<endl;
}
 
// XActionListener
virtual void SAL_CALL actionPerformed (const ::com::sun::star::awt::ActionEvent& rEvent ) 
                                                                   throw ( RuntimeException) {
// increase click counter
	_nCounts++;
	cout << "OK : " << _nCounts << endl;
 }
};
 
int main()
{
SimpleOOConnection sOOConnection1;
 
//instantiating connection to Remote Service Manager
	Reference< XMultiServiceFactory > xRemoteServiceManager=sOOConnection1.connect_ooffice
		("uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");
//checks whether getting Remote Service Manager or Not
	if(!xRemoteServiceManager.is())
	{
	cout<<"Error in connection"<<endl;
	return 1;
	}
 
// setting Desktop reference to desktop
	Reference< XInterface > desktop =xRemoteServiceManager->createInstance
		(OUString::createFromAscii("com.sun.star.frame.Desktop" ));
 
// Query for the XUnoUrlResolver interface for loading Desktop
	Reference< XComponentLoader > xComponentLoader( desktop, UNO_QUERY );
 
//////////////////////////////////////////////////////////////////////////////////////
	Any any;
	sal_Int32 value;
 
	Reference< XComponentContext > xComponentContext =
	defaultBootstrap_InitialComponentContext();
 
// retrieve the servicemanager from the context
	Reference< XMultiComponentFactory > xMultiComponentFactory =
	xComponentContext->getServiceManager();
/************************************************************************************
Reference<XInterface> dialogModel = xMultiComponentFactory->createInstanceWithContext(
                                      OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"),
                                      xComponentContext );
************************************************************************************/
/////////////////////////////////////////////////////////////////////////////////////////
 
	Reference<XInterface> dialogModel = xRemoteServiceManager->createInstance
		(OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"));
	cout<<"hi"<<endl;
 
///////////////////////////////////////////////////////////////////////////////////////////
 
	Reference< XPropertySet >xPSetDialog(dialogModel,UNO_QUERY );
 
	value=150;
	any<<=value;
	xPSetDialog->setPropertyValue( OUString::createFromAscii("PositionX"), any );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("PositionY"), any );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("Width"), any );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("Height"), any );
	any<<=OUString::createFromAscii( "Runtime Dialog Demo" );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("Title"), any );
 
	Reference<XMultiServiceFactory> xMultiServiceFactory(dialogModel,UNO_QUERY );
 
	Reference< XInterface > buttonModel = xMultiServiceFactory->createInstance
		(OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel") );
 
	Reference< XPropertySet >xPSetButton(buttonModel,UNO_QUERY );
 
	value=20;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("PositionX"), any );
 
	value=70;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("PositionY"), any );
	value=50;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("Width"), any );
	value=14;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("Height"), any );
	any<<=OUString::createFromAscii("Button1");
	xPSetButton->setPropertyValue( OUString::createFromAscii("Name"), any );
	value=1;
	any<<=value;
 
//xPSetButton->setPropertyValue( OUString::createFromAscii("TabIndex"), any );
	any<<=OUString::createFromAscii( "Click Me" );
 
	xPSetButton->setPropertyValue( OUString::createFromAscii("Label"), any );
 
// insert the control models into the dialog model
	Reference< XNameContainer >xNameCont(dialogModel,UNO_QUERY );
	any<<=buttonModel;
 
	xNameCont->insertByName( OUString::createFromAscii("Button1"), any );
 
// create the dialog control and set the model
	Reference<XInterface> dialog = xRemoteServiceManager->createInstance(
			OUString::createFromAscii("com.sun.star.awt.UnoControlDialog"));
 
	Reference<XControl> xControl(dialog,UNO_QUERY );
	Reference<XControlModel >xControlModel(dialogModel,UNO_QUERY );
	xControl->setModel( xControlModel );
 
 // add an action listener to the button control
	Reference< XControlContainer >xControlCont(dialog ,UNO_QUERY );
	Reference< XInterface > objectButton = xControlCont->getControl( 
							OUString::createFromAscii("Button1") );
	Reference< XButton >xButton(objectButton ,UNO_QUERY);
 
	ActionListenerImpl *xListener = new ActionListenerImpl( xControlCont );
	Reference< XActionListener > xActionListener = 
			static_cast< XActionListener* > ( xListener );
 
	xButton->addActionListener( xActionListener );
 
// create a peer
	Reference<XInterface> toolkit = xRemoteServiceManager->createInstance(
	OUString::createFromAscii("com.sun.star.awt.ExtToolkit"));
	Reference< XToolkit >xToolkit(toolkit , UNO_QUERY );
 
 
	Reference< XWindow >xWindow(xControl , UNO_QUERY );
	xWindow->setVisible( true );
	xControl->createPeer( xToolkit,'\0' );//create instance of XWindowPeer
 
 
// execute the dialog
	Reference< XDialog >xDialog(dialog , UNO_QUERY );
	xDialog->execute();
 
// dispose the dialog
	Reference< XComponent > xComponent(dialog,UNO_QUERY );
	xComponent->dispose();
 
/////////////////////////////////////////////////////////////////////////////////////
 
	return 0;
}

This code will print out :

hi
OK : 1
OK : 2
OK : 3
OK : 4
OK : 5
OK : 6
OK : 7
OK : 8
object listened to will be disposed

When clicking on the button it increment and prints out the new value. From this code any tips to manage a dialog box can be hired :

  1. create a dialog model service, dialogModel variable in the above code
  2. query a XPropertySet interface to set any properties (x y positions, size, title, ..)
  3. create all controls with the same previous both rules : query a control model first, and then query a XPropertySet interface to set any properties
  4. query a XNameContainer from the dialog model
  5. insert every control model into the dialog model with this container
  6. create the dialog control and query first aXControl interface and second a XControlModedl interface to set the model
  7. add action listener if needed
  8. after creating a peer run the dialog

Complete Translation of a Java example

Edit-find-replace.png This article needs to be checked for accuracy and style.

Let's give now a complete translation of SampleDialog.java example. You can find it in <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/BasicAndDialogs/CreatingDialogs This is a dialog box with a “Click Me” button. When you click this button it increments a counter and prints out the result in the dialog box. I have done this example in few hours starting from the previous one. Without GAP (from India) 's help it would be a few months postponed. This example is constructed as usually, without helper (using the style defined in chapter 4.3 “Prepare a new code as a starting point”) Here are the listings : we begin with the event listener (See com.sun.star.awt.XActionListener, com.sun.star.awt.XControlContainer com.sun.star.awt.XFixedText interfaces) :

//Listing 18 The Action performed Event Listener
// C++
typedef ::cppu::WeakImplHelper1< ::com::sun::star::awt::XActionListener > ActionListenerHelper;
/** action listener
*/
class ActionListenerImpl : public ActionListenerHelper
{
private :
	sal_Int32 _nCounts;
	Reference< XControlContainer > _xControlCont;
	//XControlContainer _xControlCont;
 
public :
ActionListenerImpl(const Reference< XControlContainer >& xControlCont) {
	_xControlCont = xControlCont;
	_nCounts = 0;
}
 
// XEventListener
 virtual void SAL_CALL disposing (const com::sun::star::lang::EventObject& aEventObj ) throw(::com::sun::star::uno::RuntimeException) {
//	_xControlCont = NULL;
	printf("object listened to will be disposed\n");
}
 
// XActionListener
virtual void SAL_CALL actionPerformed (const ::com::sun::star::awt::ActionEvent& rEvent ) throw ( RuntimeException) {
// increase click counter
	_nCounts++;
//	printf("OK :  %d\n",_nCounts); OLD listener
	OUString OUStr;
// set label text
	Reference< XControl > label = _xControlCont->getControl(OUString::createFromAscii("Label1"));
 
// Don't forget to add : #include <com/sun/star/awt/XFixedText.hpp>
// Don't forget to add "com.sun.star.awt.XFixedText \" in the makefile
	Reference< XFixedText > xLabel(label,UNO_QUERY);
	xLabel->setText (OUString::createFromAscii("Text1 ") + OUStr.valueOf((sal_Int32)_nCounts));
 }
};

What differs from the previous one is only the action performed method where we replace a printf (or cout<<) with a setText. We don't print out in the shell windows but in the dialog box windows. Let's have a look in the corresponding IDL file (see also com.sun.star.awt.XFixedText):

//Listing 19 XFixedText Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
interface XFixedText: com::sun::star::uno::XInterface
{
	[oneway] void setText( [in] string Text );
	string getText();
	/** sets the alignment of the text in the control.
		<pre>
		0: left
		1: center
		2: right
	 */
	[oneway] void setAlignment( [in] short nAlign ); 
 	short getAlignment(); 
 
};
}; }; }; };  

We are ready to construct and use the dialog box now. Here is the listing (we don't give the ooConnect() procedure already given many times in this document.

//Listing 20 The complete Code
// C++
main( ) {
//retrieve an instance of the remote service manager
	Reference< XMultiServiceFactory > xServiceManager;
    	xServiceManager = ooConnect();
    	if( xServiceManager.is() ){
        	printf( "Connected sucessfully to the office\n" );
    	}
 
//get the desktop service using createInstance returns an XInterface type
    	Reference< XInterface  > Desktop = xServiceManager->createInstance(
    		OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//query for the XComponentLoader interface
    	Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
    	if( rComponentLoader.is() ){
        	printf( "XComponentloader successfully instanciated\n" );
    	}
 
	Reference< XInterface > xdialogModel =
	 xServiceManager->createInstance(
	 	OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"));
	if (xdialogModel.is()) printf("OK XDialogModel\n"); else printf("Error ... XDialodModel\n");
 
	Any val;
	Reference< XPropertySet > xPSetDialog(xdialogModel,UNO_QUERY);
	if (xPSetDialog.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");
	sal_Int32 value=100;
	val<<=value;
	xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=150;val<<=value;
	xPSetDialog->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=100;val<<=value;
	xPSetDialog->setPropertyValue(OUString::createFromAscii("Height"),val);
 
	val <<=OUString::createFromAscii("Runtime Dialog Demo");
	xPSetDialog->setPropertyValue(OUString::createFromAscii("Title"),val);
 
	Reference< XMultiServiceFactory > xMultiServiceFactory( xdialogModel,UNO_QUERY);
 
///*****************
//******** in the above line xMultiServiceFactory instead xServiceManager !!!!!!
//Reference< XInterface > xbuttonModel = xServiceManager>createInstance( ....
	Reference< XInterface > xbuttonModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel"));
	if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n");
 
	Reference< XPropertySet > xPSetButton(xbuttonModel,UNO_QUERY);
	if (xPSetButton.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");
 
	value=20; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=70; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=50; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=14; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Button1");
	xPSetButton->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetButton->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)0));
	val <<=OUString::createFromAscii("Click Me");
	xPSetButton->setPropertyValue(OUString::createFromAscii("Label"),val);
 
// create the label model and set the properties
	Reference< XInterface > xlabelModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlFixedTextModel"));
	if (xlabelModel.is()) printf("OK xlabelModel\n"); else printf("Error ... xlabelModel\n");
	Reference< XPropertySet > xPSetLabel(xlabelModel,UNO_QUERY);
	if (xPSetLabel.is()) printf("OK XPropertySet2\n"); else printf("Error ... XPropertySet2\n");
	value=40; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=30; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=100; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=14; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Label1");
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetLabel->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));
	val <<=OUString::createFromAscii("Text1");
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Label"),val);
 
// insert all the control in container
	Reference< XNameContainer > xNameCont(xdialogModel,UNO_QUERY);
	if (xNameCont.is()) printf("OK XNameContainer\n"); else printf("Error ... XNameContainer\n");
	val <<= xbuttonModel;
// We insert first the button
	xNameCont->insertByName(OUString::createFromAscii("Button1") ,val); printf("First\n");
// We insert now the text control
	val <<= xlabelModel;
	xNameCont->insertByName(OUString::createFromAscii("Label1") , val);
 
// create the dialog control and set the model
	Reference< XInterface >dialog = xServiceManager->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlDialog"));
	if (dialog.is()) printf("OK dialog\n"); else printf("Error ... dialog\n");
	Reference< XControl > xControl(dialog,UNO_QUERY);
	if (xControl.is()) printf("OK XControl\n"); else printf("Error ... XControl\n");
	Reference< XControlModel > xControlModel(xdialogModel,UNO_QUERY);
	if (xControlModel.is()) printf("OK xControlModel\n"); else printf("Error ... xControlModel\n");
	xControl->setModel(xControlModel);
 
// add an action listener to the button control
	Reference< XControlContainer > xControlCont(dialog,UNO_QUERY);
	if (xControlCont.is()) printf("OK xControlContainer\n"); else printf("Error ... xControlContainer\n");
	Reference< XInterface > objectButton=xControlCont->getControl(OUString::createFromAscii("Button1"));
	if (objectButton.is()) printf("OK objectButton\n"); else printf("Error ... objectButton\n");
	Reference< XButton > xButton(objectButton,UNO_QUERY);
	ActionListenerImpl *xListener = new ActionListenerImpl( xControlCont );
	Reference< XActionListener > xActionListener = static_cast< XActionListener* > ( xListener );
	xButton->addActionListener( xActionListener );
 
// create a peer
	Reference< XToolkit >xToolkit = Reference< XToolkit >( xServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "com.sun.star.awt.Toolkit" ))), UNO_QUERY );
	if (xToolkit.is()) printf ("XToolkit OK...\n"); else printf("XToolkit Error\n");
 
	Reference< XWindow > xWindow(xControl,UNO_QUERY);
	xWindow->setVisible(true);
	xControl->createPeer(xToolkit,NULL);
	Reference< XDialog > xDialog(dialog,UNO_QUERY);
	xDialog->execute();
	Reference< XComponent > xComponent(dialog,UNO_QUERY);
	xComponent->dispose();
 
	return 0;
}

What is obtained is presented in the below figure :

The First Dialog Example


Text Control example

We want now to construct a more complex dialog box with a text control.

List Box example

We want now to construct a dialog box with a list box.

Radio button example

We want now to construct a dialog box with a radio button.

TO DO

Developer's Guide states it is possible to construct a component with a dialog that have been created with the Dialog Editor integrated in the OpenOffice.org Basic IDE. I think the same is possible with a binary executable and I have to work around this subject.

See also

Personal tools