Difference between revisions of "Programming OOoDraw and OOoImpress"

From Apache OpenOffice Wiki
Jump to: navigation, search
(See also)
(See also)
Line 443: Line 443:
 
* Writing a Program to Control OpenOffice.org, by Franco Pingiori — [http://www.linuxjournal.com/article/8550 Part 1] and [http://www.linuxjournal.com/article/8608 Part 2], Linux Journal
 
* Writing a Program to Control OpenOffice.org, by Franco Pingiori — [http://www.linuxjournal.com/article/8550 Part 1] and [http://www.linuxjournal.com/article/8608 Part 2], Linux Journal
  
[[Category:Draw issues]]
+
[[Category:OOoDraw]]
 
[[Category:Development]]
 
[[Category:Development]]
 
[[Category:Uno:Cpp]]
 
[[Category:Uno:Cpp]]

Revision as of 14:02, 20 May 2006

OOoDraw is my favorite application of OpenOffice.org suite. I think then I will spend a lot of time with this chapter. I start writing this chapter with the Help of Christian post in OOoForum (Code snippets) Working with a Presentation Document in C++ In this chapter, we use again the starting code described here . It consists of a subprogram “ooConnect()” and a main. Working with this code consists of adding new code in the main (see the red comment). We give again the main program slightly modified to fit OOoDraw requirements : [cpp] //Listing 1 Again the starting Code // C++ // adapted for OOoDraw 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 OOoDraw document

   Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(

OUString::createFromAscii("private:factory/sdraw"),

       OUString::createFromAscii("_blank"),
       0,
       Sequence < ::com::sun::star::beans::PropertyValue >());

// add code here

   return 0;

}

Finding the drawing Slide

Bear in mind that if OOoSheet opens with three sheets by default, OOoDraw opens with only one page/slide (index 0). An existing Slide If you only know the index of the slide :

[cpp] //Listing 2 Index access to a draw Slide // C++ // Don't forget to add : using namespace com::sun::star::drawing; // Don't forget to add : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> // Don't forget to add "com.sun.star.drawing.XDrawPagesSupplier \" in the makefile // Don't forget to add : using namespace com::sun::star::container; // Don't forget to add : #include <com/sun/star/container/XIndexAccess.hpp> // Don't forget to add "com.sun.star.container.XIndexAccess \" in the makefile

Reference< XDrawPagesSupplier > rDrawDoc(xcomponent, UNO_QUERY);

// query the XDrawPages Interface Reference< XDrawPages > rDrawPages = rDrawDoc->getDrawPages();

// query the XIndexAccess Interface Reference< XIndexAccess > rPageIndexAccess(rDrawPages, UNO_QUERY);

Any DrawPage = rPageIndexAccess->getByIndex(0);

If you want to know how many pages belong to your document, you can reach it from rPageIndexAccess object with : [cpp] //Listing 3 How many Slides ? // C++ rPageIndexAccess->getCount(); If you only know the page name : [cpp] //Listing 4 Slide Name Access //C++ // Don't forget to add : #include <com/sun/star/container/XNameAccess.hpp> // Don't forget to add "com.sun.star.container.XNameAccess \" in the makefile

//query the XNameAccess Interface Reference< XNameAccess > rNameAccess(rDrawPages, UNO_QUERY);

if (rNameAccess->hasByName(OUString::createFromAscii("Slide 1"))) { Any DrawPage = rNameAccess-> getByName(OUString::createFromAscii("Slide 1")); }

Create, rename, copy and remove a Slide

Create a new slide with a known Index : [cpp] //Listing 5 Creating a new Slide // C++ // Don't forget to add : using namespace com::sun::star::drawing; // Don't forget to add : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> // Don't forget to add "com.sun.star.drawing.XDrawPagesSupplier \" in the makefile // Don't forget to add : using namespace com::sun::star::container; // Don't forget to add : #include <com/sun/star/container/XIndexAccess.hpp> // Don't forget to add "com.sun.star.container.XIndexAccess \" in the makefile

Reference< XDrawPagesSupplier > rDrawDoc(xcomponent, UNO_QUERY);

// query the XDrawPages Interface Reference< XDrawPages > rDrawPages = rDrawDoc->getDrawPages();

// query for the XDrawPage Inteface Reference< XDrawPage > rDrawPage = rDrawPages->insertNewByIndex(2); In this example, the new slide is indexed with value 2 and then its default name is “Slide 3”. You can see a difference between [chapter 6.1.1] previous code and this one : the former uses an Any type variable (DrawPage) although the latter code obtains directly a XDrawPage interface. One more step is needed to obtain a XDrawPage when working with Any : a UNO query. Add the above code to the former and you obtain like the latter code a XDrawPage interface. [cpp] //Listing 6 Accessing the XDrawPage Service // C++ // Don't forget to add : #include <com/sun/star/drawing/XDrawPage.hpp> // Don't forget to add "com.sun.star.drawing.XDrawPage \" in the makefile // Query the XDrawPage Interface Reference< XDrawPage > rDrawPage(DrawPage, UNO_QUERY); How to rename your slide ? You have to change the Name property of the slide : [cpp] //Listing 7 Renaming a Slide // C++ // Don't forget to add : #include <com/sun/star/container/XNamed.hpp> // Don't forget to add "com.sun.star.container.XNamed \" in the makefile

// query for the XNamed Interface Reference< XNamed > rNamed(rDrawPage, UNO_QUERY); rNamed->setName(OUString::createFromAscii("My second page")); The XNamed interface is your friend as seen in this code. The corresponding IDL code is given now :

// IDL
module com {  module sun {  module star {  module container {

interface XNamed: com::sun::star::uno::XInterface
{
	string getName();
	[oneway] void setName( [in] string aName );
};
}; }; }; };  

As seen only two methods are available setName already used in the example and getName. We have already focused our attention on the difference between PageDraw and rPageDraw variables : please note we can use both in the previous code. And now you want to copy a page : you have to query the XDrawPageDuplicator interface. We have to pass a draw page reference to the method duplicate(). A new draw page is appended at the end of the page list, using the default naming scheme for pages, Slide n . [cpp] //Listing 8 This Listing doesn't work at the Moment // C++ to check (doesn't work !!!) // Don't forget to add : #include <com/sun/star/drawing/XDrawPageDuplicator.hpp> // Don't forget to add "com.sun.star.drawing.XDrawPageDuplicator \" in the makefile

// query for the XDrawPageDuplicator Interface Reference< XDrawPageDuplicator > rDrawPageDuplicator(rDrawPage(s)???, UNO_QUERY);

Reference< XDrawPage> rDrawPage2 = rDrawPageDuplicator->duplicate(rDrawPage); // This last line doesn't work If you want to remove a page known by its index [cpp] //Listing 9 Index access // C++ // Don't forget to add : using namespace com::sun::star::drawing; // Don't forget to add : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> // Don't forget to add "com.sun.star.drawing.XDrawPagesSupplier \" in the makefile // Don't forget to add : using namespace com::sun::star::container; // Don't forget to add : #include <com/sun/star/container/XIndexAccess.hpp> // Don't forget to add "com.sun.star.container.XIndexAccess \" in the makefile

Reference< XDrawPagesSupplier > rDrawDoc(xcomponent, UNO_QUERY);

// query the XDrawPages Interface Reference< XDrawPages > rDrawPages = rDrawDoc->getDrawPages();

// query for the XDrawPage Inteface Reference< XDrawPage > rDrawPage = rDrawPages->insertNewByIndex(0);

rDrawPages->remove(rDrawPage); Removing a page known by its name is let as an exercise.

Setting the Focus on a Slide

If you obtain a XDrawPage interface corresponding to a hidden page and you want to put it on the top : [cpp] //Listing 10 Setting a Slide as currently focused // C++ // First Obtain a XDrawPage interface for this page, and after :

// Don't forget to add : using namespace com::sun::star::frame; // Don't forget to add : #include <com/sun/star/frame/XModel.hpp> // Don't forget to add "com.sun.star.frame.XModel \" in the makefile

// Don't forget to add : #include <com/sun/star/drawing/XDrawView.hpp> // Don't forget to add "com.sun.star.drawing.XDrawView \" in the makefile

// Query the XModel Interface Reference< XModel > rmodel(rDrawDoc, UNO_QUERY); Reference< XController > ctl = rmodel->getCurrentController();

// Query the XDrawView interface Reference< XDrawView > rDrawView(ctl, UNO_QUERY); rDrawView->setCurrentPage(rDrawPage);

Property of a Slide

Properties belong to the slide :

slide's properties
Properties Signification
Name Name of the slide
BorderLeft Left margin in 1/100 mm
BorderRight Right margin in 1/100 mm
BorderTop Top margin in 1/100 mm
MBorderBottom Bottom margin in 1/100 mm
Height Height of the page in 1/100 mm
Width Width of the page in 1/100 mm
Number Number of the page begins from 1
Orientation Portrait : com.sun.star.view.PaperOrientation.PORTRAIT

or Landscape : com.sun.star.view.PaperOrientation.LANDSCAPE

If you want for instance retrieve the page width (a property), use this code : [cpp] //Listing 11 Slide Properties // 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 // find out page width Reference< XPropertySet > rPageProps(rDrawPage, UNO_QUERY);

Any ApageWidth = rPageProps->getPropertyValue(OUString::createFromAscii("Width")); sal_Int32 pageWidth; ApageWidth >>= pageWidth; If you want to set the four page margins properties you can use this code : [cpp] //Listing 12 Margin Properties // C++ // Obtain rPageProps like previous code Any props[4]; props[0] <<= (short)1200; props[1] <<= (short)1200; props[2] <<= (short)1200; props[3] <<= (short)1200;

rPageProps->setPropertyValue(OUString::createFromAscii("BorderLeft"),props[0]); rPageProps->setPropertyValue(OUString::createFromAscii("BorderRight"),props[1]); rPageProps->setPropertyValue(OUString::createFromAscii("BorderTop"),props[2]); rPageProps->setPropertyValue(OUString::createFromAscii("BorderBottom"),props[3]); An other simpler way is to use the build in makeAny function : [cpp] //Listing 13 Margin Properties and makeAny Function // C++ // Obtain rPageProps like previous code rPageProps-> setPropertyValue(OUString::createFromAscii("BorderLeft"),makeAny((short)1200)); rPageProps-> setPropertyValue(OUString::createFromAscii("BorderRight"),makeAny((short)1200)); rPageProps-> setPropertyValue(OUString::createFromAscii("BorderTop"),makeAny((short)1200)); rPageProps-> setPropertyValue(OUString::createFromAscii("BorderBottom"),makeAny((short)1200)); It's time now to draw shapes on pages.

Drawing with OOoDraw

Inserting a Shape

With OOoDraw text is considered as a shape like rectangle, ellipses... Let's then start with a TextShape : [cpp] //Listing 14 Inserting a text Shape // C++ // Don't forget to add :using namespace com::sun::star::awt; for Point and Size

// Don't forget to add : #include <com/sun/star/drawing/XShape.hpp> // Don't forget to add "com.sun.star.drawing.XShape \" in the makefile

// Don't forget to add : #include <com/sun/star/drawing/XShapes.hpp> // Don't forget to add "com.sun.star.drawing.XShapes \" in the makefile // Don't forget to add : using namespace com::sun::star::text; // 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

Reference< XMultiServiceFactory > DocFactory(xcomponent, UNO_QUERY); Reference< XInterface > textshape = DocFactory->createInstance( OUString::createFromAscii("com.sun.star.drawing.TextShape") ); Reference< XShape > rTxtShape(textshape, UNO_QUERY);

Point *Pos = new ( Point ); Size *TheSize = new ( Size ); Pos->X = 2000; Pos->Y = 6000; TheSize->Width = 7000; TheSize->Height = 2000; rTxtShape->setPosition(Pos); rTxtShape->setSize(*TheSize);

// Query XShapes Interface Reference< XShapes > Shapes(rDrawPage, UNO_QUERY); Shapes->add(rTxtShape);

// Query the XText Interface Reference< XText > rText(rTxtShape, UNO_QUERY);

       rText->setString(OUString::createFromAscii("Hello people around the world"));

This listing when executed writes out “Hello people around the world” on a page. Changing a shape is simple : if you want to draw a rectangle, the only line to change is : [cpp] // Listing 15 Change this Line // C++ Reference< XInterface > textshape = DocFactory->createInstance( OUString::createFromAscii("com.sun.star.drawing.TextShape") ); with : [cpp] //Listing 16 Inserting a Rectangle Shape // C++ Reference< XInterface > textshape = DocFactory->createInstance( OUString::createFromAscii("com.sun.star.drawing.RectangleShape") ); We shall examine how to draw a shape again later. Note that you can write text too with this new shape as explained now.

Writing Text in a Shape

Writing text in a shape is obtained with the same way as writing text in a TextShape. For a RectangleShape (rRecShape) we have then : [cpp] //Listing 17 setString method to insert a Text // C++ // Query the XText Interface Reference< XText > rText(rRecShape, UNO_QUERY);

       rText->setString(OUString::createFromAscii("Hello"));

which draws a rectangle and writes out “Hello” in this rectangle.

Giving a Name to the Shape

Every shape can receive a name. This feature is very interesting if you want transform OOoDraw as a graphical front-end. Here is a code example which give a name to a shape : [cpp] //Listing 18 Naming a Shape // 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

// Query the XPropertySet Interface Reference< XPropertySet > shapeprops(rtxtShape, UNO_QUERY); shapeprops->setPropertyValue(OUString::createFromAscii("Name"), makeAny(OUString::createFromAscii("demo"))); The XShapes interface allows adding, removing as shown in the IDL file :

//Listing 19 Index access to Shapes (IDL file)
// IDL
interface XShapes: com::sun::star::container::XIndexAccess
{
	void add( [in] com::sun::star::drawing::XShape xShape );
	void remove( [in] com::sun::star::drawing::XShape xShape );
};

The XIndexAccess inheritance allows also getcount() and getByIndex. This allows the construction of a loop on all shapes.

Graphics and OOoDraw

In OOoDraw a graphic is a bitmap or vector picture. We are interesting in this chapter with bitmap graphics.

Inserting a bitmap

Here is an example which insert a bitmap. We start as in previous chapter : with a drawing page. The only difference is again with the shape which is now a GraphicObjectShape. And we have to give a file link : [cpp] //Listing 20 Inserting an Image in a Slide // C++ // Don't forget #include <osl/file.hxx>

// Don't forget to add :using namespace com::sun::star::awt; for Point and size

// Don't forget to add : #include <com/sun/star/drawing/XShape.hpp> // Don't forget to add "com.sun.star.drawing.XShape \" in the makefile

// Don't forget to add : #include <com/sun/star/drawing/XShapes.hpp> // Don't forget to add "com.sun.star.drawing.XShapes \" in the makefile

// 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< XMultiServiceFactory > DocFactory(xcomponent, UNO_QUERY); Reference< XInterface > GraphicShape = DocFactory->createInstance( OUString::createFromAscii("com.sun.star.drawing.GraphicObjectShape")); Reference< XShape > rGrafShape(GraphicShape, UNO_QUERY);

Point *Pos = new (Point); Size *TheSize = new ( Size ); Pos->X = 2000; Pos->Y = 6000; TheSize->Width = 7000; TheSize->Height = 2000; rGrafShape->setPosition(*Pos); rGrafShape->setSize(*TheSize); OUString sImageUrl; osl::FileBase::getFileURLFromSystemPath(

                OUString::createFromAscii("/home/smoutou/photoperso.jpg"),sImageUrl);

Reference< XPropertySet > rShapeProps(rGrafShape, UNO_QUERY); rShapeprops->setPropertyValue(OUString::createFromAscii("GraphicURL"), makeAny(sImageUrl))

// Query XShapes Interface Reference< XShapes > Shapes(rDrawPage, UNO_QUERY); Shapes->add(rGrafShape); This code doesn't insert the picture in the document but the link. Inserting effectively is not possible with the API but with menus :

  1. Edition -> link

select all the pictures link click on deconnect button; confirm

  1. Save the document.

Changing the Size of a Picture

To keep proportion when changing the size, you have first to calculate it. For that we first get the picture's size in pixels but this is possible only after the “Shapes->add(rGrafShape);” Here is an example which resize the picture with a chosen width and a height calculated. [cpp] //Listing 21 Modifying a Bitmap Size //C++ // Don't forget to add : #include <com/sun/star/awt/XBitmap.hpp> // Don't forget to add "com.sun.star.awt.XBitmap \" in the makefile

Any Bitmap = rShapeProps-> getPropertyValue(OUString::createFromAscii("GraphicObjectFillBitmap")); Reference< XBitmap > rBitmap(Bitmap, UNO_QUERY); // query the size in pixel *TheSize = rBitmap->getSize(); sal_Int32 proportion = TheSize->Height/TheSize->Width; TheSize->Width = 14000; TheSize->Height = 14000*proportion; rGrafShape->setSize(*TheSize);

Inserting many Pictures

Every time you insert a picture, you have to query many times the GraphicObjectShape, even if you insert many times the same picture.

Finding a Picture with its Name

The picture like other shapes can be accessed with an index, not very easy to use. But we can give them a name (see 6.2.3 Giving a Name to the Shape) We shall tackle this problem later.

If you want to go further with shapes go to next chapter.

See also

Personal tools