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

From Apache OpenOffice Wiki
Jump to: navigation, search
m (La méthode insertString)
m (Traduire le code Java en C++)
Line 530: Line 530:
 
xWordCursor->gotoNextWord(true);
 
xWordCursor->gotoNextWord(true);
 
</pre>
 
</pre>
 +
 +
=Accéder aux propriétés du curseur=
 +
Si l'on veut aller plus en avant et utiliser des caractères gras par exemple, on doit accéder aux propriétés des curseurs. Nous donnons un exemple qui part du code précédent et met le texte ajouter en gras. Cela peut être fait en remarquant que le code précédent insert un texte avec le dernier paramètre positionné à true. Cela signifie que la chaîne insérée est marquée. Si l'n change simplement une propriété du curseur, cela changera le texte. Ainsi seulement ajouter le code ci-dessous au listing 22 :
 +
<source lang="cpp">
 +
//Listing 23 Setting Text in bold
 +
//C++
 +
// Don't forget to add : using namespace com::sun::star::beans;
 +
// Don't forget to add : #include <com/sun/star/beans/XPropertySet.hpp>
 +
// Don't forget to add "com.sun.star.beans.XPropertySet \" in the makefile
 +
    Reference< XPropertySet> xCursorProps (xTextCursor,UNO_QUERY);
 +
    Any cw;
 +
// Don't forget to add : using namespace com::sun::star::awt::FontWeight;
 +
// Don't forget to add : #include <com/sun/star/awt/FontWeight.hpp>
 +
// Don't forget to add "com.sun.star.awt.FontWeight \" in the makefile
 +
    cw <<= BOLD;
 +
    xCursorProps->setPropertyValue(OUString::createFromAscii("CharWeight"),cw);
 +
</source>
 +
met « we are here  » en gras. Comme déjà vu [[Documentation/FR/LanguageCpp#Aller_plus_loin_:_les_constantes_UNO|ici]] nous sommes de nouveau confonté à des constantes. BOLD est une constante. Elle provient du fichier IDL suivant :
 +
<source lang="idl">
 +
//Listing 24 Constants to set the Font Weight
 +
//IDL
 +
module com {  module sun {  module star {  module awt { 
 +
constants FontWeight
 +
{
 +
/** The font weight is not specified/known.    */
 +
const float DONTKNOW = 0.000000;
 +
/** specifies a 50% font weight.    */
 +
const float THIN = 50.000000;
 +
/** specifies a 60% font weight.    */
 +
const float ULTRALIGHT = 60.000000;
 +
/** specifies a 75% font weight.    */
 +
const float LIGHT = 75.000000;
 +
/** specifies a 90% font weight.    */
 +
const float SEMILIGHT = 90.000000;
 +
/** specifies a normal font weight.    */
 +
const float NORMAL = 100.000000;
 +
/** specifies a 110% font weight.    */
 +
const float SEMIBOLD = 110.000000;
 +
/** specifies a 150% font weight.    */
 +
const float BOLD = 150.000000;
 +
/** specifies a 175% font weight.    */
 +
const float ULTRABOLD = 175.000000;
 +
/** specifies a 200% font weight.    */
 +
const float BLACK = 200.000000;
 +
};
 +
}; }; }; };
 +
</source>
 +
Et les commentaires dans le programme indiquent comment utiliser ces constantes.
 +
 +
Voir aussi <idl>com.sun.star.beans.XPropertySet</idl> et <idl>com.sun.star.awt.FontWeight</idl>
  
 
=Traduire le code Java en C++=
 
=Traduire le code Java en C++=

Revision as of 13:14, 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 >());

tandis que l'ouverture d'un document existant se fait par :

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

Gestion du texte

Trouver le texte

Nous commençons par montrer comment on peut trouver le texte ouplus exactement l'interface XText.

 
//Listing 13 Obtenir l'interface XText
// C++
// Don't forget to add : using namespace com::sun::star::text;
// Don't forget to add : #include <com/sun/star/text/XTextDocument.hpp>
// Don't forget to add "com.sun.star.text.XTextDocument \" in the makefile
// Don't forget to add : #include <com/sun/star/text/XText.hpp>
// Don't forget to add "com.sun.star.text.XText \" in the makefile
 
//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 >());
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();

La chose la plus intéressante est de faire des choses visibles (je veux dire ajouter ou retirer du texte).

Voir aussi com.sun.star.text.XTextDocument et com.sun.star.text.XText.

Ecrire du texte dans le document

La manière la plus simple pour écrire du texte dans un document et la méthode setString de l'interface XText interface. Cela nous donne en l'occurrence ce code :

//Listing 14 Ecrire du texte dans un document OOoWriter
// C++
// Don't forget to add : using namespace com::sun::star::text;
// Don't forget to add : #include <com/sun/star/text/XTextDocument.hpp>
// Don't forget to add "com.sun.star.text.XTextDocument \" in the makefile
// Don't forget to add : #include <com/sun/star/text/XText.hpp>
// Don't forget to add "com.sun.star.text.XText \" in the makefile
 
//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 >());
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();
    xText->setString(OUString::createFromAscii("Hello"));

Qu'arrive-t-il si l'on remplace la dernière ligne par les deux ci-dessous :

//Listing 15 More on setString Method (XText Interface)
// C++
    xText->setString(OUString::createFromAscii("Hello")); 
    xText->setString(OUString::createFromAscii(" All around the world"));

Réponse : seulement : only « All around the world » est écrit. Cela fonctionne donc comme attendu : setString est setString. Ainsi si vous voulez mettre du texte derrière un autre texte une autre méthode doit être découverte.

Voir aussi com.sun.star.text.XTextDocument et com.sun.star.text.XText.

Gérer du texte avec l'interface XTextRange

L'interface XTextRange est capable de gérer le texte avec une méthode setString mais en gardant l'ancien texte. Par exemple si vous voulez ouvrir un document (contenant du texte) et ajouter du texte au tout début, faites comme ceci :

//Listing 16 Using the XTextRange Interface 
// C++
    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 >());
 
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();
 
    Reference<XTextRange> xTextRange = xText->getStart();
    xTextRange->setString(OUString::createFromAscii("Start here "));

La méthode getEnd() peut être aussi utilisée.

Voir aussi com.sun.star.text.TextRange.

Nous voyons ainsi comment insérer du texte au tout début et devinons comment l'insérer à la fin. Mais si vous voulez gérer la place exacte où vous voulez insérer votre texte alors l'interface XCursorText est votre amie.

L'interface XTextCursor

Le Developer's Guide indique : le code ci-dessus n'est pas flexible. Si vous voulez gagner en flexibilité, créez un curseur de texte qui est une zone de texte (text range) mouvante. Comme l'interface XTextCursor hérite de l'interface XTextRange, un curseur est un XTextRange et incorpore donc les méthodes d'un XTextRange:

com::sun::star::text::XText getText()
com::sun::star::text::XTextRange getStart()
com::sun::star::text::XTextRange getEnd()
string getString()
void setString( [in] string aString)

Comme déjà vu, la méthode setString est aussi disponible et fonctionne toujours de la même manière.

//Listing 17 More on setString Method (XTextCursor Interface)
// 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 >());
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();
    Reference< XTextCursor> xTextCursor = xText->createTextCursor();
    xTextCursor->setString(OUString::createFromAscii("Hello")); 
    xTextCursor->setString(OUString::createFromAscii(" All around the world"));

Voir aussi com.sun.star.text.XTextCursor.

Une nouvelle question : qu'arrive-t-il si l'on utilise ce code mais sans instancier une deuxième fois la variable cursor entre deux appels setString ?

//Listing 18 More on setString Method (XTextCursor interface)
// 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 >());
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();
    Reference< XTextCursor> xTextCursor = xText->createTextCursor();
    xTextCursor->setString(OUString::createFromAscii("Hello ")); 
    xTextCursor = xText->createTextCursor(); // added
    xTextCursor->setString(OUString::createFromAscii("All around the world"));

Réponse : « all around the worldHello  » est écrit montrant que quand vous initialisez une interface XTextCursor, le curseur est toujours au début du document.

Voir aussi com.sun.star.text.XTextCursor, com.sun.star.text.XText et com.sun.star.text.XTextDocument.

Si vous voulez votre texte à la place adéquate, vous pouvez utiliser ce code :

//Listing 19 More on goRight Method (XTextCursor Interface)
// 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 >());
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();
    Reference< XTextCursor> xTextCursor = xText->createTextCursor();
    xTextCursor->setString(OUString::createFromAscii("Hello ")); 
    xTextCursor = xText->createTextCursor();
    xTextCursor ->goRight(6,0); // added to move the cursor
    xTextCursor->setString(OUString::createFromAscii("All around the world"));

où la méthode goRight est utilisée. Ce n'est pas la bonne façon de faire, instancier deux fois la variable xTextCursor. Mais ce code nous montrece que l'on peut faire avec un curseur : le déplacer. Bien sûr la méthode goLeft existe aussi. Le fichier IDL correspondant est montré maintenant :

//Listing 20 XTextCursor Interface
// IDL
module com {  module sun {  module star {  module text {
interface XTextCursor: com::sun::star::text::XTextRange
{
	/** sets the end of the position to the start.*/
	[oneway] void collapseToStart();
	/** sets the start of the position to the end.*/
	[oneway] void collapseToEnd();
	/** determines if the start and end positions are the same.*/
	boolean isCollapsed();
	/** moves the cursor the specified number of characters to the left.*/
	boolean goLeft( [in] short nCount,
			 [in] boolean bExpand );
	/** moves the cursor the specified number of characters to the right.*/
	boolean goRight( [in] short nCount,
			 [in] boolean bExpand );
	/** moves the cursor to the start of the text.*/
	void gotoStart( [in] boolean bExpand );
	/** moves the cursor to the end of the text.*/
	void gotoEnd( [in] boolean bExpand );
	/** moves or expands the cursor to a specified <type>TextRange</type>.*/
	void gotoRange( [in] com::sun::star::text::XTextRange xRange,
			 [in] boolean bExpand );
};
}; }; }; };

Ce qui peut être réellement fait avec cette interface est donné dans le service <OpenOffice.org1.1_SDK>/idl/com/sun/star/text/TextCursor.idl. En fait l' introspection de XTextCursor me montre que les méthodes ci-dessous sont disponibles :

...
boolean gotoPreviousParagraph([IN]boolean)
boolean gotoNextParagraph([IN]boolean)
boolean gotoEndOfParagraph([IN]boolean)
boolean gotoStartOfParagraph([IN]boolean)
boolean isEndOfParagraph()
boolean isStartOfParagraph()
boolean gotoStartOfWord([IN]boolean)
boolean gotoEndOfWord([IN]boolean)
boolean gotoPreviousWord([IN]boolean)
boolean gotoNextWord([IN]boolean)
boolean isEndOfWord()
boolean isStartOfWord()
boolean gotoEndOfSentence([IN]boolean)
boolean gotoStartOfSentence([IN]boolean)
boolean gotoPreviousSentence([IN]boolean)
boolean gotoNextSentence([IN]boolean)
boolean isEndOfSentence()
boolean isStartOfSentence()
void gotoRange([IN]com.sun.star.text.XTextRange,[IN]boolean)
void gotoEnd([IN]boolean)
void gotoStart([IN]boolean)
boolean goRight([IN]short,[IN]boolean)
boolean goLeft([IN]short,[IN]boolean)
...

Mais comme d'habitude tout n'est pas disponible d'un coup, il vous faudra des requêtes UNO_QUERY. Pour donner un exemple utilisant la méthode gotoEndOfWord, on commence par modifier le programme pour lire un fichier existant plutôt que de partir d'un fichier vierge et demandons une interface XWordCursor :

//Listing 21 Using the XWordCursor Service when loading a File
// C++
// Don't forget to add : using namespace com::sun::star::text;
// Don't forget to add : #include <com/sun/star/text/XTextDocument.hpp>
// Don't forget to add "com.sun.star.text.XTextDocument \" in the makefile
// Don't forget to add : #include <com/sun/star/text/XWordCursor.hpp>
// Don't forget to add "com.sun.star.text.XWordCursor \" in the makefile
// Don't forget to add : #include <osl/file.hxx>  
 
    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 >());
 
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();
    Reference< XTextCursor> xTextCursor = xText->createTextCursor();
    Reference < XWordCursor > xWordCursor (xTextCursor,UNO_QUERY);
    xWordCursor->gotoEndOfWord(0);
    xWordCursor->setString(OUString::createFromAscii(" OK"));

Jetez un coup d'oeil sur le fichier XWordCursor.idl file pour apprendre ce qui est possible de faire avec la variable xWordCursor de l'exemple précédent. Pour aller plus loin aller à Translating OOoBasic programs into C++.

See also com.sun.star.text.XTextDocument and com.sun.star.text.XWordCursor.

La méthode insertString

Le Developer's Guide indique : le curseur peut être mis où cela est nécessaire et la chaîne de caractère positionnée après. Cela n'a aucun inconvénient. Après le positionnement de la chaîne, la chaîne insérée est toujours sélectionnée. Cela indique que du nouveau texte ne peut pas être inséré sans bouger le curseur une nouvelle fois. Ainsi la méthode la plus flexible pour insérer du texte à l'aide d'un curseur est la méthode insertString() de l'interface XText. Elle prend un XTextRange comme cible de la zone qui est remplacé durant l'insertion, une chaîne à insérer et un paramètre booléen qui détermine si le texte inséré doit être absorbé par le curseur après avoir été inséré. Le XTextRange pourrait être un XTextRange. Le XTextCursor est un XTextRange, ainsi il est utilisé ici:

void insertString( [in] com::sun::star::text::XTextRange xRange, 
					[in] string aString, 
					[in] boolean bAbsorb) 

Pour insérer du texte séquentiellement le paramètre bAbsorb doit être positionné à false, ainsi le XTextRange se rétrécit à la fin de l'insertion. Si bAbsorb est true, la zone de texte sélectionne le nouveau texte inséré. La chaîne qui était sélectionnée par la zone de texte avant l'insertion est effacé..

Considerez l'utilisation de insertString() ci-dessosu :

//Listing 22 The insertString Method
//C++
    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 >());
 
    Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
    Reference< XText > xText = xTextDocument->getText();
    Reference< XTextCursor> xTextCursor = xText->createTextCursor();
// Don't forget to add : #include <com/sun/star/text/XWordCursor.hpp>
// Don't forget to add "com.sun.star.text.XWordCursor \" in the makefile    
    Reference < XWordCursor > xWordCursor (xTextCursor,UNO_QUERY);
    xWordCursor->gotoNextWord(false); 
    xWordCursor->gotoNextWord(false); 
    xWordCursor->gotoNextWord(true);
// Use the XSimpleText interface to insert a word at the current cursor
// location, over-writing
// the current selection (the third word selected above) 
// a UNO query because xTextRange = xWordCursor->getStart(); doesn't work  
    Reference<XTextRange> xTextRange (xWordCursor,UNO_QUERY);
    xText->insertString(xTextRange,OUString::createFromAscii("We are here "),true);

Ce programme prend le troisième mot et le remplace par «We are here». En premier lieu, je voulais utiliser quelque chose comme

xTextRange = xWordCursor->getStart();

pour retrouver l'interface XTextRange dont j'avais besoin pour le insertString. Cela fonctionnait seulement de manière partielle parceque l'information de sélection était perdue et je n'étais pas capable de remplacer le mot sélectionné à l'aide de l'instruction :

xWordCursor->gotoNextWord(true);

Accéder aux propriétés du curseur

Si l'on veut aller plus en avant et utiliser des caractères gras par exemple, on doit accéder aux propriétés des curseurs. Nous donnons un exemple qui part du code précédent et met le texte ajouter en gras. Cela peut être fait en remarquant que le code précédent insert un texte avec le dernier paramètre positionné à true. Cela signifie que la chaîne insérée est marquée. Si l'n change simplement une propriété du curseur, cela changera le texte. Ainsi seulement ajouter le code ci-dessous au listing 22 :

//Listing 23 Setting Text in bold
//C++
// Don't forget to add : using namespace com::sun::star::beans;
// Don't forget to add : #include <com/sun/star/beans/XPropertySet.hpp>
// Don't forget to add "com.sun.star.beans.XPropertySet \" in the makefile
    Reference< XPropertySet> xCursorProps (xTextCursor,UNO_QUERY);
    Any cw;
// Don't forget to add : using namespace com::sun::star::awt::FontWeight;
// Don't forget to add : #include <com/sun/star/awt/FontWeight.hpp>
// Don't forget to add "com.sun.star.awt.FontWeight \" in the makefile
    cw <<= BOLD;
    xCursorProps->setPropertyValue(OUString::createFromAscii("CharWeight"),cw);

met « we are here  » en gras. Comme déjà vu ici nous sommes de nouveau confonté à des constantes. BOLD est une constante. Elle provient du fichier IDL suivant :

//Listing 24 Constants to set the Font Weight
//IDL
module com {  module sun {  module star {  module awt {  
constants FontWeight
{ 
	/** The font weight is not specified/known.     */	
	const float DONTKNOW = 0.000000; 
	/** specifies a 50% font weight.     */	
	const float THIN = 50.000000; 
	/** specifies a 60% font weight.     */	
	const float ULTRALIGHT = 60.000000; 
 	/** specifies a 75% font weight.     */	
	const float LIGHT = 75.000000; 
 	/** specifies a 90% font weight.    */	
	const float SEMILIGHT = 90.000000; 
	/** specifies a normal font weight.     */	
	const float NORMAL = 100.000000; 
	/** specifies a 110% font weight.     */	
	const float SEMIBOLD = 110.000000; 
 	/** specifies a 150% font weight.    */	
	const float BOLD = 150.000000; 
	/** specifies a 175% font weight.     */	
	const float ULTRABOLD = 175.000000; 
	/** specifies a 200% font weight.     */	
	const float BLACK = 200.000000; 
}; 
}; }; }; };

Et les commentaires dans le programme indiquent comment utiliser ces constantes.

Voir aussi com.sun.star.beans.XPropertySet et com.sun.star.awt.FontWeight

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