Difference between revisions of "FR/Documentation/L'automation d'OpenOffice.org avec un binaire exécutable"
SergeMoutou (Talk | contribs) m (→Save the Document) |
|||
(109 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
− | Nous voulons maintenant nous attaquer | + | Nous voulons maintenant nous attaquer à un programme entier en UNO/OpenOffice.org. Ce programme effectuera quelques tâches sur des documents OpenOffice.org, chargements de fichiers, modifications de fichiers, sauvegardes de fichiers.... |
− | + | =Introduction à partir d'un exemple du SDK= | |
+ | == Introduction aux services et interfaces== | ||
+ | Avant de commencer, il me faut vous parler de l'organisation de l'API UNO et particulièrement de la distinction entre services et interfaces. Un service est un ensemble d'interfaces. Tous les deux sont caractérisés par des noms commençant par "com.sun.star" puis d'un nom de module ".lang" par exemple et enfin du nom du service ou de l'interface. Pour faire la distrinction entre les deux un nom d'interface commencera toujours par un X. Par exemple , <idl>com.sun.star.lang.ServiceManager</idl> est un service et un clic sur le lien vous montre qu'il contient plusieurs interfaces dont <idl>com.sun.star.lang.XServiceInfo</idl> qui est bien une interface puisque le nom commence par X. Voir des compléments dans [[FR/Documentation/BASIC_Guide/Modules%2C_Services_and_Interfaces|Modules, services et interfaces]] dans le document de programmation OOoBasic. | ||
+ | |||
+ | ==Programmer l'API UNO== | ||
Danny Brewer a écrit dans le forum sur Openoffice :[http://www.oooforum.org/forum/viewtopic.php?t=5252 ici]. | Danny Brewer a écrit dans le forum sur Openoffice :[http://www.oooforum.org/forum/viewtopic.php?t=5252 ici]. | ||
Pour faire quelque chose d'utile avec OOo à travers l'API, dans la plupart des cas, cela nécessite soit de créer, soit d'ouvrir un nouveau document. Ensuite vous aimeriez manipuler le contenu du document, en extraire de l'information, l'imprimer, le convertir en un autre format, travailler avec des données d'un formulaire ou encore réaliser d'autres tâches sur les documents. | Pour faire quelque chose d'utile avec OOo à travers l'API, dans la plupart des cas, cela nécessite soit de créer, soit d'ouvrir un nouveau document. Ensuite vous aimeriez manipuler le contenu du document, en extraire de l'information, l'imprimer, le convertir en un autre format, travailler avec des données d'un formulaire ou encore réaliser d'autres tâches sur les documents. | ||
Pour cela la première chose à apprendre est comment ouvrir ou créer des documents. | Pour cela la première chose à apprendre est comment ouvrir ou créer des documents. | ||
− | Les objets ServiceManager et Desktop | + | Les objets <idl>com.sun.star.lang.ServiceManager</idl> et <idl>com.sun.star.frame.Desktop</idl> sont parmi ceux qu'il faut savoir utiliser. Pour pouvoir travailler avec OOo avec l'API, vous devez obtenir deux objets absolument essentiels |
+ | |||
+ | 1. le <idl>com.sun.star.lang.ServiceManager</idl>, (gestionnaire de service) | ||
− | + | 2. le <idl>com.sun.star.frame.Desktop</idl> (le bureau) | |
− | + | ||
− | 2. le Desktop (le bureau) | + | |
− | Une fois le ServiceManager obtenu,un appel à sa | + | Le processus qui permet d'obtenir un <code>ServiceManager</code>, s'appelle un "bootstrap" [[Documentation/FR/L%27automation_d%27OpenOffice.org_avec_un_binaire_ex%C3%A9cutable#Introduction_au_Bootstrapping|décrit plus loin]]. Une fois le <idl>com.sun.star.lang.ServiceManager</idl>, obtenu,un appel à sa méthode createInstance() permet d'obtenir l'objet <code>Desktop</code>. Une fois obtenu cet objet <idl>com.sun.star.frame.Desktop</idl>, vous pouvez l'utiliser pour créer ou ouvrir des nouveaux documents. Voir un complément sur le Desktop en OOoBasic [[FR/Documentation/BASIC_Guide/StarDesktop|ici]]. |
− | Une fois obtenu cet objet Desktop, vous pouvez l'utiliser pour créer ou ouvrir des nouveaux documents. | + | |
− | + | ==Obtenir le gestionnaire de services == | |
− | + | Pour chaque différent langage, il y a un mécanisme permettant d' acquérir le “Service Manager.” | |
Le moyen d'obtenir le service manager est donné dans l'exemple SDK : | Le moyen d'obtenir le service manager est donné dans l'exemple SDK : | ||
<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding | <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding | ||
− | + | Commençons par notre premier exemple (sous Linux) : | |
− | {{ | + | {{Lin| |
<pre> | <pre> | ||
cd <OpenOffice.org1.1_SDK> | cd <OpenOffice.org1.1_SDK> | ||
Line 32: | Line 35: | ||
Sous windows, cela donnerait : | Sous windows, cela donnerait : | ||
− | {{ | + | {{Win| |
<pre> | <pre> | ||
cd <OpenOffice.org1.1_SDK> | cd <OpenOffice.org1.1_SDK> | ||
setsdkenv_windows | setsdkenv_windows | ||
− | cd examples | + | cd examples\DevelopersGuide\ProfUNO\CppBinding |
make | make | ||
make Office_connect.run | make Office_connect.run | ||
Line 42: | Line 45: | ||
}} | }} | ||
− | Nous commencerons notre travail à partir de cet exemple. Tout les listings que nous donnerons sont à ajouter à cet exemple. Où ça? Ceci montré maintenant : | + | Nous commencerons notre travail à partir [[Documentation/DevGuide/ProUNO/C%2B%2B/Establishing_Interprocess_Connections|de cet exemple]]. Tout les listings que nous donnerons sont à ajouter à cet exemple. Où ça? Ceci montré maintenant : |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 14 | //Listing 14 | ||
Line 85: | Line 88: | ||
printf( "Connected sucessfully to the office\n" ); | printf( "Connected sucessfully to the office\n" ); | ||
− | // ***** | + | |
+ | // ***** METTEZ votre code ici ********************************************* | ||
} | } | ||
catch( Exception &e ) | catch( Exception &e ) | ||
Line 96: | Line 100: | ||
} | } | ||
</source> | </source> | ||
− | Je ne peux pas expliquer complètement toutes les lignes de ce fichier source. Je peux juste dire que | + | Je ne peux pas expliquer complètement toutes les lignes de ce fichier source, mais si vous voulez déjà vous faire une idée de ce qui vous attend en programmation UNO, vous pouvez quand même aller consulter les interfaces qui apparaissent les unes après les autres dans ce code, à savoir : <idl>com.sun.star.uno.XComponentContext</idl>, |
+ | <idl>com.sun.star.lang.XMultiComponentFactory</idl>, <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.bridge.XUnoUrlResolver</idl>. | ||
+ | |||
+ | Je peux juste dire que ce code n'est qu'un moyen parmi d'autres d'obtenir le “Service Manager”. Une autre façon de le faire est donnée dans l'exemple du SDK : <OpenOffice.org1.1_SDK>/examples/cpp/DocumentLoader. | ||
+ | |||
+ | Avant de continuer, faisons quelques remarques didactiques (voir aussi [[FR/Documentation/BASIC_Guide/API_Intro| ici]]). Ce code vous montre, même si vous ne le comprenez pas, le travail qui nous sera nécessaire pour faire de la programmation UNO. Vous devrez écrire du code C++ parsemé de variables étranges comme : | ||
+ | <source lang="cpp"> | ||
+ | Reference< XQuelqueChose > rQuelqueChose = un_Moyen_D_Obenir_Le_QuelqueChose; | ||
+ | </source> | ||
+ | Dans ce morceau de code XQuelqueChose représente une interface car son nom commence par un X. Vous avez dans le code ci-dessus deux moyens pour obtenir des interfaces : | ||
+ | <source lang="cpp"> | ||
+ | // obtenir une interface premier moyen :fonction toute faite | ||
+ | Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext(); | ||
+ | </source> | ||
+ | et aussi | ||
+ | <source lang="cpp"> | ||
+ | // obtenir une interface deuxième moyen :UNO_QUERY à parir d'un service | ||
+ | Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY ); | ||
+ | </source> | ||
+ | Comment je sais que je suis parti d'un service ? Son nom ne commence pas par un X, c'est donc un service, comme je l'ai expliqué en début de chapitre. Et si vous voulez l'obtenir, en C++ il vous faudra le transtyper dans une variable de type <idl>com.sun.star.uno.XInterface</idl> (c'est ce qui s'est passé pour la variable rResolver de l'exemple ci-dessus). | ||
+ | |||
+ | {{Note| | ||
+ | Le langage C++ ne permet donc pas l'utilisation directe de services, mais plutôt des interfaces. Tout service devra être transtypé dans une variable de type <idl>com.sun.star.uno.XInterface</idl>. Ce n'est pas le cas du OOoBasic qui au contraire vous permet d'utiliser les services directement. | ||
+ | }} | ||
+ | Le lecteur intéressé par des explications plus détaillées peut lire la section suivante. | ||
− | + | == Introduction au Bootstrapping == | |
− | Le Bootstrap (désolé je garde la terminologie anglaise) est discuté plus en détail [[ | + | Le Bootstrap (désolé je garde la terminologie anglaise) est discuté plus en détail [[Documentation/FR/Base_de_registres#Le_d.C3.A9marrage_.28Bootstrap.29|plus tard]]. Nous nous contenterons donc d'une introduction maintenant. Le bootstrap est le mécanisme qui permet d'obtenir un service manager. |
− | {{ | + | {{Note| |
Le service manager est un composant qui, comme son nom l'indique, permet la gestion des services. Chaque service est composé de plusieurs interfaces et en C++ il n'est pas possible de faire quoi que ce soit avec UNO sans avoir obtenu du service manager l'interface correspondante. | Le service manager est un composant qui, comme son nom l'indique, permet la gestion des services. Chaque service est composé de plusieurs interfaces et en C++ il n'est pas possible de faire quoi que ce soit avec UNO sans avoir obtenu du service manager l'interface correspondante. | ||
}} | }} | ||
Line 107: | Line 135: | ||
[[Image:ch4Fig1bootstrap.png|none|thumb|600px|Bootstrapping]] | [[Image:ch4Fig1bootstrap.png|none|thumb|600px|Bootstrapping]] | ||
− | {{ | + | {{Warn|Comme tous les schémas, sa compréhension nécessite de connaître toutes les conventions qu'il utilise. Je pense changer de conventions dans le futur en m'inspirant du nouvel inspecteur d'objet Java [[Object Inspector|(New Object Inspector)]] disponible maintenant. Pour comprendre où je veux en venir, reportez-vous à la section correspondante [[Documentation/FR/OpenOffice_Writer#Aller_plus_loin_avec_l.27Inspector_Java|sur l'Inspecteur et OOoWriter]].}} |
− | Si vous êtes intéressé, regardez simultanément le code et le dessin pour comprendre les conventions pour réaliser la figure ci-dessus. Par exemple, les deux interfaces XInterface sont connectées parcequ'on utilise la même variable en fait. Les rectangles | + | Si vous êtes intéressé, regardez simultanément le code et le dessin pour comprendre les conventions pour réaliser la figure ci-dessus. Par exemple, les deux interfaces XInterface sont connectées par une double flèche parcequ'on utilise la même variable en fait. Les rectangles remplis en gris sont réservés aux paramètres... etc... |
− | On veut maintenant | + | On veut maintenant l'objet desktop (bureau) afin de charger un composant tableur OooCalc. Décrivons les choses étapes par étapes. |
La '''première étape''' est d'obtenir le desktop. Vous ajouter ensuite ce code : | La '''première étape''' est d'obtenir le desktop. Vous ajouter ensuite ce code : | ||
<source lang="cpp"> | <source lang="cpp"> | ||
− | // Listing 2 | + | // Listing 2 Obtenir le service desktop |
+ | // desktop est un service car il ne commence pas par un X | ||
// C++ | // C++ | ||
Reference< XInterface > xDesktop = rOfficeServiceManager->createInstance( | Reference< XInterface > xDesktop = rOfficeServiceManager->createInstance( | ||
Line 122: | Line 151: | ||
</source> | </source> | ||
Votre objet desktop est la variable xDesktop. | Votre objet desktop est la variable xDesktop. | ||
+ | |||
+ | {{Note|Notez qu'un service sera toujours transtypé en une interface XInterface et aussi qu'il est rare que l'on utilise un service en C++.}} | ||
'''Deuxième étape''' : demande de l'interface XComponentLoader | '''Deuxième étape''' : demande de l'interface XComponentLoader | ||
<source lang="cpp"> | <source lang="cpp"> | ||
− | // Listing 3 | + | // Listing 3 demande de l'interface XComponentLoader |
// C++ | // C++ | ||
// query a XcomponentLoader Interface | // query a XcomponentLoader Interface | ||
Line 132: | Line 163: | ||
if( rComponentLoader.is() ) | if( rComponentLoader.is() ) | ||
{ | { | ||
− | printf( " | + | printf( "XComponentloader succesfully instanciated\n" ); |
} | } | ||
</source> | </source> | ||
Avant d'examiner les problèmes avec ce code, nous en donnons une représentation schématique : | Avant d'examiner les problèmes avec ce code, nous en donnons une représentation schématique : | ||
− | [[Image:ch4fig2Componentloader.png|none|thumb|600px| | + | [[Image:ch4fig2Componentloader.png|none|thumb|600px|Obtention de l'interface XComponentLoader]] |
Le code ci-dessus produit malheureusement les messages d'erreur suivant : | Le code ci-dessus produit malheureusement les messages d'erreur suivant : | ||
Line 143: | Line 174: | ||
error 'XcomponentLoader' undeclared (First use this function) .... | error 'XcomponentLoader' undeclared (First use this function) .... | ||
</pre> | </pre> | ||
− | Cela nous montre l'existance d'un problème avec XComponentLoader : cela indique que vous avez probablement à ajouter une inclusion d'un fichier hpp dans votre programme à l'aide des "include". Le nom du fichier concerné est probablement XComponentLoader.hpp mais nous avons à trouver son chemin complet. Une façon est d'utiliser l' [http://api.openoffice.org/docs/common/ref/index-files/index-1.html index général] et d'y chercher XComponentLoader. On trouve alors : | + | Cela nous montre l'existance d'un problème avec XComponentLoader : cela indique que vous avez probablement à ajouter une inclusion d'un fichier hpp dans votre programme à l'aide des "include". Le nom du fichier concerné est probablement XComponentLoader.hpp mais nous avons à trouver son chemin complet. Une façon est d'utiliser l'[http://api.openoffice.org/docs/common/ref/index-files/index-1.html index général] et d'y chercher XComponentLoader. On trouve alors : <idl>com.sun.star.frame.XComponentLoader</idl> qui nous permet de déduire que la directive |
<source lang="cpp"> | <source lang="cpp"> | ||
#include <com/sun/star/frame/XComponentLoader.hpp> | #include <com/sun/star/frame/XComponentLoader.hpp> | ||
</source> | </source> | ||
− | est | + | est requise. Un essai nous permet de constater que ce n'est pas suffisant puisque le même message d'erreur que précédemment est encore obtenu : |
<pre> | <pre> | ||
com/sun/star/frame/XComponentLoader.hpp: No such file or directory | com/sun/star/frame/XComponentLoader.hpp: No such file or directory | ||
</pre> | </pre> | ||
− | J'ai déjà discuté ce fait : le SDK ne fournit pas les fichiers hpp mais seulement | + | {{Note| |
+ | J'ai déjà discuté ce fait : le SDK ne fournit pas les fichiers hpp mais seulement le moyen de les construire à partir des fichiers IDL. Il vous faudra donc ouvrir et changer le fichier "makefile" si vous avez opté pour une installation qui ne construit pas en une fois l'arborescence des fichiers d'inclusions. | ||
+ | }} | ||
+ | Regardez comme cela est réalisé ci-dessous avec l'ajout d'une ligne : | ||
<pre> | <pre> | ||
#added com.sun.star.frame.XComponentLoader | #added com.sun.star.frame.XComponentLoader | ||
Line 171: | Line 205: | ||
com.sun.star.container.XHierarchicalNameAccess | com.sun.star.container.XHierarchicalNameAccess | ||
</pre> | </pre> | ||
− | Construisant le projet donne toujours le même message d'erreur. Qu'est-ce qui manque maintenant ? | + | Construisant le projet donne toujours le même message d'erreur. Qu'est-ce qui manque encore maintenant ? |
− | Seulement une instruction de nommage qui nous donne le résultat final : | + | Seulement une directive permettant l'utilisation de l'espace de nom correspondant. Je l'appellerai parfois instruction de nommage (ce qui n'est pas vraiment français) et cela nous donne le résultat final : |
<source lang="cpp"> | <source lang="cpp"> | ||
// C++ | // C++ | ||
using namespace com::sun::star::frame; | using namespace com::sun::star::frame; | ||
</source> | </source> | ||
− | (Pour aller plus loin avec ces deux étapes voir [[ | + | (Pour aller plus loin avec ces deux étapes voir [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Obtention_d.27une_interface_en_C.2B.2B|Obtention d'une interface en C++]]) |
'''étape 3''' : obtenir une instance du tableur | '''étape 3''' : obtenir une instance du tableur | ||
Line 192: | Line 226: | ||
et cela fonctionne : vous avez un nouveau document OOoCalc vierge. | et cela fonctionne : vous avez un nouveau document OOoCalc vierge. | ||
− | Cet [[ | + | Cet [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Obtention_d.27une_interface_en_C.2B.2B|hyperlien]] abordera de nouveau le problème de la construction des fichiers d'inclusion. |
Une autre chose à noter est : quand vous construisez des variables avec le modèle Reference comme cela est fait dans l'extrait de code ci-dessous : | Une autre chose à noter est : quand vous construisez des variables avec le modèle Reference comme cela est fait dans l'extrait de code ci-dessous : | ||
Line 202: | Line 236: | ||
varName.is() | varName.is() | ||
</pre> | </pre> | ||
− | Le problème de choisir quoi faire en cas d'échec de la création de la variable (varName.is() est faux) est complexe | + | Le problème de choisir quoi faire en cas d'échec de la création de la variable (varName.is() est faux) est complexe et pas abordé complètement dans ce document. Il réfère aux exceptions. |
− | == | + | =La chaîne de compilation= |
+ | La chaîne de compilation désigne dans ce document une vue graphique (et simplifiée) des fichiers "makefile". Cela vous donne de l'information sur quels sont les types de fichiers transformés et à l'aide de quels outils vous allez pouvoir construire un binaire qui utilise l'interface UNO. Il est très important de connaître la chaîne de compilation si vous voulez modifier un makefile. Si vous n'en n'avez pas l'intention, sauter cette section. | ||
− | + | Pour les amateurs, regardez toutes les opérations réalisées pour réaliser et exécuter un fichier binaire. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | [[Image:CompilationChain2.png|center|UNO binary build chain]] | |
− | + | ||
− | + | Notez que l'utilisation de <code>regmerge</code> et <code>regcomp</code> pour la création du fichier office_connect.rdb [[Documentation/FR/Base_de_registres#La_cr.C3.A9ation_de_office_connect.rdb|est décrite ici]]. | |
− | + | Le point important dans cette chaîne de compilation est l'utilisation de <code>cppumaker</code> pour construire l'ensemble des fichiers d'extension hdl et hpp dont vous aurez besoin pour construire votre application. | |
− | + | La réalisation d'un makefile à ce stade nécessitera donc la gestion des binaires <code>regmerge</code>, <code>regcomp</code>, <code>cppumaker</code> ainsi que <code>gcc</code>. | |
+ | Vous pouvez trouver d'autres descriptions de chaîne de compilation [[Documentation/FR/Construire_des_composants#Cha.C3.AEne_de_compilation_d.27un_composant|ici dans ce Wiki]] et aussi [[Counter_Example|ici (en anglais)]]. Je vais probablement réserver dans le futur un chapitre sur les fichiers "makefile" dans un [[Make|Make Chapter]]. | ||
− | + | On peut aussi trouver une description de chaîne de compilation dans le tutorial sur Java et Eclipse [[JavaEclipseTuto|ici]] et montrée ci-dessous : | |
− | + | [[Image:CompilationChain.png|center|UNO component build chain]] | |
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | {{Tip|Nous n'utilisons pas la même représentation schématique des fichiers et outils binaires dans nos propres chaînes de description. Je trouve celle-ci plus compacte que la mienne mais pour le moment, faute de temps, je n'envisage pas encore de changer : peut-être dans le futur.}} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | = Nouveau code comme point de départ = | |
− | + | Le style de programmation présenté dans l'[[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]] ne me satisfait pas complètement. Je l'ai donné parce qu'il est plus facile de commencer des explications à partir d'un exemple fourni avec le SDK que de partir directement d'un code nouveau. Je trouve la fonction de [[CppSDKAuthors|Niall Dorgan]] meilleure dans [http://www.oooforum.org/forum/viewtopic.php?t=8664 oooforum.org]. Alors j'ai décidé d'adopter son style légèrement modifié : une fonction est entièrement responsable de la connection : ooConnect() et je la présente maintenant avec le programme principal associé. | |
+ | == La fonction ooConnect()== | ||
+ | Nous donnons pour commencer la fonction ooConnect() : | ||
+ | {{:OOConnectFR}} | ||
+ | == Le programme principal== | ||
+ | Nous donnons maintenant le programme principal à modifier (le "main()") : | ||
+ | {{Warn|N'oubliez pas de changer la chaîne de caractères "private:factory/scalc" en "private:factory/swriter" ou "private:factory/sdraw" suivant l'application OpenOffice que vous ciblez.}} | ||
− | + | {{:MainOOConnectFR}} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | {{Note|Prenez ce code et mettez-le dans le fichier office_connect.cxx du répertoire <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding (en prenant soin de renommer et sauver le fichier initial office_connect.cxx) et vous pouvez utiliser le fichier "makefile" légèrement modifié de l'[[UNO_automation_with_a_binary_%28executable%29#Introduction_:_starting_from_a_SDK_example |introduction]] pour compiler le projet. A partir de maintenant j'utiliserai toujours ce code comme point de départ. Cela signifie que je donnerai tout ou partie de code qu'il faudra insérer dans ce programme.}} | |
− | + | ||
− | + | ||
− | + | Aller plus loin dans la compréhension consiste à comprendre l'obtention des interfaces. Comme déjà mentionné dans cette section, cette explication est disponible [[FR/Documentation/Fichiers_IDL_et_C%2B%2B#Obtention_d.27une_interface_en_C.2B.2B|ici]]. Cet hyperlien n'est cependant pas pour les débutants. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | = Trouver et sauver un document = | |
− | + | Si vous voulez des détails sur Desktop, vous pouvez lire [[FR/Documentation/BASIC_Guide/Documents|Utilisation de documents OpenOffice.org]] qui vous aidera à comprendre en partie notre code de départ. | |
− | Toute cette section est basée sur le | + | Toute cette section est basée sur le remplacement du code C++ donné dans le Listing 6. Ce code est à repérer et à changer dans le Listing 5. |
<source lang="cpp"> | <source lang="cpp"> | ||
Line 404: | Line 292: | ||
</source> | </source> | ||
Les deux paramètres "private:factory/scalc" et “_blank” peuvent être changés. Voyant les conséquences de ces changements. | Les deux paramètres "private:factory/scalc" et “_blank” peuvent être changés. Voyant les conséquences de ces changements. | ||
− | + | ==Chargement d'un fichier existant == | |
− | Pour charger un fichier existant, | + | Pour charger un fichier existant, remplacer le code du Listing 6 par |
− | {{ | + | {{Lin| |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 7 Chargment d'un fichier | //Listing 7 Chargment d'un fichier | ||
Line 418: | Line 306: | ||
Sequence < ::com::sun::star::beans::PropertyValue >()); | Sequence < ::com::sun::star::beans::PropertyValue >()); | ||
</source> | </source> | ||
+ | dans le listing 5. | ||
}} | }} | ||
− | Vous | + | Vous voulez charger ou prendre un fichier déjà ouvert de même nom, changez alors le paramètre “_blank” : |
− | {{ | + | {{Lin| |
<source lang="cpp"> | <source lang="cpp"> | ||
− | //Listing 8 | + | //Listing 8 Changer le prametre _blank |
// C++ | // C++ | ||
//get an instance of the spreadsheet | //get an instance of the spreadsheet | ||
Line 434: | Line 323: | ||
}} | }} | ||
Le nom du fichier est compatible UNIX. Sous Windows on peut utiliser l'équivalence | Le nom du fichier est compatible UNIX. Sous Windows on peut utiliser l'équivalence | ||
− | {{ | + | {{Win| |
<pre> | <pre> | ||
C:\My Documents\tata.sxc file:///C|/My%20Documents/tata.sxc | C:\My Documents\tata.sxc file:///C|/My%20Documents/tata.sxc | ||
Line 441: | Line 330: | ||
A gauche le nom de fichier qui est fortement dépendant du système et à droite ce que l'on appelle URL. UNO utilise seulement les URL, soit vous retenez sa syntaxe particulière, soit vous les construisez de manière automatique : | A gauche le nom de fichier qui est fortement dépendant du système et à droite ce que l'on appelle URL. UNO utilise seulement les URL, soit vous retenez sa syntaxe particulière, soit vous les construisez de manière automatique : | ||
− | {{ | + | {{Lin| |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 9 Constructing an URL | //Listing 9 Constructing an URL | ||
Line 450: | Line 339: | ||
osl::FileBase::getFileURLFromSystemPath( | osl::FileBase::getFileURLFromSystemPath( | ||
OUString::createFromAscii("/home/smoutou/edt.sxd"),sDocUrl); | OUString::createFromAscii("/home/smoutou/edt.sxd"),sDocUrl); | ||
+ | //get an instance of the spreadsheet | ||
+ | Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( | ||
+ | sDocUrl, | ||
+ | OUString::createFromAscii("_blank"), | ||
+ | 0, | ||
+ | Sequence < ::com::sun::star::beans::PropertyValue >()); | ||
+ | </source> | ||
+ | }} | ||
+ | ou le programme Windows correspondant : | ||
+ | {{Win| | ||
+ | <source lang="cpp"> | ||
+ | //Listing 9b Constructing an URL | ||
// Windows C++ to check | // Windows C++ to check | ||
− | // osl | + | // Don't forget #include <osl/file.hxx> |
− | / | + | |
+ | OUString sDocUrl; | ||
+ | osl::FileBase::getFileURLFromSystemPath( | ||
+ | OUString::createFromAscii("C:\My Documents\tata.sxc"),sDocUrl); | ||
//get an instance of the spreadsheet | //get an instance of the spreadsheet | ||
Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( | Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( | ||
Line 483: | Line 386: | ||
D'autres transformations sont possibles : voir la documentation osl::FileBase dans http://api.openoffice.org/docs/cpp/ref/names/osl/c-FileBase.html | D'autres transformations sont possibles : voir la documentation osl::FileBase dans http://api.openoffice.org/docs/cpp/ref/names/osl/c-FileBase.html | ||
− | + | == Créer un nouveau document == | |
Il vous faut choisir votre type de document et utiliser la chaîne de caractères magique pour remplacer "private:factory/scalc" : | Il vous faut choisir votre type de document et utiliser la chaîne de caractères magique pour remplacer "private:factory/scalc" : | ||
− | ; | + | ; chaîne magique |
{| border cellspacing="0" width="550" | {| border cellspacing="0" width="550" | ||
|- style = "background:#b3e2d1;text-align:center" | |- style = "background:#b3e2d1;text-align:center" | ||
Line 494: | Line 397: | ||
| Tableur Calc ||private:factory/scalc | | Tableur Calc ||private:factory/scalc | ||
|- style="text-align:center" | |- style="text-align:center" | ||
− | | | + | | Dessin||private:factory/sdraw |
|- style="text-align:center" | |- style="text-align:center" | ||
− | | | + | | Présentation Impress ||private:factory/simpress |
|- style="text-align:center" | |- style="text-align:center" | ||
| Ecriture de formules Mathématiques ||private:factory/smath | | Ecriture de formules Mathématiques ||private:factory/smath | ||
|} | |} | ||
− | + | == Document par défaut (déjà ouvert)== | |
Le moyen d'obtenir le document par défaut est légèrement différent des deux sections précédentes. Nous commençons par donner les lignes de programme à changer puis les changements effectifs à réaliser. | Le moyen d'obtenir le document par défaut est légèrement différent des deux sections précédentes. Nous commençons par donner les lignes de programme à changer puis les changements effectifs à réaliser. | ||
− | Pour trouver le document par défaut, changer le code précédent donner à nouveau ci-dessous en Listing 11 par celui du Listing 12. | + | Pour trouver le document par défaut, changer le code précédent donner à nouveau ci-dessous en Listing 11 par celui du Listing 12 en n'oubliant pas de regarder la documentation des interfaces <idl>com.sun.star.uno.XInterface</idl>, <idl>com.sun.star.frame.XComponentLoader</idl> et <idl>com.sun.star.lang.XComponent</idl> correspondantes. |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 11 Finding the default Document : code to remove | //Listing 11 Finding the default Document : code to remove | ||
Line 545: | Line 448: | ||
==Sauver le Document== | ==Sauver le Document== | ||
− | Dans les exemples de cette section je vais demander une nouvelle interface : l'interface XStorable. | + | Dans les exemples de cette section je vais demander une nouvelle interface : l'interface <idl>com.sun.star.frame.XStorable</idl>. |
Il vous est donc possible de sauver en ajoutant ce nouveau code | Il vous est donc possible de sauver en ajoutant ce nouveau code | ||
<source lang="cpp"> | <source lang="cpp"> | ||
Line 560: | Line 463: | ||
</source> | </source> | ||
Il est aussi possible de donner un nom en sauvegardant : | Il est aussi possible de donner un nom en sauvegardant : | ||
− | {{ | + | {{Win| |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 14 How to store a Document (Windows version) | //Listing 14 How to store a Document (Windows version) | ||
Line 578: | Line 481: | ||
}} | }} | ||
ou | ou | ||
− | {{ | + | {{Lin| |
<source lang="cpp"> | <source lang="cpp"> | ||
//Listing 15 How to store a Document (Linux Version) | //Listing 15 How to store a Document (Linux Version) | ||
Line 595: | Line 498: | ||
}} | }} | ||
− | Nous sommes maintenant prêt pour décrire | + | Nous sommes maintenant prêt pour décrire toutes les applications Openoffice.org. Nous allons commencer par Calc mais avant de commencer regardons à nouveau le Desktop. |
+ | |||
+ | = Ma première énumération de Conteneur avec Desktop= | ||
+ | Les conteneurs sont un concept important de la programmation OOo parceque vous les trouvez partout. Par exemple dans un tableur toutes les feuilles sont dans un conteneur, dans Draw toutes les pages sont dans un conteneur, dans une page toutes les formes (rectangles, cercles,...) sont dans un conteneur et ainsi de suite. | ||
+ | ==L'interface XEnumerationAccess== | ||
+ | |||
+ | Plutôt de grands discours nous commençons par donner un exemple de code qui utilise les interfaces <idl>com.sun.star.frame.XDesktop</idl>, <idl>com.sun.star.container.XEnumerationAccess</idl>, <idl>com.sun.star.lang.XServiceInfo</idl> et <idl>com.sun.star.frame.XStorable </idl> : | ||
+ | <source lang="cpp"> | ||
+ | //Listing 16 L'interface XEnumeration | ||
+ | // C++ | ||
+ | // container | ||
+ | // Ne pas oublier d'ajouter : using namespace com::sun::star::frame; | ||
+ | // Ne pas oublier la directive : #include <com/sun/star/frame/XDesktop.hpp> | ||
+ | // Ne pas oublier d'ajouter "com.sun.star.frame.XDesktop \" dans le makefile | ||
+ | |||
+ | // otention de l'interface XDesktop (et non du service Desktop) | ||
+ | Reference<XDesktop> desk(xServiceManager->createInstance( | ||
+ | OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY); | ||
+ | |||
+ | // Ne pas oublier d'ajouter : using namespace com::sun::star::container; | ||
+ | // Ne pas oublier la directive : #include <com/sun/star/container/XEnumerationAccess.hpp> | ||
+ | // Ne pas oublier d'ajouter "com.sun.star.container.XEnumerationAccess \" dans le makefile | ||
+ | Reference<XEnumerationAccess> comps = desk->getComponents(); | ||
+ | if (comps->hasElements()) { | ||
+ | Reference<XEnumeration> compenum(comps->createEnumeration(), UNO_QUERY); | ||
+ | while (compenum->hasMoreElements()) { | ||
+ | Reference<XComponent> comp(compenum->nextElement(), UNO_QUERY); | ||
+ | |||
+ | // Ne pas oublier d'ajouter : using namespace com::sun::star::lang; | ||
+ | // Ne pas oublier la directive: #include <com/sun/star/lang/XServiceInfo.hpp> | ||
+ | // Ne pas oublier d'ajouter "com.sun.star.lang.XServiceInfo \" dans le makefile | ||
+ | Reference<XServiceInfo> serviceinfo(comp, UNO_QUERY); | ||
+ | if (serviceinfo->supportsService( | ||
+ | OUString::createFromAscii("com.sun.star.document.OfficeDocument"))) { | ||
+ | |||
+ | // Ne pas oublier la directive: #include <com/sun/star/frame/XStorable.hpp> | ||
+ | // Ne pas oublier d'ajouter "com.sun.star.frame.XStorable \" dans le makefile | ||
+ | Reference<XStorable> storeable(comp, UNO_QUERY); | ||
+ | if (storeable->hasLocation()) { | ||
+ | OString loc = OUStringToOString(storeable->getLocation(), | ||
+ | RTL_TEXTENCODING_ASCII_US); | ||
+ | printf("-- %s\n",loc.pData->buffer); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | Ce programme affiche : | ||
+ | {{Lin| | ||
+ | <pre> | ||
+ | -- file:///home/smoutou/OpenOffice.org1.1_SDK/UNOCpp_AP01.sxw | ||
+ | -- file:///home/smoutou/Inetrecup/Openoffice/01prog_menu-context_officebean2.sxw | ||
+ | </pre> | ||
+ | }} | ||
+ | dépendant naturellement de quels fichiers sont chargés et de quel système d'exploitation vous disposez. | ||
+ | |||
+ | ==L'interface XIndexAccess== | ||
+ | En général il y a deux moyens d'accéder aux éléments d'un conteneur, avec un index (numérique) ou par son nom. Les interfaces correspondantes sont XIndexAccess et XNameAccess. Si vous voulez savoir ce que vous pouvez faire avec une interface, cherchez le fichier IDL correspondant. Les fichiers IDL sont expliqués plus tard dans le document ([[Documentation/FR/Fichiers_IDL_et_C%2B%2B|voir ici]]). Par exemple, nous donnons le fichier IDL de l'interface <idl>com.sun.star.container.XIndexAcess</idl> (en retirant tous les commentaires) : | ||
+ | <source lang="idl"> | ||
+ | //Listing 17 XIndexAccess IDL File (without Comments) | ||
+ | // IDL | ||
+ | module com { module sun { module star { module container { | ||
+ | interface XIndexAccess: com::sun::star::container::XElementAccess | ||
+ | { | ||
+ | long getCount(); | ||
+ | any getByIndex( [in] long Index ) | ||
+ | raises( com::sun::star::lang::IndexOutOfBoundsException, | ||
+ | com::sun::star::lang::WrappedTargetException ); | ||
+ | |||
+ | }; | ||
+ | }; }; }; }; | ||
+ | </source> | ||
+ | |||
+ | Le chemin pour trouver ce fichier IDL peut être retrouvé avec le contenu de ce fichier : <OpenOffice.org1.1_SDK>/idl/com/sun/star/container | ||
+ | et le nom du fichier est celui de l'interface avec l'extension “.idl”. | ||
+ | Deux méthodes peuvent être utilisées : getCount() et getByIndex() comme on peut facilement le voir sur le listing ci-dessus. | ||
+ | |||
+ | Voir aussi <idl>com.sun.star.container.XElementAccess</idl>. | ||
+ | |||
+ | ==L'interface XNameAccess== | ||
+ | La deuxième interface d'accès est quant à elle décrite par <idl>com.sun.star.container.XNameAccess</idl>: | ||
+ | <source lang="idl"> | ||
+ | //Listing 18 XNameAccess IDL file (without Comments) | ||
+ | // IDL | ||
+ | module com { module sun { module star { module container { | ||
+ | interface XNameAccess: com::sun::star::container::XElementAccess | ||
+ | { | ||
+ | any getByName( [in] string aName ) | ||
+ | raises( com::sun::star::container::NoSuchElementException, | ||
+ | com::sun::star::lang::WrappedTargetException ); | ||
+ | sequence<string> getElementNames(); | ||
+ | boolean hasByName( [in] string aName ); | ||
+ | }; | ||
+ | }; }; }; }; | ||
+ | </source> | ||
+ | qui montre trois méthodes. Notre but dans cette section est de voir le desktop comme un conteneur. Il peut effectivement contenir des fenêtres. Voir aussi <idl>com.sun.star.container.XElementAccess</idl>. | ||
+ | |||
+ | =Ce qui n'est pas toujours très clair pour moi= | ||
+ | |||
+ | Plus tard, je vais décrire un [[Constructing_Helpers#Reflection_Helper|"reflection helper"]]. Il nous permet de connaître les méthodes et propriétés d'un objet... | ||
+ | Quand j'utilise ce programme pour regarder les méthodes de l'objet “Desktop” je vois clairement la méthode getComponents(). Mais je ne peux pas l'appeler directement. Il me faut construire une variable desktop nommée “desk” dans le listing ci-dessus avant de l'appeler. | ||
+ | {{Note| | ||
+ | Une relecture plus fine des remarques précédentes me montre que la variable "desktop" est en fait un service tandis que la variable "desk" est une interface. En C++ il vous faut utiliser les interfaces (et pas les services) tandis qu'en OOoBasic vous utilisez les services. Tout cela sera revu [[Documentation/FR/Fichiers_IDL_et_C%2B%2B|plus en détail ici]]. | ||
+ | }} | ||
+ | |||
+ | On n'a pas besoin d'un “#include <com/sun/star/lang/XComponent.hpp>” et je ne comprends pas bien pourquoi ! En général on se trouve dans ce cas lorsque l'interface est obtenue à partir d'une méthode d'une précédente interface, mais ici ce n'est pas tout à fait le cas. | ||
+ | |||
+ | Vous pouvez trouver des explications [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#IDL__et_C.2B.2B|ici]] écrites après les lignes ci-dessus (réservées aux non débutants). | ||
+ | |||
+ | =Ce que nous avons appris dans ce chapitre= | ||
+ | Je suis toujours plus intéressé par les figures que par les longues explications. Cependant les schémas sont faciles à comprendre seulement si vous prenez le temps d'y chercher toutes les conventions qui s'y trouvent. Si ce n'est pas le cas, relisez l'introduction de ce chapitre. | ||
+ | |||
+ | Nous donnons donc un schéma résumant tout ce qui a été appris dans ce chapitre. | ||
+ | |||
+ | [[Image:ch4fig3Summary.png]] | ||
+ | |||
+ | == Retour à la page d'accueil== | ||
+ | |||
+ | [[Documentation/FR/Cpp_Guide|Page d'accueil du développement C++ à l'aide du SDK]] | ||
+ | |||
+ | == Voir aussi == | ||
+ | * [[FR/Documentation/BASIC_Guide/API_Intro|Introduction à l'API StarOffice]] | ||
+ | * [[FR/Documentation/BASIC_Guide/Documents|Utilisation de documents StarOffice]] en OOoBasic | ||
+ | * [[Uno/Cpp/Tutorials/Introduction_to_Cpp_Uno|C++ and UNO tutorial]] | ||
+ | * To learn C++ : [http://www.smart2help.com/e-books/ C++ e-books] | ||
+ | * 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 21:15, 14 July 2018
Nous voulons maintenant nous attaquer à un programme entier en UNO/OpenOffice.org. Ce programme effectuera quelques tâches sur des documents OpenOffice.org, chargements de fichiers, modifications de fichiers, sauvegardes de fichiers....
Contents
Introduction à partir d'un exemple du SDK
Introduction aux services et interfaces
Avant de commencer, il me faut vous parler de l'organisation de l'API UNO et particulièrement de la distinction entre services et interfaces. Un service est un ensemble d'interfaces. Tous les deux sont caractérisés par des noms commençant par "com.sun.star" puis d'un nom de module ".lang" par exemple et enfin du nom du service ou de l'interface. Pour faire la distrinction entre les deux un nom d'interface commencera toujours par un X. Par exemple , com.sun.star.lang.ServiceManager est un service et un clic sur le lien vous montre qu'il contient plusieurs interfaces dont com.sun.star.lang.XServiceInfo qui est bien une interface puisque le nom commence par X. Voir des compléments dans Modules, services et interfaces dans le document de programmation OOoBasic.
Programmer l'API UNO
Danny Brewer a écrit dans le forum sur Openoffice :ici. Pour faire quelque chose d'utile avec OOo à travers l'API, dans la plupart des cas, cela nécessite soit de créer, soit d'ouvrir un nouveau document. Ensuite vous aimeriez manipuler le contenu du document, en extraire de l'information, l'imprimer, le convertir en un autre format, travailler avec des données d'un formulaire ou encore réaliser d'autres tâches sur les documents. Pour cela la première chose à apprendre est comment ouvrir ou créer des documents. Les objets com.sun.star.lang.ServiceManager et com.sun.star.frame.Desktop sont parmi ceux qu'il faut savoir utiliser. Pour pouvoir travailler avec OOo avec l'API, vous devez obtenir deux objets absolument essentiels
1. le com.sun.star.lang.ServiceManager, (gestionnaire de service)
2. le com.sun.star.frame.Desktop (le bureau)
Le processus qui permet d'obtenir un ServiceManager
, s'appelle un "bootstrap" décrit plus loin. Une fois le com.sun.star.lang.ServiceManager, obtenu,un appel à sa méthode createInstance() permet d'obtenir l'objet Desktop
. Une fois obtenu cet objet com.sun.star.frame.Desktop, vous pouvez l'utiliser pour créer ou ouvrir des nouveaux documents. Voir un complément sur le Desktop en OOoBasic ici.
Obtenir le gestionnaire de services
Pour chaque différent langage, il y a un mécanisme permettant d' acquérir le “Service Manager.” Le moyen d'obtenir le service manager est donné dans l'exemple SDK : <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding Commençons par notre premier exemple (sous Linux) :
cd <OpenOffice.org1.1_SDK> ./setsdkenv_unix cd examples/DevelopersGuide/ProfUNO/CppBinding make make Office_connect.run |
qui écrit seulement : "Connected successfully to the office". Mais c'est déjà pas mal ? Non ?
Sous windows, cela donnerait :
cd <OpenOffice.org1.1_SDK> setsdkenv_windows cd examples\DevelopersGuide\ProfUNO\CppBinding make make Office_connect.run |
Nous commencerons notre travail à partir de cet exemple. Tout les listings que nous donnerons sont à ajouter à cet exemple. Où ça? Ceci montré maintenant :
//Listing 14 //C++ *** extract from office_connect.cxx int main( ) { // create the initial component context Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext(); // retrieve the servicemanager from the context Reference< XMultiComponentFactory > rServiceManager = rComponentContext->getServiceManager(); // instantiate a sample service with the servicemanager. Reference< XInterface > rInstance = rServiceManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ), rComponentContext ); // Query for the XUnoUrlResolver interface Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY ); if( ! rResolver.is() ) { printf( "Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service\n" ); return 1; } try { // resolve the uno-url rInstance = rResolver->resolve( OUString::createFromAscii( "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) ); if( ! rInstance.is() ) { printf( "StarOffice.ServiceManager is not exported from remote counterpart\n" ); return 1; } // query for the simpler XMultiServiceFactory interface, sufficient for scripting Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY); if( ! rInstance.is() ) { printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" ); return 1; } printf( "Connected sucessfully to the office\n" ); // ***** METTEZ votre code ici ********************************************* } catch( Exception &e ) { OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); printf( "Error: %s\n", o.pData->buffer ); return 1; } return 0; }
Je ne peux pas expliquer complètement toutes les lignes de ce fichier source, mais si vous voulez déjà vous faire une idée de ce qui vous attend en programmation UNO, vous pouvez quand même aller consulter les interfaces qui apparaissent les unes après les autres dans ce code, à savoir : com.sun.star.uno.XComponentContext, com.sun.star.lang.XMultiComponentFactory, com.sun.star.uno.XInterface, com.sun.star.bridge.XUnoUrlResolver.
Je peux juste dire que ce code n'est qu'un moyen parmi d'autres d'obtenir le “Service Manager”. Une autre façon de le faire est donnée dans l'exemple du SDK : <OpenOffice.org1.1_SDK>/examples/cpp/DocumentLoader.
Avant de continuer, faisons quelques remarques didactiques (voir aussi ici). Ce code vous montre, même si vous ne le comprenez pas, le travail qui nous sera nécessaire pour faire de la programmation UNO. Vous devrez écrire du code C++ parsemé de variables étranges comme :
Reference< XQuelqueChose > rQuelqueChose = un_Moyen_D_Obenir_Le_QuelqueChose;
Dans ce morceau de code XQuelqueChose représente une interface car son nom commence par un X. Vous avez dans le code ci-dessus deux moyens pour obtenir des interfaces :
// obtenir une interface premier moyen :fonction toute faite Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext();
et aussi
// obtenir une interface deuxième moyen :UNO_QUERY à parir d'un service Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY );
Comment je sais que je suis parti d'un service ? Son nom ne commence pas par un X, c'est donc un service, comme je l'ai expliqué en début de chapitre. Et si vous voulez l'obtenir, en C++ il vous faudra le transtyper dans une variable de type com.sun.star.uno.XInterface (c'est ce qui s'est passé pour la variable rResolver de l'exemple ci-dessus).
Le langage C++ ne permet donc pas l'utilisation directe de services, mais plutôt des interfaces. Tout service devra être transtypé dans une variable de type com.sun.star.uno.XInterface. Ce n'est pas le cas du OOoBasic qui au contraire vous permet d'utiliser les services directement. |
Le lecteur intéressé par des explications plus détaillées peut lire la section suivante.
Introduction au Bootstrapping
Le Bootstrap (désolé je garde la terminologie anglaise) est discuté plus en détail plus tard. Nous nous contenterons donc d'une introduction maintenant. Le bootstrap est le mécanisme qui permet d'obtenir un service manager.
Mémoriser le code de la section précédente est difficile et probablement inutile. Cependant, nous en donnons une représentation graphique pour en montrer les principales étapes.
Comme tous les schémas, sa compréhension nécessite de connaître toutes les conventions qu'il utilise. Je pense changer de conventions dans le futur en m'inspirant du nouvel inspecteur d'objet Java (New Object Inspector) disponible maintenant. Pour comprendre où je veux en venir, reportez-vous à la section correspondante sur l'Inspecteur et OOoWriter. |
Si vous êtes intéressé, regardez simultanément le code et le dessin pour comprendre les conventions pour réaliser la figure ci-dessus. Par exemple, les deux interfaces XInterface sont connectées par une double flèche parcequ'on utilise la même variable en fait. Les rectangles remplis en gris sont réservés aux paramètres... etc...
On veut maintenant l'objet desktop (bureau) afin de charger un composant tableur OooCalc. Décrivons les choses étapes par étapes.
La première étape est d'obtenir le desktop. Vous ajouter ensuite ce code :
// Listing 2 Obtenir le service desktop // desktop est un service car il ne commence pas par un X // C++ Reference< XInterface > xDesktop = rOfficeServiceManager->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
Votre objet desktop est la variable xDesktop.
Notez qu'un service sera toujours transtypé en une interface XInterface et aussi qu'il est rare que l'on utilise un service en C++. |
Deuxième étape : demande de l'interface XComponentLoader
// Listing 3 demande de l'interface XComponentLoader // C++ // query a XcomponentLoader Interface Reference< XComponentLoader > rComponentLoader (xDesktop, UNO_QUERY); if( rComponentLoader.is() ) { printf( "XComponentloader succesfully instanciated\n" ); }
Avant d'examiner les problèmes avec ce code, nous en donnons une représentation schématique :
Le code ci-dessus produit malheureusement les messages d'erreur suivant :
error 'XcomponentLoader' undeclared (First use this function) ....
Cela nous montre l'existance d'un problème avec XComponentLoader : cela indique que vous avez probablement à ajouter une inclusion d'un fichier hpp dans votre programme à l'aide des "include". Le nom du fichier concerné est probablement XComponentLoader.hpp mais nous avons à trouver son chemin complet. Une façon est d'utiliser l'index général et d'y chercher XComponentLoader. On trouve alors : com.sun.star.frame.XComponentLoader qui nous permet de déduire que la directive
#include <com/sun/star/frame/XComponentLoader.hpp>
est requise. Un essai nous permet de constater que ce n'est pas suffisant puisque le même message d'erreur que précédemment est encore obtenu :
com/sun/star/frame/XComponentLoader.hpp: No such file or directory
Regardez comme cela est réalisé ci-dessous avec l'ajout d'une ligne :
#added com.sun.star.frame.XComponentLoader TYPES := \ com.sun.star.uno.XNamingService \ com.sun.star.uno.XComponentContext \ com.sun.star.uno.XWeak \ com.sun.star.uno.XAggregation \ com.sun.star.frame.XComponentLoader \ com.sun.star.lang.XMain \ com.sun.star.lang.XMultiServiceFactory \ com.sun.star.lang.XSingleComponentFactory \ com.sun.star.lang.XTypeProvider \ com.sun.star.lang.XComponent \ com.sun.star.registry.XSimpleRegistry \ com.sun.star.registry.XImplementationRegistration \ com.sun.star.bridge.XBridgeFactory \ com.sun.star.bridge.XUnoUrlResolver \ com.sun.star.container.XHierarchicalNameAccess
Construisant le projet donne toujours le même message d'erreur. Qu'est-ce qui manque encore maintenant ? Seulement une directive permettant l'utilisation de l'espace de nom correspondant. Je l'appellerai parfois instruction de nommage (ce qui n'est pas vraiment français) et cela nous donne le résultat final :
// C++ using namespace com::sun::star::frame;
(Pour aller plus loin avec ces deux étapes voir Obtention d'une interface en C++)
étape 3 : obtenir une instance du tableur
// Listing 4 Créer un nouveau document OOoCalc // C++ Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( OUString::createFromAscii("private:factory/scalc"), OUString::createFromAscii("_blank"), 0, Sequence < ::com::sun::star::beans::PropertyValue >());
et cela fonctionne : vous avez un nouveau document OOoCalc vierge.
Cet hyperlien abordera de nouveau le problème de la construction des fichiers d'inclusion.
Une autre chose à noter est : quand vous construisez des variables avec le modèle Reference comme cela est fait dans l'extrait de code ci-dessous :
Reference<...>varName
vous disposez en contrepartie de la possibilité de tester la réussite de la construction avec la fonction :
varName.is()
Le problème de choisir quoi faire en cas d'échec de la création de la variable (varName.is() est faux) est complexe et pas abordé complètement dans ce document. Il réfère aux exceptions.
La chaîne de compilation
La chaîne de compilation désigne dans ce document une vue graphique (et simplifiée) des fichiers "makefile". Cela vous donne de l'information sur quels sont les types de fichiers transformés et à l'aide de quels outils vous allez pouvoir construire un binaire qui utilise l'interface UNO. Il est très important de connaître la chaîne de compilation si vous voulez modifier un makefile. Si vous n'en n'avez pas l'intention, sauter cette section.
Pour les amateurs, regardez toutes les opérations réalisées pour réaliser et exécuter un fichier binaire.
Notez que l'utilisation de regmerge
et regcomp
pour la création du fichier office_connect.rdb est décrite ici.
Le point important dans cette chaîne de compilation est l'utilisation de cppumaker
pour construire l'ensemble des fichiers d'extension hdl et hpp dont vous aurez besoin pour construire votre application.
La réalisation d'un makefile à ce stade nécessitera donc la gestion des binaires regmerge
, regcomp
, cppumaker
ainsi que gcc
.
Vous pouvez trouver d'autres descriptions de chaîne de compilation ici dans ce Wiki et aussi ici (en anglais). Je vais probablement réserver dans le futur un chapitre sur les fichiers "makefile" dans un Make Chapter.
On peut aussi trouver une description de chaîne de compilation dans le tutorial sur Java et Eclipse ici et montrée ci-dessous :
Nouveau code comme point de départ
Le style de programmation présenté dans l'introduction ne me satisfait pas complètement. Je l'ai donné parce qu'il est plus facile de commencer des explications à partir d'un exemple fourni avec le SDK que de partir directement d'un code nouveau. Je trouve la fonction de Niall Dorgan meilleure dans oooforum.org. Alors j'ai décidé d'adopter son style légèrement modifié : une fonction est entièrement responsable de la connection : ooConnect() et je la présente maintenant avec le programme principal associé.
La fonction ooConnect()
Nous donnons pour commencer la fonction ooConnect() :
// Listing 0 // C++ #include <stdio.h> #include <cppuhelper/bootstrap.hxx> #include <com/sun/star/bridge/XUnoUrlResolver.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> // on ajoute la ligne ci-apres #include <com/sun/star/frame/XComponentLoader.hpp> using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::bridge; // ajouté aussi : using namespace com::sun::star::frame; using namespace rtl; using namespace cppu; // appel de la fonction de démarrage Reference< XMultiServiceFactory > ooConnect(){ // create the initial component context Reference< XComponentContext > rComponentContext = defaultBootstrap_InitialComponentContext(); // obtention du servicemanager à partir du context Reference< XMultiComponentFactory > rServiceManager = rComponentContext->getServiceManager(); // instantiate a sample service with the servicemanager. Reference< XInterface > rInstance = rServiceManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ),rComponentContext ); // Query for the XUnoUrlResolver interface Reference< XUnoUrlResolver > rResolver( rInstance, UNO_QUERY ); if( ! rResolver.is() ){ printf( "Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service\n" ); return NULL; } try { // resolve the uno-url rInstance = rResolver->resolve( OUString::createFromAscii( "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ) ); if( ! rInstance.is() ){ printf( "StarOffice.ServiceManager is not exported from remote counterpart\n" ); return NULL; } // query for the simpler XMultiServiceFactory interface, sufficient for scripting Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY); if( ! rOfficeServiceManager.is() ){ printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" ); return NULL; } return rOfficeServiceManager; } catch( Exception &e ){ OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ); printf( "Error: %s\n", o.pData->buffer ); return NULL; } return NULL; }
Il serait bon de regarder aussi :
- les interfaces com.sun.star.uno.XComponentContext, com.sun.star.lang.XMultiComponentFactory, com.sun.star.uno.XInterface, com.sun.star.bridge.XUnoUrlResolver et com.sun.star.lang.XMultiServiceFactory,
- et aussi le service com.sun.star.bridge.UnoUrlResolver.
Le programme principal
Nous donnons maintenant le programme principal à modifier (le "main()") :
N'oubliez pas de changer la chaîne de caractères "private:factory/scalc" en "private:factory/swriter" ou "private:factory/sdraw" suivant l'application OpenOffice que vous ciblez. |
// code C++ //Listing 0b Notre programme principal int main( ) { //retrouve une instance service manager distant avec notre ooConnect() Reference< XMultiServiceFactory > rOfficeServiceManager; rOfficeServiceManager = ooConnect(); if( rOfficeServiceManager.is() ){ printf( "Connecté avec succès à OpenOffice\n" ); } //get the desktop service using createInstance returns an XInterface type Reference< XInterface > Desktop = rOfficeServiceManager->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" )); //demande de l'interface XComponentLoader interface Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY); if( rComponentLoader.is() ){ printf( "XComponentloader successfully instanciated\n" ); } //get an instance of the spreadsheet Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( OUString::createFromAscii("private:factory/scalc"), OUString::createFromAscii("_blank"), 0, Sequence < ::com::sun::star::beans::PropertyValue >()); //********************************* // c'est ici que l'on rajoute le code présenté dans ce chapitre; //********************************* return 0; }
Ce code est appelé un programme d'amorce ou de démarrage et utilise :
- les interfaces com.sun.star.lang.XMultiServiceFactory, com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader et com.sun.star.lang.XComponent interfaces
- le service com.sun.star.frame.Desktop,
- la structure UNO com.sun.star.beans.PropertyValue.
Rappelez-vous que chaque fois que vous demandez une interface vous devez ajouter des lignes de code si elles n'existent pas dans le code source ainsi que dans le makefile. Je vais en général ajouter des commentaires pour éviter les omissions.
Note importante : Le point le plus important dans la chaîne de compilation des exemples ci-après est que l'utilitaire cppumaker construira chacun des fichiers d'inclusion hpp et hdl que votre application utilisera. Le SDK ne fournit pas les fichiers hpp, mais vous devez les construire à partir des fichiers IDL qui eux sont fournis avec le SDK.
|
Il est possible de construire tous les fichiers d'inclusion hpp lors de l'installation du SDK comme j'ai eu l'occasion de le mentionner pour l'installation sous Windows. C'est naturellement possible aussi avec les autres systèmes d'exploitation. En procédant ainsi il ne vous faudra plus modifier votre MakeFile (sauf peut-être le chemin pour atteindre ces fichiers). |
Prenez ce code et mettez-le dans le fichier office_connect.cxx du répertoire <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding (en prenant soin de renommer et sauver le fichier initial office_connect.cxx) et vous pouvez utiliser le fichier "makefile" légèrement modifié de l'introduction pour compiler le projet. A partir de maintenant j'utiliserai toujours ce code comme point de départ. Cela signifie que je donnerai tout ou partie de code qu'il faudra insérer dans ce programme. |
Aller plus loin dans la compréhension consiste à comprendre l'obtention des interfaces. Comme déjà mentionné dans cette section, cette explication est disponible ici. Cet hyperlien n'est cependant pas pour les débutants.
Trouver et sauver un document
Si vous voulez des détails sur Desktop, vous pouvez lire Utilisation de documents OpenOffice.org qui vous aidera à comprendre en partie notre code de départ.
Toute cette section est basée sur le remplacement du code C++ donné dans le Listing 6. Ce code est à repérer et à changer dans le Listing 5.
//Listing 6 Créer un nouveau composant //C++ //get an instance of the spreadsheet Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( OUString::createFromAscii("private:factory/scalc"), OUString::createFromAscii("_blank"), 0, Sequence < ::com::sun::star::beans::PropertyValue >());
Les deux paramètres "private:factory/scalc" et “_blank” peuvent être changés. Voyant les conséquences de ces changements.
Chargement d'un fichier existant
Pour charger un fichier existant, remplacer le code du Listing 6 par
Vous voulez charger ou prendre un fichier déjà ouvert de même nom, changez alors le paramètre “_blank” :
Le nom du fichier est compatible UNIX. Sous Windows on peut utiliser l'équivalence
A gauche le nom de fichier qui est fortement dépendant du système et à droite ce que l'on appelle URL. UNO utilise seulement les URL, soit vous retenez sa syntaxe particulière, soit vous les construisez de manière automatique :
ou le programme Windows correspondant :
Une autre possibilité est de construire l'URL à partir d'un nom de fichier et de son chemin
//Listing 10 Constructing an URL : an other Way // C++ LINUX and Windows // Don't forget #include <osl/file.hxx> // Don't forget #include <osl/process.hxx> OUString sDocUrl, sWorkingDir; osl_getProcessWorkingDir(&sWorkingDir.pData); osl::FileBase::getAbsoluteFileURL( sWorkingDir, OUString::createFromAscii("edt.sxd"), sDocUrl); //get an instance of the spreadsheet Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( sDocUrl, OUString::createFromAscii("_blank"), 0, Sequence < ::com::sun::star::beans::PropertyValue >());
où l'URL du fichier est construit à partir du chemin d'exécution et du nom du fichier. D'autres transformations sont possibles : voir la documentation osl::FileBase dans http://api.openoffice.org/docs/cpp/ref/names/osl/c-FileBase.html
Créer un nouveau document
Il vous faut choisir votre type de document et utiliser la chaîne de caractères magique pour remplacer "private:factory/scalc" :
- chaîne magique
Type du nouveau Document | Chaîne magique |
Texte dans Writer | private:factory/swriter |
Tableur Calc | private:factory/scalc |
Dessin | private:factory/sdraw |
Présentation Impress | private:factory/simpress |
Ecriture de formules Mathématiques | private:factory/smath |
Document par défaut (déjà ouvert)
Le moyen d'obtenir le document par défaut est légèrement différent des deux sections précédentes. Nous commençons par donner les lignes de programme à changer puis les changements effectifs à réaliser. Pour trouver le document par défaut, changer le code précédent donner à nouveau ci-dessous en Listing 11 par celui du Listing 12 en n'oubliant pas de regarder la documentation des interfaces com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader et com.sun.star.lang.XComponent correspondantes.
//Listing 11 Finding the default Document : code to remove //C++ //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" ); } //get an instance of the spreadsheet Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL( OUString::createFromAscii("private:factory/scalc"), OUString::createFromAscii("_blank"), 0, Sequence < ::com::sun::star::beans::PropertyValue >()); // add code here return 0;
Voici notre nouveau code :
//Listing 12 Finding the default Document : Code to insert // C++ // Don't forget the #include <com/sun/star/frame/XDesktop.hpp> // Don't forget to add com.sun.star.frame.XDesktop \ in the makefile //get the desktop service using createInstance returns an XInterface type Reference< XInterface > Desktop = rOfficeServiceManager->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" )); //query the XDesktop Interface Reference< XDesktop > xDesktop (Desktop, UNO_QUERY); Reference< XComponent > xcomponent = xDesktop->getCurrentComponent(); return 0;
Comme vous pouvez le remarquer il vous faut demander une interface XDesktop. Il est important de noter qu'à chaque fois que vous voulez obtenir une interface, il vous faudra ajouter une ou deux (si le nommage n'est pas réalisé). Pour aller plus loin ici si vous n'êtes pas débutant.
Sauver le Document
Dans les exemples de cette section je vais demander une nouvelle interface : l'interface com.sun.star.frame.XStorable. Il vous est donc possible de sauver en ajoutant ce nouveau code
//Listing 13 How to store a Document // C++ // Don't forget the #include <com/sun/star/frame/XStorable.hpp> // Don't forget to add com.sun.star.frame.XStorable \ in the makefile // Query for Xstorable interface Reference< XStorable > rcomponentStore (xcomponent, UNO_QUERY); if( !rcomponentStore.is() ){ printf( "XStorable Not successfully instanciated\n" ); }else rcomponentStore->store();
Il est aussi possible de donner un nom en sauvegardant :
ou
Nous sommes maintenant prêt pour décrire toutes les applications Openoffice.org. Nous allons commencer par Calc mais avant de commencer regardons à nouveau le Desktop.
Ma première énumération de Conteneur avec Desktop
Les conteneurs sont un concept important de la programmation OOo parceque vous les trouvez partout. Par exemple dans un tableur toutes les feuilles sont dans un conteneur, dans Draw toutes les pages sont dans un conteneur, dans une page toutes les formes (rectangles, cercles,...) sont dans un conteneur et ainsi de suite.
L'interface XEnumerationAccess
Plutôt de grands discours nous commençons par donner un exemple de code qui utilise les interfaces com.sun.star.frame.XDesktop, com.sun.star.container.XEnumerationAccess, com.sun.star.lang.XServiceInfo et com.sun.star.frame.XStorable :
//Listing 16 L'interface XEnumeration // C++ // container // Ne pas oublier d'ajouter : using namespace com::sun::star::frame; // Ne pas oublier la directive : #include <com/sun/star/frame/XDesktop.hpp> // Ne pas oublier d'ajouter "com.sun.star.frame.XDesktop \" dans le makefile // otention de l'interface XDesktop (et non du service Desktop) Reference<XDesktop> desk(xServiceManager->createInstance( OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY); // Ne pas oublier d'ajouter : using namespace com::sun::star::container; // Ne pas oublier la directive : #include <com/sun/star/container/XEnumerationAccess.hpp> // Ne pas oublier d'ajouter "com.sun.star.container.XEnumerationAccess \" dans le makefile Reference<XEnumerationAccess> comps = desk->getComponents(); if (comps->hasElements()) { Reference<XEnumeration> compenum(comps->createEnumeration(), UNO_QUERY); while (compenum->hasMoreElements()) { Reference<XComponent> comp(compenum->nextElement(), UNO_QUERY); // Ne pas oublier d'ajouter : using namespace com::sun::star::lang; // Ne pas oublier la directive: #include <com/sun/star/lang/XServiceInfo.hpp> // Ne pas oublier d'ajouter "com.sun.star.lang.XServiceInfo \" dans le makefile Reference<XServiceInfo> serviceinfo(comp, UNO_QUERY); if (serviceinfo->supportsService( OUString::createFromAscii("com.sun.star.document.OfficeDocument"))) { // Ne pas oublier la directive: #include <com/sun/star/frame/XStorable.hpp> // Ne pas oublier d'ajouter "com.sun.star.frame.XStorable \" dans le makefile Reference<XStorable> storeable(comp, UNO_QUERY); if (storeable->hasLocation()) { OString loc = OUStringToOString(storeable->getLocation(), RTL_TEXTENCODING_ASCII_US); printf("-- %s\n",loc.pData->buffer); } } } }
Ce programme affiche :
-- file:///home/smoutou/OpenOffice.org1.1_SDK/UNOCpp_AP01.sxw -- file:///home/smoutou/Inetrecup/Openoffice/01prog_menu-context_officebean2.sxw |
dépendant naturellement de quels fichiers sont chargés et de quel système d'exploitation vous disposez.
L'interface XIndexAccess
En général il y a deux moyens d'accéder aux éléments d'un conteneur, avec un index (numérique) ou par son nom. Les interfaces correspondantes sont XIndexAccess et XNameAccess. Si vous voulez savoir ce que vous pouvez faire avec une interface, cherchez le fichier IDL correspondant. Les fichiers IDL sont expliqués plus tard dans le document (voir ici). Par exemple, nous donnons le fichier IDL de l'interface com.sun.star.container.XIndexAcess (en retirant tous les commentaires) :
//Listing 17 XIndexAccess IDL File (without Comments) // IDL module com { module sun { module star { module container { interface XIndexAccess: com::sun::star::container::XElementAccess { long getCount(); any getByIndex( [in] long Index ) raises( com::sun::star::lang::IndexOutOfBoundsException, com::sun::star::lang::WrappedTargetException ); }; }; }; }; };
Le chemin pour trouver ce fichier IDL peut être retrouvé avec le contenu de ce fichier : <OpenOffice.org1.1_SDK>/idl/com/sun/star/container et le nom du fichier est celui de l'interface avec l'extension “.idl”. Deux méthodes peuvent être utilisées : getCount() et getByIndex() comme on peut facilement le voir sur le listing ci-dessus.
Voir aussi com.sun.star.container.XElementAccess.
L'interface XNameAccess
La deuxième interface d'accès est quant à elle décrite par com.sun.star.container.XNameAccess:
//Listing 18 XNameAccess IDL file (without Comments) // IDL module com { module sun { module star { module container { interface XNameAccess: com::sun::star::container::XElementAccess { any getByName( [in] string aName ) raises( com::sun::star::container::NoSuchElementException, com::sun::star::lang::WrappedTargetException ); sequence<string> getElementNames(); boolean hasByName( [in] string aName ); }; }; }; }; };
qui montre trois méthodes. Notre but dans cette section est de voir le desktop comme un conteneur. Il peut effectivement contenir des fenêtres. Voir aussi com.sun.star.container.XElementAccess.
Ce qui n'est pas toujours très clair pour moi
Plus tard, je vais décrire un "reflection helper". Il nous permet de connaître les méthodes et propriétés d'un objet... Quand j'utilise ce programme pour regarder les méthodes de l'objet “Desktop” je vois clairement la méthode getComponents(). Mais je ne peux pas l'appeler directement. Il me faut construire une variable desktop nommée “desk” dans le listing ci-dessus avant de l'appeler.
Une relecture plus fine des remarques précédentes me montre que la variable "desktop" est en fait un service tandis que la variable "desk" est une interface. En C++ il vous faut utiliser les interfaces (et pas les services) tandis qu'en OOoBasic vous utilisez les services. Tout cela sera revu plus en détail ici. |
On n'a pas besoin d'un “#include <com/sun/star/lang/XComponent.hpp>” et je ne comprends pas bien pourquoi ! En général on se trouve dans ce cas lorsque l'interface est obtenue à partir d'une méthode d'une précédente interface, mais ici ce n'est pas tout à fait le cas.
Vous pouvez trouver des explications ici écrites après les lignes ci-dessus (réservées aux non débutants).
Ce que nous avons appris dans ce chapitre
Je suis toujours plus intéressé par les figures que par les longues explications. Cependant les schémas sont faciles à comprendre seulement si vous prenez le temps d'y chercher toutes les conventions qui s'y trouvent. Si ce n'est pas le cas, relisez l'introduction de ce chapitre.
Nous donnons donc un schéma résumant tout ce qui a été appris dans ce chapitre.
Retour à la page d'accueil
Page d'accueil du développement C++ à l'aide du SDK
Voir aussi
- Introduction à l'API StarOffice
- Utilisation de documents StarOffice en OOoBasic
- C++ and UNO tutorial
- To learn C++ : C++ e-books
- Writing a Program to Control OpenOffice.org, by Franco Pingiori — Part 1 and Part 2, Linux Journal