FR/Documentation/Utilitaires C++

From Apache OpenOffice Wiki
Jump to: navigation, search

Jouer avec les fenêtres du toolkit

Documentation note.png Cette section est ancienne (2005) : écrite longtemps avant que je découvre la nouvelle possibilité des composants et boîtes de dialogue dans le Developer's Guide (2007). Pour le moment (Mai 2009), je me suis contenté de construire des composants avec ces boîtes de dialogue mais j'espère un peu plus tard regarder si ce mécanisme ne peut pas fonctionner dans des binaires exécutables. Juin 2009 : je pense que c'est possible mais forcément en utilisant des event listeners : c'est toujours mieux que de construire des boîtes de dialogue à l'exécution.

Explications de Danny Brewer

Il y a deux choses différentes ici. En réalité il y en a trois.

  1. Les dialogues
  2. AWT
  3. Les formes

Les formes sont d'un plus haut niveau que les deux autres.

  • Sur les deux premiers, les dialogues utilisent le UnoDialogControl et ses modèles. Vous pouvez aussi créer des fenêtres AWT avec les commandes.
  • Les fenêtres AWT peuvent être modales ou non, et ne sont pas attachées à d'autres fenêtres.
  • Les fenêtres AWT ne sont pas comme les dialogues.

Généralement, les dialogues sont réalisés de façon modale en appelant la méthode execute() du dialogue. J'ai réussi à réaliser des boites de dialogue non modales.

Les fenêtres MessageBox

Le code initial est en gros le même que le précédent (examples/DevelopersGuide/ProfUNO/CppBinding/). Nous examinons aussi l'exemple de “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/Addons/ProtocolHandlerAddon_cpp” où nous trouvons une fenêtre MessageBox. Le code correspondant est donné ici (voir aussi les intrerfaces com.sun.star.awt.XWindowPeer, com.sun.star.awt.XMessageBox, com.sun.star.frame.XFrame, com.sun.star.awt.XToolkit et la structure com.sun.star.awt.WindowDescriptor et les constantes com.sun.star.awt.WindowAttribute) :

//Listing 1
// C++
// N'oubliez pas d'ajouter la directive : #include <com/sun/star/awt/WindowDescriptor.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.WindowDescriptor \" dans le makefile
// N'oubliez pas d'ajouter la directive : #include <com/sun/star/awt/WindowAttribute.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.WindowAttribute \" dans le makefile
// N'oubliez pas d'ajouter la directive : #include <com/sun/star/awt/XWindowPeer.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.XWindowPeer \" dans le makefile
// N'oubliez pas d'ajouter la directive : #include <com/sun/star/awt/XMessageBox.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.XMessageBox \" dans le makefile

/**
  * Montre un boîte de message avec le toolkit UNO
  */
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(0,0,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();
            }
        }
    }
}

pour comprendre le WindowAttribute::BORDER et les autres constantes, jetons un oeil au fichier IDL com.sun.star.awt.WindowAttribute décrivant les attributs de fenêtres :

//Listing 2
// 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;  
};
}; }; }; };

Nous donnons maintenant le listing d'un programme principal complet pour nous apprendre à utiliser cette procédure :

//Listing 3
//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" );
    	}

// Ne pas oublier la directive : #include <com/sun/star/awt/XToolkit.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.awt.XToolkit \" dans le 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;
}

(Voir aussi l'interface com.sun.star.awt.XToolkit ainsi que le service com.sun.star.awt.Toolkit). Nous pouvons tirer trois choses importantes de ce code :

  • la manière que nous pouvons utiliser un tel fichier de constantes IDL (donné ci-dessus) avec C++: ce n'est pas la première fois que nous rencontrons ce genre de fichier IDL,
  • la manière dont on peut accéder à une interface à travers un service avec createInstance et UNO_QUERY simultanément (voir comment nous obtenons rToolkit)
  • nous voyons aussi comment nous obtenons une fenêtre à partir du service com.sun.star.frame.Desktop.

Nous présenterons plus tard un utilitaire C++ utilisant ce code. (Voir ici (en anglais))

Une fenêtre toute simple

Nous donnons maintenant le listing d'un programme capable de construire une fenêtre toute simple en utilisant le toolkit UNO (voir les interfaces com.sun.star.awt.XToolkit , com.sun.star.frame.XFrame, com.sun.star.frame.XDesktop) :

//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;
}


La boîte de dialogue d'obtention d'un fichier : « file picker dialog »

Nous voulons fournir une boîte de dialogue pour chercher un fichier par exploration et qui rende le nom du fichier choisi. Nous commençons par partir d'un exemple du livre de Bernard Marcelly. Quand nous travaillons avec la boîte de dialogue d'obtention d'un fichier, nous devons nous intéresser à trois fichiers IDL. Voici le premier (com.sun.star.ui.dialogs.XFilePicker) :

//Listing 4 Le fichier XFilePicker.idl
// 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();
};
}; }; }; }; };

Le début de ce fichier indique que l'héritage nous conduit à nous intéresser aussi à l'interface com.sun.star.ui.dialogs.XExecutableDialog :

//Listing 5 Le fichier XExecutableDialog.idl
// 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();
};
}; }; }; }; };

et ce qui est plus difficile à voir et qui nous intéresses est un fichier définissant deux constantes (com.sun.star.ui.dialogs.ExecutableDialogresults voir comment utiliser les constantes UNO en C++) :

//Listing 6 Le fichier ExecutableDialogResult
// IDL
module com { module sun { module star { module ui { module dialogs {
constants ExecutableDialogResults
{
	const short CANCEL = 0;
	const short OK     = 1;
};
}; }; }; }; };

La façon de faire peut être expliquée comme suit. Vous devez en premier obtenir une Interface com.sun.star.ui.dialogs.XFilePicker. Après nous utilisons un setDisplayDirectory pour un exemple, ensuite nous exécutons la boîte du dialogue et finalement nous obtenons le premier des dossiers choisis. Voici le code correspondant :

//Listing 7
// LINUX C++ (Seuls les chemins sont de type LINUX)
// basé sur l'exemple de Bernard Marcelly dans son livre 1ere édition p512
// Ne pas oublier la directive #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
				OUString::createFromAscii("/home/smoutou/"),sDocUrl);

// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs;
// N'oubliez pas d'ajouter la directive : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilePicker \" dans le 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();

// N'oubliez pas d'ajouter la directive : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

C'est possible de modifier le filtre nommé avec l'interface com.sun.star.ui.dialogs.XFilterManager. Voici le fichier IDL correspondant :

//Listing 8 Le fichier XfilterManager.idl
// 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( );
};
}; }; }; }; };

Et maintenant voici un exemple en C++ qui utilise cette interface :

// Listing 9
// LINUX C++
// N'oubliez pas #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
						OUString::createFromAscii("/home/smoutou/"),sDocUrl);
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs;
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// N'oubliez pas d'ajouter "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);

// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
// N'oubliez pas d'ajouter "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();

// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

Il est possible de modifier les noms du filtre avec l'interface com.sun.star.ui.dialogs.XFilterManager dont nous présentons le fichier IDL correspondant maintenant :

//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( );
};
}; }; }; }; };

Et pour terminer un petit exemple de code C++ qui utilise cette interface :

//Listing 11 Using the File Picker
// LINUX C++
// N'oubliez pas d'ajouter : #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
						OUString::createFromAscii("/home/smoutou/"),sDocUrl);
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs;
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilePicker \" dans le 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);

// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilterManager \" dans le 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();

// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.ExecutableDialogResults \" dans le makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

Voir les interfaces com.sun.star.ui.dialogs.XFilePicker, com.sun.star.ui.dialogs.XFilterManager et les constantes com.sun.star.ui.dialogs.ExecutableDialogResults.

Il est temps de montrer comment faire une sauvegarde avec une boîte de Dialogue.

Boîte de dialogue d'enregistrement

Nous partons encore d'un exemple de Bernard Marcelly. Notre problème est de traduire ces lignes OOoBasic :

'Listing 12
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

en particulier celle qui concerne la méthode "initialize" qu'il nous faudra mettre en oeuvre. Ce type de recherche est important quand on programme avec l'API UNO. Remarquons quand même que l'outil XRay nous permettrait de faire cette recherche probablement plus simplement, mais je décris ici les étapes telles que je les ai réalisées.

Nous cherchons d'abord les constantes qui permettent de transformer la boîte de dialogue précédente. Elles sont définies dans le fichier de constantes com.sun.star.ui.dialogs.TemplateDescription (voir aussi la programmation des constantes UNO en C++) :

//Listing 13 Le fichier TemplateDescription.idl
// 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;
};
}; }; }; }; };

Pour "initialize" nous cherchons dans le service com.sun.star.ui.dialogs.FilePicker que nous reproduisons maintenant :

//Listing 14 Description du service FilePicker
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;
};
}; }; }; }; };

où vous voyez une interface com.sun.star.lang.XInitialization. Nous donnons donc le fichier XInitialization.idl pour un examen attentif :

//Listing 15
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 ); 
 
}; 
}; }; }; };

C'est bien, nous l'avons trouvé avec une quête qui je l'espère ne vous a pas semblé trop longue. Nous voyons que nous devons passer une séquence à la procédure d'initialisation. Il est temps d'écrire le code correspondant.

//Listing 16
	// LINUX C++
	// inspired by Bernard Marcelly's Example p515
// N'oubliez pas #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
						OUString::createFromAscii("/home/smoutou/"),sDocUrl);
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs;
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// N'oubliez pas d'ajouter "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);

// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilterManager \" in the makefile
	Reference< XFilterManager > rFilterManager (rFilePicker, UNO_QUERY);

// N'oubliez pas d'ajouter : #include <com/sun/star/lang/XInitialization.hpp>
// N'oubliez pas d'ajouter "com.sun.star.lang.XInitialization \" in the makefile
	Reference< XInitialization > rInitialize (rFilePicker, UNO_QUERY);
	Sequence < Any > info(1);

// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
// N'oubliez pas d'ajouter "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();

// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

Ce morceau de code utilise les interfaces déjà rencontrées com.sun.star.ui.dialogs.XFilePicker, com.sun.star.ui.dialogs.XFilterManager et com.sun.star.lang.XInitialization ainsi que la défibnition de constantes UNO dans com.sun.star.ui.dialogs.ExecutableDialogResults.


Nous sommes intéressés maintenant par la généralisation de tout ceci à une boîte de dialogue générale.

Boite de dialogue à l'exécution

Lire aussi le Developer's Guide et Boîtes de dialogue.

Après les exemples précédents inspirés par le livre de Bernard Marcelly sur la programmation OOoBasic, il est grand temps de présenter un exemple qui s'inspire du livre d'Andrew Pitonyak. OOoBasic étant particulièrement difficile à traduire dans cette situation, on choisit plutôt de s'inspirer d'un exemple Java du SDK dans le répertoire : <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/BasicAndDialogs/CreatingDialogs et le fichier SampleDialog.java correspondant.

Documentation note.png Les boîtes de dialogue qui seront abaordées maintenant sont des boîtes de dialogue fabriquées à l'exécution, (runtime dialog). Il faut savoir que depuis une version récente d'OpenOffice, il est possible d'exécuter des boîtes de dialogue OOoBasic à partir du C++ (ou autre langage). Mais les seuls exemples du SDK sont pour les composants et en Java, et je n'ai pas eu le temps d'explorer ceci dans les programme d'automation et en C++.

Pour cet exemple nous utilisons l'aide de GAP donné ici. Nous donnons maintenant le code complet mais puisqu'il est important en taille, il vous faudra vous documenter sur les interfaces 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 et aussi sur l'événement com.sun.star.awt.ActionEvent. Puisque nous avons décidé d'être complet, regardez donc aussi les services com.sun.star.frame.Desktop, com.sun.star.awt.UnoControlDialogModel et com.sun.star.awt.UnoControlButtonModel. Maintenant que vous avez fait le tour de la question, je donne le code :

//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;
}

Ce code affichera dans une boite DOS :

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

En cliquant sur le bouton, une incrémentation est réalisée et la nouvelle valeur est affichée. On peut tirer un certain nombre d'indications de ce code pour gérer une boite de dialogue :

  1. créer un service "dialog model", avec la variable dialogModel dans le code ci-dessus
  2. demander une interface XPropertySet pour positionner les propriétés (positions x et y, taille, titre, ..)
  3. création de tous les contrôles avec les deux règles précédentes : demander un "control model" en premier, et ensuite demander une interface XPropertySet pour positionner les propriétés
  4. demander une interface XNameContainer en partant du "dialog model"
  5. insérer tous les modèles de contrôle dans le modèle de dialogue avec le conteneur
  6. crééer un controle dialogue et demander une interface XControl puis l'interface XControlModedl pour positionner correctement le modèlel
  7. ajouter des "action listener" si nécessaires
  8. après création d'un "peer" exécuter la boîte de dialogue

Traduction complète d'un exemple Java

Donnons maintenant une traduction complète du code Java SampleDialog.java. Vous pouvez le trouver dans <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/BasicAndDialogs/CreatingDialogs C'est une boîte de dialogue avec un bouton “Click Me”. Quand vous cliquez sur ce bouton, un compteur est incrémenté et la nouvelle valeur est affichée dans la boîte de dialogie. J'ai réalisé cet exemple en quelques heures en partant du précédent. Sans l'aide précieuse de GAP (from India) cela aurait été probablement retardé de quelques mois.

Cet exemple est construit comme toujours, sans "helper" (en utilisant ce code toujours comme point de départ) Voici maintenant les listings : on commence par l'intercepteur d'événements (voir les interfaces com.sun.star.awt.XActionListener, com.sun.star.awt.XControlContainer com.sun.star.awt.XFixedText) :

//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));
 }
};

Ce qui diffère du code précédent est seulement la méthode "action performed" dans laquelle nous remplaçons le vieux printf (or cout<<) avec un setText. On n'affiche plus dans la fenêtre de shell mais directement dans la boîte de dialogue. Un petit coup d'oeil sur le fichier IDL correspondant (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(); 
 
};
}; }; }; };

On est prêt à construire et utiliser la boîte de dialogue maintenant. Voici un listing dans lequel nous avons omis la procédure ooConnect() donnée déjà plusieurs fois dans ce 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;
}

Ce qui est obtenu est présenté maintenant dans la figure ci-dessous :

The First Dialog Example

Boîte de dialogue avec une zone de texte

On veut maintenant construire la boite de dialogue montrée ci-dessous.

An example of dialog with edit control

On doit jeter un oeil dans les fichiers IDL correspondants. On commence par l'interface com.sun.star.awt.XTextComponent.

//Listing 21 XTextComponent Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
interface XTextComponent: com::sun::star::uno::XInterface
{
	[oneway] void addTextListener( [in] com::sun::star::awt::XTextListener l );
	[oneway] void removeTextListener( [in] com::sun::star::awt::XTextListener l );
	[oneway] void setText( [in] string aText );
	[oneway] void insertText( [in] com::sun::star::awt::Selection Sel,
			 [in] string Text );
	string getText();
	string getSelectedText();
	[oneway] void setSelection( [in] com::sun::star::awt::Selection aSelection );
	com::sun::star::awt::Selection getSelection();
	boolean isEditable();
	[oneway] void setEditable( [in] boolean bEditable );
	[oneway] void setMaxTextLen( [in] short nLen );
	short getMaxTextLen();
};
}; }; }; };

Comme montré sur l'image cidessus, cet exemple comporte un défaut : le texte est ajouté en haut au lieu d'être ajouté à la suite ! Pour le moment, je ne sais pas résoudre ce problème : si j'utilise une méthode setText, j'obtiens toujours une seule ligne, si j'utilise la méthode insertText il me faut lui fournir une sélection. Je peux prendre cette sélection avec la méthode getSelection mais il n'y a rien de sélectionné et cette méthode retourne le début du texte. (Je pense avec du recul qu'il faut gérer un curseur ici)

Nous montrons maintenant le service com.sun.star.awt.UnoControlEditModel dans le fichier UnoControlEditModel.idl :

//Listing 22 UnoControlEditModel Service : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
service UnoControlEditModel
{
	service com::sun::star::awt::UnoControlModel;
	[property] short Align;
	[property] long BackgroundColor;
	[property] short Border; 
	[optional, property] short EchoChar; 
	[property] boolean Enabled; 
	[property] com::sun::star::awt::FontDescriptor FontDescriptor; 
	[property] short FontEmphasisMark;
	[property] short FontRelief;
	[property] boolean HScroll;
	[property] boolean HardLineBreaks;
	[property] string HelpText;
	[property] string HelpURL;
	[property] short MaxTextLen; 
	[property] boolean MultiLine; 
	[property] boolean Printable; 
	[property] boolean ReadOnly; 
	[property] boolean Tabstop; 
	[property] string Text; 
	[property] long TextColor; 
	[property] long TextLineColor;
	[property] boolean VScroll;    
}; 
}; }; }; };

Nous utilisons un certain nombre de ces propriétés dans l'exemple ci-après. Pour le construire, je modifie d'abord l'intercepteur d'événements de l'exemple précédent comme indiqué dans le listing ci-dessous :

//Listing 23 We first remplace XFixedText with XTextComponent interface
// C++
....
// Don't forget to add : #include <com/sun/star/awt/XTextComponent.hpp>
// Don't forget to add "com.sun.star.awt.XTextComponent \" in the makefile
//	Reference< XFixedText > xLabel(label,UNO_QUERY); //OLD
	Reference< XTextComponent > xLabel(label,UNO_QUERY);
	xLabel->insertText (xLabel->getSelection(),
		OUString::createFromAscii("Text1 ") + OUStr.valueOf((sal_Int32)_nCounts)+
		OUString::createFromAscii("\n"));
....

et ensuite je remplace le service “com.sun.star.awt.UnoControlFixedTextModel” par "com.sun.star.awt.UnoControlEditModel". Cela est réalisé avec le code :

//Listing 24 The UnoControlEditModel : an Example
// C++
	Reference< XInterface > xlabelModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlEditModel"));
	Reference< XPropertySet > xPSetLabel(xlabelModel,UNO_QUERY);
	value=20; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=10; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=110; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=50; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Height"),val);
	xPSetLabel->setPropertyValue(OUString::createFromAscii("HScroll"),makeAny((sal_Bool)true));
	xPSetLabel->setPropertyValue(OUString::createFromAscii("VScroll"),makeAny((sal_Bool)true));
	xPSetLabel->setPropertyValue(OUString::createFromAscii("MultiLine"),
		makeAny((sal_Bool)true));
	xPSetLabel->setPropertyValue(OUString::createFromAscii("HardLineBreaks"),
		makeAny((sal_Bool)true));
	val <<=OUString::createFromAscii("Label1");
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetLabel->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));

On construira des classes (nommées helper) pour simplifier l'écriture d'un tel code plus tard. Mais avant tout, nous devons parler d'un autre type de bouton, le bouton "OK".

La propriété à changer est "com.sun.star.awt.PushButtonType". Les valeurs prises par cette propriété sont encore et toujours données par un fichier IDL :

Listing 25 PushButtonType enumeration : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
enum PushButtonType
{
	STANDARD,
	OK, 
	CANCEL, 
	HELP  
}; 
}; }; }; };

Les valeurs sont données par un type énuméré. On a déjà rencontré ce type de problème et vous savez donc le résoudre. Je donne donc le code à ajouter pour obtenir un bouton "OK" :

//Listing 26 adding a second “OK” button
// C++
// second button : OK button
// we need a second button modedl
	Reference< XInterface > xbuttonModel2 = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel"));
	if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n");

	Reference< XPropertySet > xPSetButton2(xbuttonModel2,UNO_QUERY);
	if (xPSetButton2.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");
	// *** The following property is not position-independant !!!!!
	// Don't forget to add : #include <com/sun/star/awt/PushButtonType.hpp>
	// Don't forget to add "com.sun.star.awt.PushButtonType \" in the makefile
	// short is found with Inspector
	val <<= (short)PushButtonType_OK;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PushButtonType"),val);

	value=80; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=70; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=50; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=14; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Button2");
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetButton2->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));
	val <<=OUString::createFromAscii("OK");
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Label"),val);

Il faut donc ajouter ce code et modifier la partie d'insertion comme :

//Listing 27 Inserting all control in container
// C++
// 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");
	val <<= xbuttonModel2;
	xNameCont->insertByName(OUString::createFromAscii("Button2") ,val); //printf("First\n");
// We insert now the text control
	val <<= xlabelModel;
	xNameCont->insertByName(OUString::createFromAscii("Label1") , val);

Boîte de dialogue avec zone de liste

Voila ce que nous espérons réaliser : une sélection dans la zone de liste suivie par un appui sur le bouton “Click Me” nous affichera le résultat de la sélection de la zone de liste dans un shell donnant comme résultat :

Selected Item Pos :-1
Selected Item Pos :1
Selected Item Pos :0

La prelière ligne est obtenue quand rien n'est sélectionné dans la zone de liste. Pour apprendre à se servir d'une zone de liste une enquête dans les fichiers IDL est encore nécessaire. Nous présentons tout d'abord l'interface com.sun.star.awt.XListBox :

//Listing 28 XListBox Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
interface XListBox: com::sun::star::uno::XInterface
{ 
	[oneway] void addItemListener( [in] com::sun::star::awt::XItemListener l ); 
	[oneway] void removeItemListener( [in] com::sun::star::awt::XItemListener l ); 
	[oneway] void addActionListener( [in] com::sun::star::awt::XActionListener l ); 
	[oneway] void removeActionListener( [in] com::sun::star::awt::XActionListener l ); 
	[oneway] void addItem( [in] string aItem, 
			 [in] short nPos ); 
	[oneway] void addItems( [in] sequence<string> aItems, 
			 [in] short nPos ); 
	[oneway] void removeItems( [in] short nPos, 
			 [in] short nCount ); 
	short getItemCount(); 
	string getItem( [in] short nPos ); 
	sequence<string> getItems(); 
	short getSelectedItemPos(); 
	sequence<short> getSelectedItemsPos(); 
	string getSelectedItem(); 
	sequence<string> getSelectedItems(); 
	[oneway] void selectItemPos( [in] short nPos, 
			 [in] boolean bSelect ); 
	[oneway] void selectItemsPos( [in] sequence<short> aPositions, 
			 [in] boolean bSelect ); 
	[oneway] void selectItem( [in] string aItem, 
			 [in] boolean bSelect ); 
	boolean isMutipleMode(); 
	[oneway] void setMultipleMode( [in] boolean bMulti ); 
	short getDropDownLineCount(); 
	[oneway] void setDropDownLineCount( [in] short nLines ); 
	[oneway] void makeVisible( [in] short nEntry );
};
}; }; }; };

Nous nous concentrons maintenant sur le code C++.

Premièrement création d'un intercepteur d'événements ("event listener") :

//Listing 29 Our new Action performed Listener
// C++
// Don't forget the #include <cppuhelper/implbase1.hxx>
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) {
	OUString OUStr;
// set label text
	Reference< XControl > xListControl = _xControlCont->getControl(OUString::createFromAscii("Label1"));
// from adipan
	Reference< XListBox> xPSetListBox(xListControl,UNO_QUERY);
	sal_Int16 selItem = xPSetListBox->getSelectedItemPos ();
	printf ("Selected Item Pos :%d\n", selItem);
 }
};

Cet "intercepteur d'événements" sera associé au bouton “Click Me”. L'instruction printf nous rappelle que l'on utilise le shell comme sortie.

La boîte de dialogue complète est construite dans le main(). Ce serait probablement bien mieux avec des sous-programmes (peut-être plus tard).

//Listing 30 Dialog Code : an other Example
// 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);

	Reference< XInterface > xdialogModel =
	 xServiceManager->createInstance(
	 	OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"));

	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"));

	Reference< XPropertySet > xPSetButton(xbuttonModel,UNO_QUERY);

	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);

// second button : OK button
// we need a second button modedl
	Reference< XInterface > xbuttonModel2 = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel"));
	if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); 
        else printf("Error ... UnoControlButtonModel\n");

	Reference< XPropertySet > xPSetButton2(xbuttonModel2,UNO_QUERY);

	val <<= (short)PushButtonType_OK;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PushButtonType"),val);
	value=80; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=70; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=50; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=14; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Button2");
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetButton2->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));
	val <<=OUString::createFromAscii("OK");
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Label"),val);

	Reference< XInterface > xlistBoxModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlListBoxModel"));
	Reference< XPropertySet > xPSetLabel(xlistBoxModel,UNO_QUERY);
	value=20; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=10; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=110; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=50; 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)2));

// insert all the control in container
	Reference< XNameContainer > xNameCont(xdialogModel,UNO_QUERY);
	val <<= xbuttonModel;
// We insert first the button
	xNameCont->insertByName(OUString::createFromAscii("Button1") ,val); printf("First\n");
	val <<= xbuttonModel2;
	xNameCont->insertByName(OUString::createFromAscii("Button2") ,val); //printf("First\n");
// We insert now the ListBox control
	val <<= xlistBoxModel;
	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"));
	Reference< XControl > xControl(dialog,UNO_QUERY);
	Reference< XControlModel > xControlModel(xdialogModel,UNO_QUERY);
	xControl->setModel(xControlModel);

// adipan
	Sequence<OUString>seqStrlistItems(2);
	seqStrlistItems[0]=OUString::createFromAscii("Item1");
	seqStrlistItems[1]=OUString::createFromAscii("Item2");
	Reference< XControlContainer > xControlCont(dialog,UNO_QUERY);

	Reference <XInterface>  objectListBox=xControlCont->getControl(OUString::createFromAscii("Label1"));
	Reference< XControl > xListControl(objectListBox,UNO_QUERY);
	Reference< XListBox> xPSetListBox(xListControl,UNO_QUERY);
	xPSetListBox->removeItems(0, xPSetListBox->getItemCount());
	xPSetListBox->addItems ( seqStrlistItems, 0);
	xPSetListBox->selectItemPos (sal_Int16(0), sal_Bool(true) );
	xPSetListBox->makeVisible (sal_Int16(0));

// 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< XToolkit >xToolkit = Reference< XToolkit >( xServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "com.sun.star.awt.Toolkit" ))), UNO_QUERY );

	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;
}

Voir aussi les interfaces com.sun.star.lang.XMultiServiceFactory, com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader, com.sun.star.beans.XPropertySet, com.sun.star.container.XNameContainer, com.sun.star.awt.XControl, com.sun.star.awt.XControlModel, com.sun.star.awt.XControlContainer, com.sun.star.awt.XListBox, com.sun.star.awt.XButton, com.sun.star.awt.XActionListener, com.sun.star.awt.XToolkit, com.sun.star.awt.XWindow et com.sun.star.ui.dialogs.XDialog ainsi que le service com.sun.star.awt.UnoControlListBoxModel pour une bonne compréhension de ce programme.

Boîte de dialogue avec bouton radio

Il est possible d'ajouter un bouton radio. Les fichiers IDL que l'on doit soigneusement examiner sont d'abord le service com.sun.star.awt.UnoControlRadioButton, ce qui en résumé donne :

//Listing 33 UnoControlRadioButton Service : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
service UnoControlRadioButton
{
	service com::sun::star::awt::UnoControl;

	interface com::sun::star::awt::XRadioButton;

	interface com::sun::star::awt::XLayoutConstrains;

};
}; }; }; };

et ensuite le service com.sun.star.awt.UnoControlRadioButtonModel :

//Listing 34 UnoControlRadioButtonModel Service : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
service UnoControlRadioButtonModel
{
	service com::sun::star::awt::UnoControlModel;
	[property] boolean Enabled;
	[property] com::sun::star::awt::FontDescriptor FontDescriptor;
	[property] short FontEmphasisMark;
	[property] short FontRelief;
	[property] string HelpText;
	[property] string HelpURL;
	[property] string Label;
	[property] boolean Printable;

	/** specifies the state of the control.
		0: not checked
		1: checked	 */
	[property] short State;
	[property] boolean Tabstop;
	[property] long TextColor;
	[property] long TextLineColor;
};
}; }; }; };

Nos connaissances sont maintenant suffisamment avancées pour réaliser notre premier bouton radio.

1) Premièrement, créer le modèle correspondant :

//Listing 35 The Radio Button Control : an Example
// C++
// RadioButton
	Reference< XInterface > xRadioModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlRadioButtonModel"));
	Reference< XPropertySet > xPSetRadio(xRadioModel,UNO_QUERY);
	//val <<= (sal_Bool)true;
	//xPSetRadio->setPropertyValue(OUString::createFromAscii("Enabled"),val);
	value=20; val <<= value;
	xPSetRadio->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	xPSetRadio->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=10; val <<= value;
	xPSetRadio->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	xPSetRadio->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Lab1");
	xPSetRadio->setPropertyValue(OUString::createFromAscii("Label"),val);
	val <<=OUString::createFromAscii("Radio1");
	xPSetRadio->setPropertyValue(OUString::createFromAscii("Name"),val);
	value=20; val <<= value;
	xPSetRadio->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	//xPSetRadio->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)3));

2) Ajouter ce bouton radio dans la boîte de dialogue

//Listing 36 adding the Radio Control to the Dialog
// C++
// We insert now the radio button
	val <<= xRadioModel;
	xNameCont->insertByName(OUString::createFromAscii("Radio1") , val);

3) tester l'état du bouton avec un "event listener" assocé au bouton :

//Listing 37 The actionPerformed Event Listener
// C++
// XActionListener
virtual void SAL_CALL actionPerformed (const ::com::sun::star::awt::ActionEvent& rEvent ) throw ( RuntimeException) {
// increase click counter
	_nCounts++;
	printf("OK :  %d\n",_nCounts);
	OUString OUStr,OUStr2;
// look for radioButton
	Reference< XControl > label = _xControlCont->getControl(OUString::createFromAscii("Radio1"));
// Don't forget to add : #include <com/sun/star/awt/XRadioButton.hpp>
// Don't forget to add "com.sun.star.awt.XRadioButton \" in the makefile
	Reference< XRadioButton > xRadio(label,UNO_QUERY);
	sal_Bool state = xRadio->getState();
	if (state) OUStr2 = OUString::createFromAscii(" OK "); 
	else OUStr2 = OUString::createFromAscii(" NOK ");
// set label text
//	Reference< XControl > label = _xControlCont->getControl(OUString::createFromAscii("Label1"));
	label = _xControlCont->getControl(OUString::createFromAscii("Label1"));
// Don't forget to add : #include <com/sun/star/awt/XTextComponent.hpp>
// Don't forget to add "com.sun.star.awt.XTextComponent \" in the makefile
//	Reference< XFixedText > xLabel(label,UNO_QUERY); //OLD
	Reference< XTextComponent > xLabel(label,UNO_QUERY);
	xLabel->insertText (xLabel->getSelection(),
		OUString::createFromAscii("Text1 ") + OUStr.valueOf((sal_Int32)_nCounts)+OUStr2 +
		OUString::createFromAscii("\n"));
 }

Cet exemple écrit du texte dans une zone de texte :

An example of dialog with radio button

Mais avec ce code, nous pouvons cocher le bouton mais pas le décocher. Pour ce faire il nous faudrait écrire un "event listener". Mais comme d'habitude il nous faut trouver quel type d'"event listener" il nous faut mettre en oeuvre dans cette situation. Ceci est donné par l'interface idl>com.sun.star.awt.XRadioButton</idl> :

//Listing 38 XRadioButton Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
interface XRadioButton: com::sun::star::uno::XInterface
{
	[oneway] void addItemListener( [in] com::sun::star::awt::XItemListener l );
	[oneway] void removeItemListener( [in] com::sun::star::awt::XItemListener l );
	boolean getState();
	[oneway] void setState( [in] boolean b ); 
	[oneway] void setLabel( [in] string Label );  
};
}; }; }; };

qui nous montre qu'une recherche dans l'interface com.sun.star.awt.XItemEventListener est nécessaire :

//Listing 39 XItemListerner Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
interface XItemListener: com::sun::star::lang::XEventListener
{
	[oneway] void itemStateChanged( [in] com::sun::star::awt::ItemEvent rEvent );
};
}; }; }; };

Finalement on trouve le nom de notre méthode : itemStateChanged.

Exécuter une macro OOoBasic

Un premier exemple

Notre but est d'exécuter un sous-programme OOoBasic à partir du C++. Nous commençons par le message intéressant posté par Danny Brewer (http://www.oooforum.org/forum/viewtopic.php?p=20890#20890) : Dans le module Essai1 des macros OOo, je place ce sous-programme :

'Listing 133
REM  *****  BASIC  *****
Sub SaySomething( ) 
	MsgBox "Hello from OOoBasic" 
End Sub

Le code correspondant en OooBasic pour seulement exécuter ce sous-programme devrait être :

'Listing 134
REM  *****  BASIC  *****
Sub Main 
	oDispatch = createUnoService( "com.sun.star.frame.DispatchHelper" ) 
	oDispatch.executeDispatch( StarDesktop, "macro:///Standard.Module1.SaySomething()", 
		"", 0, Array() ) 
End Sub

Nous pouvons appeler directement ce sous-programme par son nom dans OOoBasic mais pas dans C++. Traduire ce code dans C++ est facile: nous donnons encore le listing complet qui utilise les interfaces com.sun.star.frame.XDispatchHelper, com.sun.star.frame.XDispatchProvider et le service com.sun.star.frame.DispatchHelper :

//Listing 135
// 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" );
    	}

	Reference< XDesktop > rDesktop(Desktop,UNO_QUERY);

// Don't forget to add : #include <com/sun/star/frame/XDispatchHelper.hpp>
// Don't forget to add "com.sun.star.frame.XDispatchHelper \" in the makefile
// Query the XDispatcher Interface
	Reference< XDispatchHelper > rDispatchHelper = Reference< XDispatchHelper >
				( rOfficeServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                        "com.sun.star.frame.DispatchHelper" ))), UNO_QUERY );


// Don't forget to add : #include <com/sun/star/frame/XDispatchProvider.hpp>
// Don't forget to add "com.sun.star.frame.XDispatchProvider \" in the makefile
// Query the XDispatchProvider Interface
	Reference< XDispatchProvider > rDispatchProvider(rDesktop,UNO_QUERY);

	Any any=rDispatchHelper->executeDispatch(rDispatchProvider,
			OUString::createFromAscii("macro:///Standard.Essai1.SaySomething()"),
			OUString::createFromAscii(""),
			0,
			Sequence < ::com::sun::star::beans::PropertyValue > ());
    return 0;
}

lequel affiche un message “Bonjour d'OOoBasic” mais retourne une erreur. Cette erreur est là seulement parce que le programme une fois terminé essaie de détruire les variables objets pendant qu'OOoBasic est toujours en marche ! Nous avons un processus complètement asynchrone.

XRay et C++

XRay est un outil d'introspection d'objets écrit en OOoBasic pour OOoBasic.Voir les Tutoriels Basic

Comme dans l'exemple précédent, nous pouvons naturellement appeler l'outil XRay depuis le C++. Ici nous expliquons comment faire cela. En premier il faut écrire un sub OOoBasic :

'Listing 136
REM  *****  BASIC  *****
Sub BernardXRay( x ) 
	oBJ = createUnoService(x)
	Xray oBJ
End Sub

dans le module “Essai1”, et en deuxième il faut écrire par exemple :

//Listing 137
// C++
...
	Reference< XDispatchHelper > rDispatchHelper = Reference< XDispatchHelper >
				( rOfficeServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                        "com.sun.star.frame.DispatchHelper" ))), UNO_QUERY );
...
	
	Any any=rDispatchHelper->executeDispatch(rDispatchProvider,
			OUString::createFromAscii(
				"macro:///Standard.Essai1.BernardXRay(com.sun.star.frame.DispatchHelper)"),
			OUString::createFromAscii(""),
			0,
			Sequence < ::com::sun::star::beans::PropertyValue > ());

La façon de faire cela est très inefficace comme explorateur d'objet. La liaison entre C++ et OOoBasic est trop lâche. Il n'y a aucune liaison entre la variable C++ rDispatchHelper et la variable oBJ OOoBasic. Une pourrait très bien être NULLE et pas la seconde. J'explorerai plus tard une autre façon avec un add-on pour faire une liaison entre OOoBasic et C++.

Aller plus loin

Notez que Christian Junker a écrit un exemple avec la nouvelle interface OOo2.0. Cet exemple permet au sous-programme OOoBasic de retourner une valeur, voir : How to call macro along with getting its return value (C++).

Retour à la page d'accueil

Page d'accueil du développement C++ à l'aide du SDK

Voir aussi

Personal tools