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 à partir d'un exemple du SDK)
m (Introduction au Bootstrapping)
Line 99: Line 99:
  
 
== Introduction au Bootstrapping ==
 
== Introduction au Bootstrapping ==
Bootstrap processes are more deeply discussed [[UNO_registery_and_Bootstrapping#The_Bootstrap|later]]. We give only an introduction here.  
+
Le Bootstrap (désolé je garde la terminologie anglaise) est dicuté plus en détail [[UNO_registery_and_Bootstrapping#The_Bootstrap|plus tard (référence anglaise!!!)]]. Nous nous contenterons donc d'une introduction maintenant.  
  
To memorize this previous piece of code is not easy and probably useless. However, we give a drawing representation of this piece of code to show the main step of the bootstrap process.  
+
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.  
  
 
[[Image:ch4Fig1bootstrap.png|none|thumb|600px|Bootstrapping]]
 
[[Image:ch4Fig1bootstrap.png|none|thumb|600px|Bootstrapping]]
  
 +
{{Documentation/Caution|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}}
 
If you are interested in, have a look simultaneously to the code and to the drawing to see the schematic conventions I have used to carry out the Figure above. For instance both XInterface are connected because we use the same variable in fact. The gray filled rectangles are for parameters... and so on.
 
If you are interested in, have a look simultaneously to the code and to the drawing to see the schematic conventions I have used to carry out the Figure above. For instance both XInterface are connected because we use the same variable in fact. The gray filled rectangles are for parameters... and so on.
  

Revision as of 12:17, 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 dicuté plus en détail plus tard (référence anglaise!!!). Nous nous contenterons donc d'une introduction maintenant.

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

If you are interested in, have a look simultaneously to the code and to the drawing to see the schematic conventions I have used to carry out the Figure above. For instance both XInterface are connected because we use the same variable in fact. The gray filled rectangles are for parameters... and so on.

We want now the desktop and load a OooCalc component.

The first step is to obtain desktop. You then add this code :

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

Your desktop object is xDesktop.

Second step : query for the XComponentLoader interface

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

Before to see the problems with this code, we give again a schematic representation :

Component Loader

The code above gives error messages :

error 'XcomponentLoader' undeclared (First use this function) ....

It shows us there is a problem with XComponentLoader : this indicates we have probably to add a hpp header file in the program's include statements. The file's name is probably XComponentLoader.hpp but we have to find where it lies. One way is to go in the general index and to look for XComponentLoader. We find : “::com::sun::star::frame” which indicates

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

is required. We can try and see it is not enough, we obtain always the same error message and one new before : com/sun/star/frame/XComponentLoader.hpp: No such file or directory I have already discussed this fact : the SDK doesn't provide any hpp file, they have to be constructed from IDL files. An other task is then  : open and change the makefile. Only add the correspondant line :

#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

Making the project gives again the same error message. What is still lacking now ? Only a namespace statement in the source file :

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

(To go further with the two steps above see Getting an Interface in C++)

Step 3 : get an instance of the spreadsheet

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

and it works : you have a new OOoCalc document.

This hyperlink will takkle again the header file construction problem.

An other thing to note is : when constructing variables with Reference template like :

	Reference<...>varName 

you can check with

	varName.is() 

function. The problem of what to do if this variable is not created (varName.is() is false) is complex and not deeply tackled in this document. It refers to exceptions.


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

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 passer au chapitre 4.3 Pour résumer, nous donnons le flot de conception (voir Figure 3) d'un exemple vu précédemment.

<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding
Personal tools