Programming OOoDraw and OOoImpress

From Apache OpenOffice Wiki
Jump to: navigation, search

Edit-find-replace.png This article needs to be checked for accuracy and style.

Introduction

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()”

// Listing 0
// C++
#include <stdio.h>
#include <cppuhelper/bootstrap.hxx>
#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
// added
#include <com/sun/star/frame/XComponentLoader.hpp>
 
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::bridge;
// added
using namespace com::sun::star::frame;
 
using namespace rtl;
using namespace cppu;
 
// a procedure for what the so called boostrap
Reference< XMultiServiceFactory > ooConnect(){
   // 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 NULL;
   }
   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 NULL;
      }
 
      // query for the simpler XMultiServiceFactory interface, sufficient for scripting
      Reference< XMultiServiceFactory > rOfficeServiceManager (rInstance, UNO_QUERY);
 
      if( ! rOfficeServiceManager.is() ){
            printf( "XMultiServiceFactory interface is not exported for StarOffice.ServiceManager\n" );
            return NULL;
        }       
        return rOfficeServiceManager;
   }
   catch( Exception &e ){
      OString o = OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );
      printf( "Error: %s\n", o.pData->buffer );
      return NULL;
   }
   return NULL;
}

Note : You have eventually to change "port=8100" into "port=2083" for recent SDK (after 2.X).

You can have a look at :

  1. com.sun.star.uno.XComponentContext, com.sun.star.lang.XMultiComponentFactory, com.sun.star.uno.XInterface, com.sun.star.bridge.XUnoUrlResolver and com.sun.star.lang.XMultiServiceFactory interfaces,
  2. com.sun.star.bridge.UnoUrlResolver service

The main function is examined now. Working with this code consists of adding new code in the main (see the comment). We give again the main program slightly modified.

Documentation caution.png To fit OOoDraw requirements you have to replace the string "private:factory/scalc" with "private:factory/sdraw".


//Listing 0b Again our starting main Code
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 spreadsheet
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/scalc"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());
// add code here
    return 0;
}

This code is called a bootstrap and uses :

  1. com.sun.star.lang.XMultiServiceFactory, com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader and com.sun.star.lang.XComponent interfaces
  2. com.sun.star.frame.Desktop service
  3. com.sun.star.beans.PropertyValue structure.

Remember each time you query for an interface you have to add code lines (if they don't exist) in the source code and a line in the makefile. I will generally add comments to prevent omissions. You can find more explanations here (if you are not a beginner).

Documentation note.png Important Note : The more important point in the compilation chain of the examples above is that cppumaker will construct every hpp and hdl files you need in your application. The SDK doesn't provide every hpp files, but you have to construt them starting from IDL files provided by SDK.
Documentation note.png It is possible to construct all the hpp files when installing the SDK as mentioned in a Windows installation. It's also possible with other OS. In doing so, you don't need modifying your MakeFile.

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 only the index of the slide is known, have look at com.sun.star.drawing.XDrawPagesSupplier and com.sun.star.container.XIndexAccess interfaces :

//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 :

//Listing 3 How many Slides ?
// C++
	rPageIndexAccess->getCount();

If you only know the page name (see com.sun.star.container.XNameAccess interface):

//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

Create a new slide with a known Index (see com.sun.star.drawing.XDrawPagesSupplier, com.sun.star.drawing.XDrawPage, com.sun.star.drawing.XDrawPages and com.sun.star.container.XIndexAccess interfaces) :

//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 previous code and this one : the former uses an Any type variable (DrawPage) although the latter code obtains directly a com.sun.star.drawing.XDrawPage interface. One more step is needed to obtain a com.sun.star.drawing.XDrawPage when working with Any : a UNO query. Add the above code to the former and you obtain like the latter code a com.sun.star.drawing.XDrawPage interface.

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

Rename

How to rename your slide ? You have to change the Name property of the slide (see com.sun.star.container.XNamed interface):

//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 com.sun.star.container.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.

Copy

And now you want to copy a page : you have to query the com.sun.star.drawing.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 .

//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

Remove

If you want to remove a page known by its index (see com.sun.star.drawing.XDrawPagesSupplier and com.sun.star.container.XIndexAccess interfaces)

//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 com.sun.star.drawing.XDrawPage interface corresponding to a hidden page and you want to put it on the top, have a look on com.sun.star.frame.XModel and com.sun.star.drawing.XDrawView interfaces :

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

See also com.sun.star.frame.XModel and com.sun.star.drawing.XDrawView.

Property of a Slide

Properties belong to the slide are presented :

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 with the com.sun.star.beans.XPropertySet interface :

//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 :

//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 :

//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.

Going further with Inspector

The new object inspector is able to generate Java or C++ or OOoBasic code. In order to try inspector ability to generate C++ code, we want to use it for the following problem : obtaining the default selected slide from a draw document. See also similar problem with writer document and particularly the definition of an IDL-tree.

Using inspector gives us the following IDL-tree :

MyDocument ->methods
  ->com.sun.star.frame.XController getCurrentController()
    ->xController->methods
      -> xDrawPage getCurrentPage         
        ->String getName           return Slide 2

The corresponding C++ code atomatically generated is presented below. It use com.sun.star.frame.XModel, com.sun.star.frame.XController, com.sun.star.drawing.XDrawView, com.sun.star.drawing.XDrawPage and com.sun.star.container.XNamed interfaces, but a closer look shows you have to add include directives :

#include "com/sun/star/frame/XModel.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "rtl/ustring.hxx"
#include "sal/config.h"
#include "sal/types.h"
 
namespace css = com::sun::star;
using namespace rtl;
 
//...
void codesnippet(const css::uno::Reference<css::uno::XInterface>& _oUnoEntryObject ){{
	css::uno::Reference<css::frame::XModel> xModel( _oUnoEntryObject, css::uno::UNO_QUERY_THROW);
	css::uno::Reference<css::frame::XController> xController = xModel->getCurrentController();
	css::uno::Reference<css::drawing::XDrawView> xDrawView( xController, css::uno::UNO_QUERY_THROW);
	css::uno::Reference<css::drawing::XDrawPage> xDrawPage = xDrawView->getCurrentPage();
	css::uno::Reference<css::container::XNamed> xNamed( xDrawPage, css::uno::UNO_QUERY_THROW);
	OUString sName = xNamed->getName();
}
//...
Documentation caution.png I have not checked this code at the moment. I have probably to add any include directives and because we don't encounter "any" type during the IDL-tree traversing, we probably haven't to modify C++ source of codesnippet sub.


Drawing with OOoDraw

Inserting a Shape

With OOoDraw text is considered as a shape like rectangle, ellipses... Let's then start with a com.sun.star.drawing.TextShape service and com.sun.star.drawing.XShape, com.sun.star.drawing.XShapes and com.sun.star.text.XText interfaces:

//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 :

// Listing 15 Change this Line
// C++
	Reference< XInterface > textshape = DocFactory->createInstance(
	               OUString::createFromAscii("com.sun.star.drawing.TextShape") );

with corresponding service com.sun.star.drawing.RectangleShape:

//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 to query a com.sun.star.text.XText interface :

//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 with com.sun.star.beans.XPropertySet interface :

//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.

See also com.sun.star.beans.XPropertySet and com.sun.star.drawing.XShape.

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 URL and use com.sun.star.drawing.XShape, com.sun.star.drawing.XShapes and com.sun.star.beans.XPropertySet interfaces :

//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

2. Save the document.

Or you copy the bitmap of the linked picture after it was added to the document and create a new shape with it. This new shape contains the actual image and not only the link.

//Listing 20.2 Inserting an Image and embedding it
 
// C++
// Don't forget #include <com/sun/star/awt/XBitmap.hpp>
 
	//Only after adding the rGrafShape to the Shapes collection, 
	//the GraphicObjectFillBitmap is set.
 
	//Get a copy of the image bitmap
	Any bmp = rShapeProps->getPropertyValue(
		OUString::createFromAscii("GraphicObjectFillBitmap"));
	Reference< XBitmap > rBitmap(bmp, UNO_QUERY);
 
	Reference< XInterface > embedShape = DocFactory->createInstance( 
	               OUString::createFromAscii("com.sun.star.drawing.GraphicObjectShape"));
	Reference< XShape > rEmbedShape(embedShape , UNO_QUERY);
 
	//Set size and pos again (this time for the embedded shape)
	rEmbedShape->setPosition(Position);
	rEmbedShape->setSize(TheSize);
 
	Reference< XPropertySet > rEmbedPropSet(rEmbedShape, UNO_QUERY);
 
	//Set the bitmap for the new embedded shape
	rEmbedPropSet->setPropertyValue(
		OUString::createFromAscii("GraphicObjectFillBitmap"), makeAny(rBitmap));
	rEmbedPropSet->setPropertyValue(
		OUString::createFromAscii("Name"), makeAny(sImageUrl));
 
	//Finally add the embedded shape to the shapes collection
	rShapes->add(rEmbedShape);
 
	//Dont forget to remove the linked shape
	rShapes->remove(rGrafShape);

See also com.sun.star.drawing.XShape, com.sun.star.drawing.XShapes com.sun.star.beans.XPropertySet and com.sun.star.drawing.GraphicObjectShape.

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.

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

See also com.sun.star.awt.XBitmap.

Inserting many Pictures

Every time you insert a picture, you have to query many times the com.sun.star.drawing.GraphicObjectShape service, 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 ( 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