Writer/API/Overview

From Apache OpenOffice Wiki
Jump to: navigation, search

In this chapter, we use again the starting code described in previous chapter. It consists of a subprogram “ooConnect()” and a main(). Starting with this code consists in adding new code in the main() where « add code here » is quoted in red. We give for the third time the main program : [cpp] //Listing 1 Our starting Code // 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 >());

// add code here

   return 0;

} We remember the reader that for the examples below we use the “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/ProfUNO/CppBinding” example. Our code is put in “office_connect.cxx” file. If needed, comments in the code indicate what to add into the makefile and into the source code. The function ooConnect() is also used and not presented here : we have already studied such a function, so it should be quite familiar to us by now. If not, have a look in previous chapter.


Using the Dispatcher and recording Macros

The first way we want to examine is the use of the dispatcher before using direct UNO calls in next section. This is a very straightforward way but probably internationalization dependent. If you record a macro, you obtain a OOoBasic code which uses the dispatcher instead of direct UNO call.

Introduction

For instance if you have a OOoWriter document, and you record a macro when inserting text and formating it, you obtain something like: [oobas] '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 How to translate such a code in C++ ? The problem is to handle the dispatcher.

The first step is to obtain a XDispatcherHelper service. [cpp] //Listing 3 Querying the XDispatchHelper Service // C++ Reference< XDispatchHelper > rDispatchHelper = Reference< XDispatchHelper > ( rOfficeServiceManager->createInstance(

                             OUString( RTL_CONSTASCII_USTRINGPARAM(
                             "com.sun.star.frame.DispatchHelper" ))), UNO_QUERY );

The second step is to obtain the XFrame interface starting from Desktop and after obtaining a XDispatchProvider starting from the previous frame (it seems very important to start from frame). [cpp] //Listing 4 Obtaining a XFrame Service // C++ Reference< XFrame > rFrame=rDesktop->getCurrentFrame();

Reference< XDispatchProvider > rDispatchProvider(rFrame,UNO_QUERY); The third step is to declare your array (Sequence in C++) of “PropertValue” and gives the values : [cpp] //Listing 5 The Property pair Name/Value // C++ Sequence < PropertyValue > args1(1);

args1[0].Name = OUString::createFromAscii("Text"); args1[0].Value <<= OUString::createFromAscii("demo de macro"); and the final step is to call the dispatcher : [cpp] //Listing 6 The Dispatcher Call // C++ rDispatchHelper->executeDispatch(rDispatchProvider, OUString::createFromAscii(".uno:InsertText"), OUString::createFromAscii(""), 0, args1); The rest of OOoBasic code can be now easily translated as shown below : [cpp] //Listing 7 Other Dispatch Calls // 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); >/code>

Dispatcher and Internationalization

One of the problem you will encounter with this programming style is : how can we write such programs running everywhere in the world ? If you work with a French OOo and record a macro you will encounter properties' values but in French. For instance, if I record a macro when inserting an image I obtain the OOoBasic code : <code>[oobas] '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 where you guess I use a French OpenOffice.org version. If you directly translate this code in C++ you obtain : [cpp] //Listing 9 Inserting an 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); which works properly. Translating it in English still work with my French OOo : [cpp] //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"); .... But we cannot avoid the question : does the first French version work on all computers ? I have no answer. I suppose the English version works everywhere. And impossible to avoid this second query : how can I know the « <tous les Formats> » is translated by « <All Formats> » in English ?

See also

Personal tools