Difference between revisions of "FR/Documentation/Utilitaires C++"
SergeMoutou (Talk | contribs) m (→Boite de dialogue à l'exécution) |
|||
(31 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
=Jouer avec les fenêtres du toolkit= | =Jouer avec les fenêtres du toolkit= | ||
+ | {{Note|Cette section est ancienne (2005) : écrite longtemps avant que je découvre la nouvelle possibilité des composants et boîtes de dialogue dans le [[Documentation/DevGuide/WritingUNO/Accessing_Dialogs|Developer's Guide (2007)]]. Pour le moment (Mai 2009), je me suis contenté de [[FR/Documentation/Composants_et_boite_de_dialogue|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== | ==Explications de Danny Brewer== | ||
Il y a deux choses différentes ici. En réalité il y en a trois. | Il y a deux choses différentes ici. En réalité il y en a trois. | ||
Line 255: | Line 256: | ||
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs; | // 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 la directive : #include <com/sun/star/ui/dialogs/XFilePicker.hpp> | ||
− | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs | + | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilePicker \" dans le makefile |
// Query the XFilePicker interface | // Query the XFilePicker interface | ||
Line 267: | Line 268: | ||
// N'oubliez pas d'ajouter la directive : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> | // 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 | + | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.ExecutableDialogResults \" in the makefile |
if (result == ExecutableDialogResults::OK) | if (result == ExecutableDialogResults::OK) | ||
ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") , | ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") , | ||
Line 348: | Line 349: | ||
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs; | // 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 : #include <com/sun/star/ui/dialogs/XFilePicker.hpp> | ||
− | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs | + | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilePicker \" dans le makefile |
// Reference< XFilePicker > rFilePicker(rDesktop,UNO_QUERY); | // Reference< XFilePicker > rFilePicker(rDesktop,UNO_QUERY); | ||
Reference< XFilePicker > rFilePicker = Reference< XFilePicker > | Reference< XFilePicker > rFilePicker = Reference< XFilePicker > | ||
Line 358: | Line 359: | ||
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilterManager.hpp> | // N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilterManager.hpp> | ||
− | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs | + | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilterManager \" dans le makefile |
Reference< XFilterManager > rFilterManager (rFilePicker, UNO_QUERY); | Reference< XFilterManager > rFilterManager (rFilePicker, UNO_QUERY); | ||
rFilterManager->appendFilter(OUString::createFromAscii("Texts"), | rFilterManager->appendFilter(OUString::createFromAscii("Texts"), | ||
Line 368: | Line 369: | ||
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> | // N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> | ||
− | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs | + | // N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.ExecutableDialogResults \" dans le makefile |
if (result == ExecutableDialogResults::OK) | if (result == ExecutableDialogResults::OK) | ||
ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") , | ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") , | ||
rFilePicker->getFiles()[0] ); | rFilePicker->getFiles()[0] ); | ||
</source> | </source> | ||
+ | Voir les interfaces <idl>com.sun.star.ui.dialogs.XFilePicker</idl>, <idl>com.sun.star.ui.dialogs.XFilterManager</idl> et les constantes <idl>com.sun.star.ui.dialogs.ExecutableDialogResults</idl>. | ||
+ | |||
Il est temps de montrer comment faire une sauvegarde avec une boîte de Dialogue. | Il est temps de montrer comment faire une sauvegarde avec une boîte de Dialogue. | ||
Line 504: | Line 507: | ||
= Boite de dialogue à l'exécution = | = Boite de dialogue à l'exécution = | ||
− | Lire aussi le [[Documentation/DevGuide/Basic/Creating_Dialogs_at_Runtime|Developer's Guide]] et [[FR/Documentation/BASIC_Guide/Dialogs| Boîtes de dialogue]. | + | Lire aussi le [[Documentation/DevGuide/Basic/Creating_Dialogs_at_Runtime|Developer's Guide]] et [[FR/Documentation/BASIC_Guide/Dialogs| 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 : | 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 : | ||
Line 510: | Line 513: | ||
et le fichier SampleDialog.java correspondant. | et le fichier SampleDialog.java correspondant. | ||
− | {{ | + | {{Note|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 [[Documentation/DevGuide/WritingUNO/Using_Dialogs_in_Components|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 [[CppSDKAuthors|GAP]] donné [[Constructing_Helpers#The_GAP.27s_Helper|ici]]. Nous | + | Pour cet exemple nous utilisons l'aide de [[CppSDKAuthors|GAP]] donné [[Constructing_Helpers#The_GAP.27s_Helper|ici]]. Nous donnons maintenant le code complet mais puisqu'il est important en taille, il vous faudra vous documenter sur les interfaces <idl>com.sun.star.awt.XActionListener</idl>, <idl>com.sun.star.awt.XControlContainer</idl>, <idl>com.sun.star.lang.XMultiServiceFactory</idl>, <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.frame.XComponentLoader</idl>, <idl>com.sun.star.uno.XComponentContext</idl>, <idl>com.sun.star.lang.XMultiComponentFactory</idl>, <idl>com.sun.star.beans.XPropertySet</idl>, <idl>com.sun.star.container.XNameContainer</idl>, <idl>com.sun.star.awt.XButton</idl>, <idl>com.sun.star.awt.XToolkit</idl>, <idl>com.sun.star.awt.XWindow</idl>, <idl>com.sun.star.ui.dialogs.XDialog</idl> et aussi sur l'événement <idl>com.sun.star.awt.ActionEvent</idl>. Puisque nous avons décidé d'être complet, regardez donc aussi les services <idl>com.sun.star.frame.Desktop</idl>, <idl>com.sun.star.awt.UnoControlDialogModel</idl> et <idl>com.sun.star.awt.UnoControlButtonModel</idl>. Maintenant que vous avez fait le tour de la question, je donne le code : |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 17 Our first Run Time Dialog Box | //Listing 17 Our first Run Time Dialog Box | ||
Line 718: | Line 721: | ||
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. | 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 [[Documentation/FR/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable#Nouveau_code_comme_point_de_d.C3.A9part|ce code]] toujours comme point de départ) Voici maintenant les listings : on commence par l'intercepteur d'événements : | + | Cet exemple est construit comme toujours, sans "helper" (en utilisant [[Documentation/FR/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable#Nouveau_code_comme_point_de_d.C3.A9part|ce code]] toujours comme point de départ) Voici maintenant les listings : on commence par l'intercepteur d'événements (voir les interfaces <idl>com.sun.star.awt.XActionListener</idl>, <idl>com.sun.star.awt.XControlContainer</idl> <idl>com.sun.star.awt.XFixedText</idl>) : |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 18 The Action performed Event Listener | //Listing 18 The Action performed Event Listener | ||
Line 760: | Line 763: | ||
}; | }; | ||
</source> | </source> | ||
− | 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 : | + | 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 (<idl>com.sun.star.awt.XFixedText</idl>) : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 19 XFixedText Interface : IDL File | //Listing 19 XFixedText Interface : IDL File | ||
Line 926: | Line 929: | ||
[[Image:Dialog2.png|none|thumb|295px|An example of dialog with edit control]] | [[Image:Dialog2.png|none|thumb|295px|An example of dialog with edit control]] | ||
− | On doit jeter un oeil dans les fichiers IDL correspondants. On commence par l'interface | + | On doit jeter un oeil dans les fichiers IDL correspondants. On commence par l'interface <idl>com.sun.star.awt.XTextComponent</idl>. |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 21 XTextComponent Interface : IDL File | //Listing 21 XTextComponent Interface : IDL File | ||
Line 951: | Line 954: | ||
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) | 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 UnoControlEditModel dans le fichier UnoControlEditModel.idl : | + | Nous montrons maintenant le service <idl>com.sun.star.awt.UnoControlEditModel</idl> dans le fichier UnoControlEditModel.idl : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 22 UnoControlEditModel Service : IDL File | //Listing 22 UnoControlEditModel Service : IDL File | ||
Line 997: | Line 1,000: | ||
.... | .... | ||
</source> | </source> | ||
− | et ensuite je remplace le service | + | et ensuite je remplace le service “<idl>com.sun.star.awt.UnoControlFixedTextModel</idl>” par "<idl>com.sun.star.awt.UnoControlEditModel</idl>". Cela est réalisé avec le code : |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 24 The UnoControlEditModel : an Example | //Listing 24 The UnoControlEditModel : an Example | ||
Line 1,024: | Line 1,027: | ||
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". | 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 "PushButtonType". Les valeurs prises par cette propriété sont encore et toujours données par un fichier IDL : | + | La propriété à changer est "<idl>com.sun.star.awt.PushButtonType</idl>". Les valeurs prises par cette propriété sont encore et toujours données par un fichier IDL : |
<source lang="idl"> | <source lang="idl"> | ||
Listing 25 PushButtonType enumeration : IDL File | Listing 25 PushButtonType enumeration : IDL File | ||
Line 1,097: | Line 1,100: | ||
Selected Item Pos :0 | Selected Item Pos :0 | ||
</pre> | </pre> | ||
− | 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 XListBox : | + | 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 <idl>com.sun.star.awt.XListBox</idl> : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 28 XListBox Interface : IDL File | //Listing 28 XListBox Interface : IDL File | ||
Line 1,137: | Line 1,140: | ||
Nous nous concentrons maintenant sur le code C++. | Nous nous concentrons maintenant sur le code C++. | ||
− | '''Premièrement création d'un"event listener"''' : | + | '''Premièrement création d'un intercepteur d'événements ("event listener")''' : |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 29 Our new Action performed Listener | //Listing 29 Our new Action performed Listener | ||
Line 1,177: | Line 1,180: | ||
}; | }; | ||
</source> | </source> | ||
− | Cet " | + | 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). | 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). | ||
Line 1,337: | Line 1,340: | ||
} | } | ||
</source> | </source> | ||
+ | Voir aussi les interfaces <idl>com.sun.star.lang.XMultiServiceFactory</idl>, <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.frame.XComponentLoader</idl>, <idl>com.sun.star.beans.XPropertySet</idl>, <idl>com.sun.star.container.XNameContainer</idl>, <idl>com.sun.star.awt.XControl</idl>, <idl>com.sun.star.awt.XControlModel</idl>, <idl>com.sun.star.awt.XControlContainer</idl>, <idl>com.sun.star.awt.XListBox</idl>, <idl>com.sun.star.awt.XButton</idl>, <idl>com.sun.star.awt.XActionListener</idl>, <idl>com.sun.star.awt.XToolkit</idl>, | ||
+ | <idl>com.sun.star.awt.XWindow</idl> et <idl>com.sun.star.ui.dialogs.XDialog</idl> ainsi que le service <idl>com.sun.star.awt.UnoControlListBoxModel</idl> pour une bonne compréhension de ce programme. | ||
== Boîte de dialogue avec bouton radio== | == 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 : | + | Il est possible d'ajouter un bouton radio. Les fichiers IDL que l'on doit soigneusement examiner sont d'abord le service <idl>com.sun.star.awt.UnoControlRadioButton</idl>, ce qui en résumé donne : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 33 UnoControlRadioButton Service : IDL File | //Listing 33 UnoControlRadioButton Service : IDL File | ||
Line 1,355: | Line 1,360: | ||
}; }; }; }; | }; }; }; }; | ||
</source> | </source> | ||
− | et | + | et ensuite le service <idl>com.sun.star.awt.UnoControlRadioButtonModel</idl> : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 34 UnoControlRadioButtonModel Service : IDL File | //Listing 34 UnoControlRadioButtonModel Service : IDL File | ||
Line 1,451: | Line 1,456: | ||
[[Image:Dialog3.png|none|thumb|310px|An example of dialog with radio button]] | [[Image:Dialog3.png|none|thumb|310px|An example of dialog with radio button]] | ||
− | Mais avec ce code, nous pouvons | + | 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> : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 38 XRadioButton Interface : IDL File | //Listing 38 XRadioButton Interface : IDL File | ||
Line 1,467: | Line 1,472: | ||
</source> | </source> | ||
− | qui nous montre qu'une recherche dans l'interface XItemEventListener est nécessaire : | + | qui nous montre qu'une recherche dans l'interface <idl>com.sun.star.awt.XItemEventListener</idl> est nécessaire : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 39 XItemListerner Interface : IDL File | //Listing 39 XItemListerner Interface : IDL File | ||
Line 1,502: | Line 1,507: | ||
</source> | </source> | ||
Nous pouvons appeler directement ce sous-programme par son nom dans OOoBasic mais pas dans C++. | 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 : | + | Traduire ce code dans C++ est facile: nous donnons encore le listing complet qui utilise les interfaces <idl>com.sun.star.frame.XDispatchHelper</idl>, <idl>com.sun.star.frame.XDispatchProvider</idl> et le service <idl>com.sun.star.frame.DispatchHelper</idl> : |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 135 | //Listing 135 | ||
Line 1,549: | Line 1,554: | ||
</source> | </source> | ||
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. | 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 et C++== | ||
− | XRay est un outil d' | + | XRay est un outil d'introspection d'objets écrit en OOoBasic pour OOoBasic.[http://www.openoffice.org/fr/Documentation/Basic/ 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. | Comme dans l'exemple précédent, nous pouvons naturellement appeler l'outil XRay depuis le C++. Ici nous expliquons comment faire cela. | ||
Line 1,559: | Line 1,565: | ||
Sub BernardXRay( x ) | Sub BernardXRay( x ) | ||
oBJ = createUnoService(x) | oBJ = createUnoService(x) | ||
− | + | Xray oBJ | |
End Sub | End Sub | ||
</source> | </source> | ||
Line 1,582: | Line 1,588: | ||
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++. | 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 : [http://www.oooforum.org/forum/viewtopic.phtml?t=27453 How to call macro along with getting its return value (C++)]. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | / | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
= Retour à la page d'accueil= | = Retour à la page d'accueil= | ||
Line 1,740: | Line 1,596: | ||
=Voir aussi = | =Voir aussi = | ||
− | * [ | + | * [[Documentation/DevGuide/Basic/Creating_Dialogs_at_Runtime|Creating Dialogs at Runtime]] in Developer's Guide |
+ | * [[FR/Documentation/BASIC_Guide/Dialogs|Boîtes de dialogue]] en OOoBasic et aussi dans le [[Documentation/DevGuide/Basic/Programming_Dialogs_and_Dialog_Controls|Developer's Guide]] | ||
* [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]] | * [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]] | ||
*[[Tutorial_UNO_Library|UNO tutorial]] | *[[Tutorial_UNO_Library|UNO tutorial]] | ||
Line 1,750: | Line 1,607: | ||
* [[Framework/Article/Generic_UNO_Interfaces_for_complex_toolbar_controls|Generic UNO Interfaces for complex toolbar controls]] | * [[Framework/Article/Generic_UNO_Interfaces_for_complex_toolbar_controls|Generic UNO Interfaces for complex toolbar controls]] | ||
* Writing a Program to Control OpenOffice.org, by Franco Pingiori — [http://www.linuxjournal.com/article/8550 Part 1] and [http://www.linuxjournal.com/article/8608 Part 2], Linux Journal | * Writing a Program to Control OpenOffice.org, by Franco Pingiori — [http://www.linuxjournal.com/article/8550 Part 1] and [http://www.linuxjournal.com/article/8608 Part 2], Linux Journal | ||
+ | |||
+ | [[Category:FR/Cpp_Guide]] |
Latest revision as of 17:02, 4 July 2018
Contents
Jouer avec les fenêtres du toolkit
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.
- Les dialogues
- AWT
- 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.
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 :
- créer un service "dialog model", avec la variable dialogModel dans le code ci-dessus
- demander une interface XPropertySet pour positionner les propriétés (positions x et y, taille, titre, ..)
- 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
- demander une interface XNameContainer en partant du "dialog model"
- insérer tous les modèles de contrôle dans le modèle de dialogue avec le conteneur
- crééer un controle dialogue et demander une interface XControl puis l'interface XControlModedl pour positionner correctement le modèlel
- ajouter des "action listener" si nécessaires
- 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 :
Boîte de dialogue avec une zone de texte
On veut maintenant construire la boite de dialogue montrée ci-dessous.
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 :
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
- Creating Dialogs at Runtime in Developer's Guide
- Boîtes de dialogue en OOoBasic et aussi dans le Developer's Guide
- C++ and UNO tutorial
- UNO tutorial
- UNO IDL
- Uno/Article/Types&Reflection
- Popup Menu Controller and C++
- Statusbar Controler and C++
- The New Tree Contol
- Generic UNO Interfaces for complex toolbar controls
- Writing a Program to Control OpenOffice.org, by Franco Pingiori — Part 1 and Part 2, Linux Journal