Difference between revisions of "FR/Documentation/OpenOffice Writer"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (Le Dispatcher et l'Internationalization)
m (Créer, ouvrir un document writer)
Line 218: Line 218:
  
 
=Créer, ouvrir un document writer=
 
=Créer, ouvrir un document writer=
A faire
+
On commence par ouvrir un nouveau document OOowriter. Cela peut être fait avec le code ci-dessous :
 +
<source lang="cpp">
 +
//Listing 11 Obtaining a blank OOoWriter Document
 +
// C++
 +
//get an instance of the OOowriter document
 +
    Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(
 +
OUString::createFromAscii("private:factory/swriter"),
 +
        OUString::createFromAscii("_blank"),
 +
        0,
 +
        Sequence < ::com::sun::star::beans::PropertyValue >());
 +
</source>
 +
while opening an existing document is done with :
 +
<source lang="cpp">
 +
//Listing 12 Obtaining a blank OOoWriter Document
 +
// C++
 +
//get an instance of the OOowriter document
 +
    OUString sDocUrl;
 +
    osl::FileBase::getFileURLFromSystemPath(
 +
                OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);
 +
    Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(
 +
sDocUrl,
 +
        OUString::createFromAscii("_blank"),
 +
        0,
 +
        Sequence < ::com::sun::star::beans::PropertyValue >());
 +
</source>
  
 
=Traduire le code Java en C++=
 
=Traduire le code Java en C++=

Revision as of 12:05, 8 July 2008

Dans ce chapitre, nous utilisons encore le code initial décrit dans chapitre 3.3. Il consiste en un sous-programme “ooConnect ()” et un programme principal main(). Travailler avec ce code consiste à ajouter le nouveau code dans le programme principal. Nous donnons pour la troisième fois le programme principal :

//Listing 1
// C++ 
// adapted for OOoWriter
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 OOowriter document
    Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/swriter"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());
// AJOUTER votre code ici
    return 0;
}

Nous rappelons au lecteur que les exemples ci-dessous, prennent comme code de départ l'exemple “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding”. Notre code est mis dans “office_connect.cxx” et nous ajoutons ce que vous trouvez comme commentaires dans le code (directives d'inclusions et définitions des espaces de nommage) ainsi que dans le makefile (en général pour créer les fichiers hpp et hxx).

Utiliser le Dispatcher et enregistrer des Macros

La première chose que nous voulons examiner est l'utilisation du dispatcher avant l'utilisation directe des appels UNO dans la prochaine section. Si vous enregistrez des macros, vous obtenez du code OOoBasic qui utilise le dispatcher plutôt que les appels UNO directs. Voir la section The OpenOffice.org recorder and UNO dispatch calls pour une discussion sur l'enregistrement des commandes du dispatcher par rapport aux appels API.

Introduction

Par exemple si vous avez un document OOoWriter et que vous déclenchez l'enregistrement d'une macro pendant que vous insérez du texte et que vous le formatez, cela vous donne quelque chose qui doit ressembler à :

'Listing 2 OOoBasic and the Dispatcher with Macro Recorder
REM  *****  BASIC  *****
 
sub Main
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
 
rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "Text"
args1(0).Value = "demo de macro"
 
dispatcher.executeDispatch(document, ".uno:InsertText", "", 0, args1())
 
rem ----------------------------------------------------------------------
dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "Bold"
args2(0).Value = true
 
dispatcher.executeDispatch(document, ".uno:Bold", "", 0, args2())
 
rem ----------------------------------------------------------------------
dim args4(2) as new com.sun.star.beans.PropertyValue
args4(0).Name = "FontHeight.Height"
args4(0).Value = 14
args4(1).Name = "FontHeight.Prop"
args4(1).Value = 100
args4(2).Name = "FontHeight.Diff"
args4(2).Value = 0
 
dispatcher.executeDispatch(document, ".uno:FontHeight", "", 0, args4())
 
end sub

Ce code est très caractéristique de l'utilisation du dispatcher. Comment traduire ce code en C++ ? Le problème est de prendre en compte le dispatcher.

La première étape est d'obtenir l'interface XDispatcherHelper.

//Listing 3 Demande de l'interface XDispatchHelper
// C++
Reference< XDispatchHelper > rDispatchHelper = Reference< XDispatchHelper >
				( rOfficeServiceManager->createInstance(
                              OUString( RTL_CONSTASCII_USTRINGPARAM(
                              "com.sun.star.frame.DispatchHelper" ))), UNO_QUERY );

Vous pouvez trouver plus d'explications ici (en anglais) (si vous n'êtes pas débutant) et vous comprendrez alors ce listing.

La deuxième étape est d'obtenir l'interface XFrame en partant de la variable Desktop (bureau) et après d'obtenir l'interface XDispatchProvider starting en partant de la variable frame qui contient le service XFrame (cela semble très important de partir de la variable frame).

//Listing 4 Obtenir une interface XFrame
// C++
Reference< XFrame > rFrame=rDesktop->getCurrentFrame();
 
Reference< XDispatchProvider > rDispatchProvider(rFrame,UNO_QUERY);

La troisième étape est de déclarer votre tableau (Sequence en C++) de “PropertValue” et de donner les valeurs :

//Listing 5 Les couples Name/Value des propriétés
// C++
	Sequence < PropertyValue > args1(1);
 
	args1[0].Name = OUString::createFromAscii("Text");
	args1[0].Value <<= OUString::createFromAscii("demo de macro");

et l'étape finale est d'appeler le dispatcher :

//Listing 6 Appel du Dispatcher
// C++
	rDispatchHelper->executeDispatch(rDispatchProvider,
			OUString::createFromAscii(".uno:InsertText"),
			OUString::createFromAscii(""),
			0,
			args1);

Le reste du code OOoBasic peut être facilement traduit comme montré ci-dessous :

//Listing 7 Autres appels du Dispatch
// C++
args1[0].Name = OUString::createFromAscii("Bold");
	args1[0].Value <<=(sal_Bool)true;
	rDispatchHelper->executeDispatch(rDispatchProvider,
			OUString::createFromAscii(".uno:Bold"),
			OUString::createFromAscii(""),
			0,
			args1);
 
	args1.realloc(3);
	args1[0].Name = OUString::createFromAscii("FontHeight.Height");
	args1[0].Value <<= (sal_Int32)14;
	args1[1].Name = OUString::createFromAscii("FontHeight.Prop");
	args1[1].Value <<= (sal_Int32)100;
	args1[2].Name = OUString::createFromAscii("FontHeight.Diff");
	args1[2].Value <<= (sal_Int32)0;
	rDispatchHelper->executeDispatch(rDispatchProvider,
			OUString::createFromAscii( ".uno:FontHeight"),
			OUString::createFromAscii(""),
			0,
			args1);

Le Dispatcher et l'Internationalization

Un des problèmes que vous rencontrerez avec ce style de programmation est : comment puis-je écrire de tels programmes pouvant tourner sur n'importe quelle machine dans le monde entier ? Si vous travaillez en français, comme je le fais, et que vous enregistrez une macro, vous allez rencontrer des valeur de propriétés en français. Par exemple, si j'enregistre une insertion d'image, j'obtiens le code OOoBasic :

'Listing 8 Inserting an Image (OOoBasic)
REM  *****  BASIC  *****
 
sub Main
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
 
rem ----------------------------------------------------------------------
dim args1(3) as new com.sun.star.beans.PropertyValue
args1(0).Name = "FileName"
args1(0).Value = "file:///home/smoutou/PhotoPCB2.jpg"
args1(1).Name = "FilterName"
args1(1).Value = "<Tous les formats>"
args1(2).Name = "AsLink"
args1(2).Value = false
args1(3).Name = "Style"
args1(3).Value = "Image"
 
dispatcher.executeDispatch(document, ".uno:InsertGraphic", "", 0, args1())
 
end sub

qui montre clairement du français. Si vous traduisez directement ce code comme expliqué plus haut, vous obtenez :

//Listing 9 Insertion d'une Image (C++ French Version)
// C++
....
	Sequence < PropertyValue > args1(4);
	args1[0].Name = OUString::createFromAscii("FileName");
	args1[0].Value <<= OUString::createFromAscii("file:///home/smoutou/PhotoPCB2.jpg");
	args1[1].Name = OUString::createFromAscii("FilterName");
	args1[1].Value <<= OUString::createFromAscii("<Tous les formats>");
	args1[2].Name = OUString::createFromAscii("AsLink");
	args1[2].Value <<=(sal_Bool)false;
	args1[3].Name = OUString::createFromAscii("Style");
	args1[3].Value <<= OUString::createFromAscii("Image");
 
	rDispatchHelper->executeDispatch(rDispatchProvider,
			OUString::createFromAscii(".uno:InsertGraphic"),
			OUString::createFromAscii(""),
			0,
			args1);

qui fonctionne correctement. Si je traduis le français du programme en anglais, cela fonctionne aussi sur ma version française d'OpenOffice :

//Listing 10 Inserting an Image (C++ English Version)
// C++
	args1[1].Name = OUString::createFromAscii("FilterName");
	args1[1].Value <<= OUString::createFromAscii("<All formats>");
	....
	args1[3].Name = OUString::createFromAscii("Style");
	args1[3].Value <<= OUString::createFromAscii("Graphics");
	....

Mais nous ne pouvons pas éviter la question : est-ce que la première version en français marche sur tous les ordinateurs ? Je n'ai pas de réponse. Je suppose que la version anglaise fonctionne partout. Il m'est impossible aussi d'éviter cette seconde question : comment puis-je savoir que « <tous les Formats> » est traduit par « <All Formats> » en anglais ?

Créer, ouvrir un document writer

On commence par ouvrir un nouveau document OOowriter. Cela peut être fait avec le code ci-dessous :

//Listing 11 Obtaining a blank OOoWriter Document
// C++
//get an instance of the OOowriter document
    Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/swriter"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

while opening an existing document is done with :

//Listing 12 Obtaining a blank OOoWriter Document
// C++
//get an instance of the OOowriter document
    OUString sDocUrl;
    osl::FileBase::getFileURLFromSystemPath(
                 OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);
    Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(
	sDocUrl,
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());

Traduire le code Java en C++

On commence avec un exemple trouvé dans un OOoForum sous le nom : Setting the page properties/margins directly from java Voici le code java :

//Listing 114
// Java
// create new writer document and get text, then manipulate text 
 XComponent xWriterComponent = newDocComponent("swriter"); 
 XTextDocument xTextDocument = (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class,xWriterComponent); 
 // Access the text document's multi service factory, which we will need for most of the 
 // following examples 
 mxDocFactory = (XMultiServiceFactory) UnoRuntime.queryInterface
		(XMultiServiceFactory.class,xTextDocument); 
 XText xText = xTextDocument.getText(); 
 // create a text cursor from the cells XText interface 
 XTextCursor xTextCursor = xText.createTextCursor(); 
 // Get the property set of the cell's TextCursor 
 XPropertySet xTextCursorProps = (XPropertySet)UnoRuntime.queryInterface
		(XPropertySet.class,xTextCursor); 
 // Page Style name 
 String pageStyleName= xTextCursorProps.getPropertyValue("PageStyleName").toString(); 
 // Get the StyleFamiliesSupplier interface of the document 
 XStyleFamiliesSupplier xSupplier = (XStyleFamiliesSupplier) UnoRuntime.queryInterface
		(XStyleFamiliesSupplier.class,xTextDocument); 
 // Use the StyleFamiliesSupplier interface to get the XNameAccess interface of the 
 // actual style families 
 XNameAccess xFamilies = (XNameAccess)UnoRuntime.queryInterface(XNameAccess.class,
		 xSupplier.getStyleFamilies()); 
 // Access the 'PageStyles' Family 
 XNameContainer xFamily = (XNameContainer) UnoRuntime.queryInterface
		(XNameContainer.class,xFamilies.getByName("PageStyles")); 
 // Insert the newly created style into the PageStyles family 
 XStyle xStyle= (XStyle) UnoRuntime.queryInterface(XStyle.class,xFamily.getByName
		(pageStyleName)); 
 // Get the property set of the TextCursor 
 XPropertySet xStyleProps = (XPropertySet)UnoRuntime.queryInterface
		(XPropertySet.class,xStyle); 
 xStyleProps.setPropertyValue("LeftMargin",new Short((short)1200)); 
 xStyleProps.setPropertyValue("RightMargin",new Short((short)1200)); 
 xStyleProps.setPropertyValue("BottomMargin",new Short((short)1200));

En C++ cela donne :

//Listing 115
// C++
// create new writer document and get text, then manipulate text 
 
// N'oubliez pas d'ajouter : using namespace com::sun::star::text;
// N'oubliez pas d'ajouter : #include <com/sun/star/text/XTextDocument.hpp>
// N'oubliez pas d'ajouter "com.sun.star.text.XTextDocument \" in the makefile
 
// N'oubliez pas d'ajouter : using namespace com::sun::star::beans;
// N'oubliez pas d'ajouter : #include <com/sun/star/beans/XPropertySet.hpp>
// N'oubliez pas d'ajouter "com.sun.star.beans.XPropertySet \" in the makefile
// N'oubliez pas d'ajouter : using namespace com::sun::star::style;
// N'oubliez pas d'ajouter : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
// N'oubliez pas d'ajouter "com.sun.star.style.XStyleFamiliesSupplier \" in the makefile
// N'oubliez pas d'ajouter : using namespace com::sun::star::container;
 
// N'oubliez pas d'ajouter : #include <com/sun/star/container/XNameContainer.hpp>
// N'oubliez pas d'ajouter "com.sun.star.container.XNameContainer \" in the makefile
 
// N'oubliez pas d'ajouter : #include <com/sun/star/style/XStyle.hpp>
// N'oubliez pas d'ajouter "com.sun.star.style.XStyle \" in the makefile
 
// the first line cannot be translated : already done in our main()
// XComponent xWriterComponent = newDocComponent("swriter"); 
 
	Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
 // Access the text document's multi service factory, which we will need for most of the
 // following examples
	Reference< XMultiServiceFactory > mxDocFactory(xTextDocument,UNO_QUERY);
	Reference< XText > xText = xTextDocument->getText();
 // create a text cursor from the cells XText interface
	Reference< XTextCursor > xTextCursor = xText->createTextCursor(); 
 
 // Get the property set of the cell's TextCursor
	Reference< XPropertySet > xTextCursorProps(xTextCursor,UNO_QUERY); 
 
 // Page Style name 
 //*** I add a intermediate variable because of Any type returned by getPropertyValue 
	Any pageStyleName2 = xTextCursorProps->getPropertyValue
							(OUString::createFromAscii("PageStyleName"));
	OUString pageStyleName;
	pageStyleName2 >>= pageStyleName ;
 
  // Get the StyleFamiliesSupplier interface of the document
	Reference< XStyleFamiliesSupplier > xSupplier(xTextDocument,UNO_QUERY);
 
 // Use the StyleFamiliesSupplier interface to get the XNameAccess interface of the
 // actual style families
	Reference< XNameAccess > xFamilies(xSupplier->getStyleFamilies(),UNO_QUERY);
 
 // Access the 'PageStyles' Family 
	Reference< XNameContainer > xFamily(xFamilies->getByName
				(OUString::createFromAscii("PageStyles")),UNO_QUERY);
// Insert the newly created style into the PageStyles family
	Reference< XStyle > xStyle(xFamily->getByName(pageStyleName),UNO_QUERY);
 
 // Get the property set of the TextCursor 
	Reference< XPropertySet > xStyleProps(xStyle,UNO_QUERY);
	Any lm, rm, bm;
	lm<<=(short)1200; rm<<=(short)1200; bm<<=(short)1200;
	xStyleProps->setPropertyValue(OUString::createFromAscii("LeftMargin"),lm);
	xStyleProps->setPropertyValue(OUString::createFromAscii("RightMargin"),rm);
	xStyleProps->setPropertyValue(OUString::createFromAscii("BottomMargin"),bm);

Ma compétence sur le type "ANY" n'est pas assez complète, alors je ne trouve pas de moyen direct d'utiliser "Any" autre qu'en utilisant des variables intermédiaires. Voyez les trois dernières lignes par exemple.

Personal tools