Difference between revisions of "FR/Documentation/L'automation d'OpenOffice.org avec un binaire exécutable"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (Introduction au Bootstrapping)
m (Nouveau code comme point de départ)
Line 388: Line 388:
  
 
Pour aller plus loin avec les explications aller voir [[IDL_Files_and_Cpp#IDL__and_C.2B.2B|ici (en anglais)]]. Cet hyperlien n'est cependant pas pour les débutants.
 
Pour aller plus loin avec les explications aller voir [[IDL_Files_and_Cpp#IDL__and_C.2B.2B|ici (en anglais)]]. Cet hyperlien n'est cependant pas pour les débutants.
 +
 +
== Trouver et sauver un document ==
 +
 +
Toute cette section est basée sur le changement du code C++ du Listing 6 dans le précédent Listing 5 :
 +
 +
<source lang="cpp">
 +
//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 >());
 +
</source>
 +
Les deux paramètres "private:factory/scalc" et “_blank” peuvent être changés. Voyant les conséquences de ces changements.
 +
===Chargement d'un fichier exostant ===
 +
 +
Pour charger un fichier existant, changer le code du Listing 6 comme
 +
{{Documentation/Linux|
 +
<source lang="cpp">
 +
//Listing 7 Chargment d'un fichier
 +
//C++
 +
//get an instance of the spreadsheet
 +
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
 +
OUString::createFromAscii("file:///home/smoutou/work/undocument.sxc"),
 +
        OUString::createFromAscii("_blank"),
 +
        0,
 +
        Sequence < ::com::sun::star::beans::PropertyValue >());
 +
</source>
 +
}}
 +
 +
Vous vouler charger ouprendre un fichier déjà ouvert de même nom, changez alors le paramètre “_blank” :
 +
{{Documentation/Linux|
 +
<source lang="cpp">
 +
//Listing 8 Changing the _blank Parameter
 +
// C++
 +
//get an instance of the spreadsheet
 +
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
 +
OUString::createFromAscii("file:///home/smoutou/OneDocument.sxc"),
 +
        OUString::createFromAscii("_default"),
 +
        0,
 +
        Sequence < ::com::sun::star::beans::PropertyValue >());
 +
</source>
 +
}}
 +
Le nom du fichier est compatible UNIX. Sous Windows on peut utiliser l'équivalence
 +
{{Documentation/Windows|
 +
<pre>
 +
C:\My Documents\tata.sxc file:///C|/My%20Documents/tata.sxc
 +
</pre>
 +
}}
 +
 +
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 :
 +
{{Documentation/Linux|
 +
<source lang="cpp">
 +
//Listing 9 Constructing an URL
 +
// LINUX C++
 +
// Don't forget #include <osl/file.hxx>
 +
 +
OUString sDocUrl;
 +
    osl::FileBase::getFileURLFromSystemPath(
 +
                OUString::createFromAscii("/home/smoutou/edt.sxd"),sDocUrl);
 +
// Windows C++ to check
 +
// osl::FileBase::getFileURLFromSystemPath(
 +
//   OUString::createFromAscii("C:\My Documents\tata.sxc"),sDocUrl);
 +
 +
//get an instance of the spreadsheet
 +
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
 +
    sDocUrl,
 +
        OUString::createFromAscii("_blank"),
 +
        0,
 +
        Sequence < ::com::sun::star::beans::PropertyValue >());
 +
</source>
 +
}}
 +
Une autre possibilité est de construire l'URL à partir d'un nom de fichier et de son chemin
 +
<source lang="cpp">
 +
//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 >());
 +
</source>
 +
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 ===
 +
You choose your document type and then replace "private:factory/scalc" by the corresponding magical text :
 +
; magical text
 +
{| border cellspacing="0" width="550"
 +
|- style = "background:#b3e2d1;text-align:center"
 +
| |new Document's Type||Magical Text
 +
|- style="text-align:center"
 +
| Writer text ||private:factory/swriter
 +
|- style="text-align:center"
 +
| Calc spreadsheet ||private:factory/scalc
 +
|- style="text-align:center"
 +
| Draw||private:factory/sdraw
 +
|- style="text-align:center"
 +
| Impress presentation ||private:factory/simpress
 +
|- style="text-align:center"
 +
| Math formula  ||private:factory/smath
 +
|}
 +
 +
==The default opened Document==
 +
The way to obtain the default document is slightly different from the previous two chapters. We then first give the  program lines to change and after the effective changes.
 +
To find the default document,  change the  previous code given again below in Listing 11 with those given in Listing 12.
 +
<source lang="cpp">
 +
//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;
 +
</source>
 +
here is our new code :
 +
<source lang="cpp">
 +
//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;
 +
</source>
 +
As you can see we have to query the XDesktop interface. It is important to note that every time you will query for an interface, you have to add one or two lines in the listing and an other in the makefile. To go further with explanations have a look [[IDL_Files_and_Cpp#IDL__and_C.2B.2B|here]] if you are not a beginner
 +
 +
==Save the Document==
 +
In the examples of this section you will query for an interface : the XStorable interface.
 +
Now you can save with adding the code
 +
<source lang="cpp">
 +
//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();
 +
</source>
 +
It is also possible to give a name when saving :
 +
{{Documentation/Windows|
 +
<source lang="cpp">
 +
//Listing 14 How to store a Document (Windows version)
 +
// C++ Windows to check
 +
//document save as
 +
// 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 the ::com::sun::star::frame::XStorable interface
 +
    Reference< XStorable > rcomponentStore (xcomponent, UNO_QUERY);
 +
if( !rcomponentStore.is() ){
 +
        printf( "XStorable Not successfully instanciated\n" );
 +
    }else
 +
    rcomponentStore->storeAsURL(OUString::createFromAscii(
 +
"file:///C|/My%20Documents/tata.sxd"),
 +
Sequence < ::com::sun::star::beans::PropertyValue >());
 +
</source>
 +
}}
 +
or
 +
{{Documentation/Linux|
 +
<source lang="cpp">
 +
//Listing 15 How to store a Document (Linux Version)
 +
// C++ LINUX
 +
//document save as
 +
// 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 the ::com::sun::star::frame::XStorable interface
 +
    Reference< XStorable > rcomponentStore (xcomponent, UNO_QUERY);
 +
if( !rcomponentStore.is() ){
 +
        printf( "XStorable Not successfully instanciated\n" );
 +
    }else
 +
    rcomponentStore->storeAsURL(OUString::createFromAscii("file:///home/smoutou/tata.sxd"),
 +
Sequence < ::com::sun::star::beans::PropertyValue >());
 +
</source>
 +
}}
 +
We are now ready to describe all the different Openoffice.org applications. We will begin with OpenOffice.orgCalc but before starting we have a look at Desktop.

Revision as of 15:14, 4 July 2008

Nous voulons maintenant nous attaquer a un programme entier en UNO/OpenOffice.org. Ce programme effectuera quelques taches sur des documents OpenOffice.org , chargements de fichiers, modifications de fichiers, sauvegardes de fichiers....

Introduction à partir d'un exemple du SDK

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 ServiceManager et Desktop

Pour pouvoir travailler avec OOo avec l'API, vous devez obtenir deux objets absolument essentiels 1. le ServiceManager (gestionnaire de service) 2. le Desktop (le bureau)

Une fois le ServiceManager obtenu,un appel à sa méthoded createInstance() permet d'obtenir l'objet Desktop. 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  : <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding Nous regardons le premier exemple en premier (sous Linux) : Template:Documentation/Linux

qui écrit seulement : "Connected successfully to the office". Mais c'est déjà pas mal ? Non ?

Sous windows, cela donnerait : Template:Documentation/Windows

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. Je peux juste dire que c'est un moyen parmi d'autres d'obtenir le “ Service Manager”. Une autre façon de le faire est donnée dans <OpenOffice.org1.1_SDK>/examples/cpp/DocumentLoader's example.

Introduction au Bootstrapping

Le Bootstrap (désolé je garde la terminologie anglaise) est discuté plus en détail plus tard (référence anglaise!!!). Nous nous contenterons donc d'une introduction maintenant. Le bootstrap est le mécanisme qui permet d'obtenir un service manager. Template:Documentation/Note 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.

Bootstrapping
Documentation caution.png Comme tous les schémas, sa compréhension nécessite de comprendre toutes les conventions qu'il utilise. Je pense changer de conventions dans le futur en m'inspirant du nouvel inspecteur d'objet Java disponible maintenant

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 rempli en gris sont réservés aux paramètres... etc...

On veut maintenant le desktop et charger un composant tableur OooCalc.

La première étape est d'obtenir le desktop. Vous ajouter ensuite ce code :

// Listing 2 Obtaining a desktop interface
// C++
Reference< XInterface  > xDesktop = rOfficeServiceManager->createInstance(
   	OUString::createFromAscii( "com.sun.star.frame.Desktop" ));

Votre objet desktop est la variable xDesktop.

Deuxième étape : demande de l'interface XComponentLoader

// Listing 3  Query a XcomponentLoader Interface
// C++
// query a XcomponentLoader Interface 
Reference< XComponentLoader > rComponentLoader (xDesktop, UNO_QUERY);
if( rComponentLoader.is() )
    	{
        	printf( "XComonentloader succesfully instanciated\n" );
    	}

Avant d'examiner les problèmes avec ce code, nous en donnons une représentation schématique :

Component Loader

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” qui nous permet de déduire que

#include <com/sun/star/frame/XComponentLoader.hpp>

est requis. Un essai nous permet de constater que ce n'est pas suffisant puisque le même message d'erreur que précédemment est obtenu :

com/sun/star/frame/XComponentLoader.hpp: No such file or directory 

J'ai déjà discuté ce fait : le SDK ne fournit pas les fichiers hpp mais seulement les moyens de les construire à partir des fichiers IDL. Il vous faudra donc ouvrir et changer le fichier "makefile". 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 maintenant ? Seulement une instruction de nommage qui nous donne le résultat final :

// C++
using namespace com::sun::star::frame;

(Pour aller plus loin avec ces deux étapes voir Getting an Interface in 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 (en anglais) 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 est pas abordé complètement dans ce document. Il réfère aux exceptions.

Utiliser l'objet desktop

On veut maintenant l'objet desktop pour charger un document tableur OOoCalc. La première étape est d'obtenir le desktop. Ensuite vous ajouté ce code:

//Listing 15 
// C++
Reference< XInterface  > xDesktop = rOfficeServiceManager->createInstance(
   	OUString::createFromAscii( "com.sun.star.frame.Desktop" ));

Votre objet desktop est dans notre variable xDesktop. Deuxième étape : demander une interface XComponentLoader

//Listing 16 
// C++
// query a XcomponentLoader Interface 
Reference< XComponentLoader > rComponentLoader (xDesktop, UNO_QUERY);
if( rComponentLoader.is() )
    	{
        	printf( "XComonentloader succesfully instanciated\n" );
    	}

Le code ci dessus donne des messages d'erreurs : error 'XComponentLoader' undeclared (First use this function) .... Cela nous montre qu'il y a un problème avec XComponentLoader : Cela indique que nous devons probablement ajouter un fichier hpp dans les directives habituelles d'inclusion. Le nom du fichier est sûrement XComponentLoader.hpp mais nous devons trouver où il se situe. Un moyen simple consiste a aller sur : http://api.openoffice.org/docs/common/ref/index-files/index-1.html et regarder pour XComponentLoader. Nous trouvons: “::com::sun::star::frame” ce qui indique qu'une directive :

//Listing 17 
// C++
#include <com/sun/star/frame/XComponentLoader.hpp>

est requise. Nous pouvons essayer de l'ajouter, tout cela pour s'apercevoir que ce n'est pas suffisant. On obtient toujours le même message d'erreur aussi qu'un autre en bonus : com/sun/star/frame/XComponentLoader.hpp: No such file or directory Je discuterais ce fait beaucoup plus en détail dans le chapitre XX : le SDK ne fournit pas les fichiers hpp , ils doivent être construit à partir de fichiers IDL . Pour cela il nous faut ouvrir et changer le makefile comme indiqué ci-dessous (repérez bien la ligne correspondante).

#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

On obtient cette fois encore le même message d'erreur dans le projet. Mais que manque-t-il donc encore pour éviter ce message ? Il manque juste une assertion de nommage dans le fichier source :

//Listing 18 
// C++
using namespace com::sun::star::frame;

Troisième étape : obtenir une instance du tableur

//Listing 19 
// C++
Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/scalc"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

Avec toutes ces modifications vous venez de créer visuellement un document tableur vierge sans nom.

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 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.

Vous pouvez trouver une description de chaîne de compilation ici dans ce Wiki (en anglais) et aussi ici (toujours 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 :

UNO component build chain


Template:Documentation/Tip

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é parcequ'il est plus facile de commencer des explications 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 function est entièrement responsable de la connection : ooConnect() et je la présente maintenant :

// Listing 5
// C++
#include <stdio.h>
#include <cppuhelper/bootstrap.hxx>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
// added
#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;
// added
using namespace com::sun::star::frame;
 
using namespace rtl;
using namespace cppu;
 
// a procedure for what the so called boostrap
Reference< XMultiServiceFactory > ooConnect(){
   // 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 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;
}
 
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" );
    	}
 
//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 >());
// AJOUTER votre code ici
    return 0;
}

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 renomer 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'utilisera toujours ce code comme point de départ. Cela signifie que je donnerai tout ou partie de code qu'il faudra insérer dans cet exemple.

Pour aller plus loin avec les explications aller voir ici (en anglais). Cet hyperlien n'est cependant pas pour les débutants.

Trouver et sauver un document

Toute cette section est basée sur le changement du code C++ du Listing 6 dans le précédent 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 exostant

Pour charger un fichier existant, changer le code du Listing 6 comme Template:Documentation/Linux

Vous vouler charger ouprendre un fichier déjà ouvert de même nom, changez alors le paramètre “_blank” : Template:Documentation/Linux Le nom du fichier est compatible UNIX. Sous Windows on peut utiliser l'équivalence Template:Documentation/Windows

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 : Template:Documentation/Linux 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

You choose your document type and then replace "private:factory/scalc" by the corresponding magical text :

magical text
new Document's Type Magical Text
Writer text private:factory/swriter
Calc spreadsheet private:factory/scalc
Draw private:factory/sdraw
Impress presentation private:factory/simpress
Math formula private:factory/smath

The default opened Document

The way to obtain the default document is slightly different from the previous two chapters. We then first give the program lines to change and after the effective changes. To find the default document, change the previous code given again below in Listing 11 with those given in Listing 12.

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

here is our new 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;

As you can see we have to query the XDesktop interface. It is important to note that every time you will query for an interface, you have to add one or two lines in the listing and an other in the makefile. To go further with explanations have a look here if you are not a beginner

Save the Document

In the examples of this section you will query for an interface : the XStorable interface. Now you can save with adding the 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();

It is also possible to give a name when saving : Template:Documentation/Windows or Template:Documentation/Linux We are now ready to describe all the different Openoffice.org applications. We will begin with OpenOffice.orgCalc but before starting we have a look at Desktop.

Personal tools