Difference between revisions of "Programming OOoDraw and OOoImpress"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (An existing Slide)
(34 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 +
{{NeedsRework|EN}}
 
==Introduction==
 
==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)
 
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)
 
[http://www.oooforum.org/forum/viewtopic.phtml?t=11128 Working with a Presentation Document in C++]
 
[http://www.oooforum.org/forum/viewtopic.phtml?t=11128 Working with a Presentation Document in C++]
In this chapter, we use again the starting code described [[UNO_automation_with_a_binary_%28executable%29 | 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 :
+
In this chapter, we use again the starting code described [[UNO_automation_with_a_binary_%28executable%29 | here ]]. It consists of a subprogram “ooConnect()”  
<source lang="cpp">
+
{{:OOConnect}}
//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
+
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.  
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
+
{{Warn|To fit OOoDraw requirements you have to replace the string "private:factory/scalc" with "private:factory/sdraw".}}
    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;
+
}
+
</source>
+
  
You can find more explanations [[IDL_Files_and_Cpp#IDL__and_C.2B.2B|here]] (if you are not a beginner).
+
{{:MainOOConnect}}
  
 
=Finding the drawing Slide=
 
=Finding the drawing Slide=
Line 70: Line 43:
 
rPageIndexAccess->getCount();
 
rPageIndexAccess->getCount();
 
</source>
 
</source>
If you only know the page name :
+
If you only know the page name (see <idl>com.sun.star.container.XNameAccess</idl> interface):
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 4 Slide Name Access
 
//Listing 4 Slide Name Access
Line 85: Line 58:
 
}
 
}
 
</source>
 
</source>
 
See also <idl>com.sun.star.drawing.XDrawPagesSupplier</idl>, <idl>com.sun.star.container.XIndexAccess</idl>  and <idl>com.sun.star.container.XNameAccess</idl>.
 
  
 
==Create, rename, copy and remove a Slide ==
 
==Create, rename, copy and remove a Slide ==
Create a new slide with a known Index :
+
=== Create===
 +
Create a new slide with a known Index (see <idl>com.sun.star.drawing.XDrawPagesSupplier</idl>, <idl>com.sun.star.drawing.XDrawPage</idl>, <idl>com.sun.star.drawing.XDrawPages</idl> and <idl>com.sun.star.container.XIndexAccess</idl> interfaces) :
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 5 Creating a new Slide
 
//Listing 5 Creating a new Slide
Line 108: Line 80:
 
Reference< XDrawPage > rDrawPage = rDrawPages->insertNewByIndex(2);
 
Reference< XDrawPage > rDrawPage = rDrawPages->insertNewByIndex(2);
 
</source>
 
</source>
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 [[Programming_OOoDraw_and_OOoImpress#An_existing_Slide|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.
+
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 [[Programming_OOoDraw_and_OOoImpress#An_existing_Slide|previous code]] and this one : the former uses an Any type variable (DrawPage) although the latter code obtains directly a <idl>com.sun.star.drawing.XDrawPage</idl> interface. One more step is needed to obtain a <idl>com.sun.star.drawing.XDrawPage</idl> when working with Any : a UNO query. Add the above code to the former and you obtain like the latter code a <idl>com.sun.star.drawing.XDrawPage</idl> interface.
<source lang="cpp">]
+
<source lang="cpp">
 
//Listing 6 Accessing the XDrawPage Service
 
//Listing 6 Accessing the XDrawPage Service
 
// C++
 
// C++
Line 117: Line 89:
 
Reference< XDrawPage > rDrawPage(DrawPage, UNO_QUERY);
 
Reference< XDrawPage > rDrawPage(DrawPage, UNO_QUERY);
 
</source>
 
</source>
How to rename your slide ? You have to change the Name property of the slide :
+
 
 +
===Rename===
 +
How to rename your slide ? You have to change the Name property of the slide (see <idl>com.sun.star.container.XNamed</idl> interface):
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 7 Renaming a Slide
 
//Listing 7 Renaming a Slide
Line 128: Line 102:
 
rNamed->setName(OUString::createFromAscii("My second page"));
 
rNamed->setName(OUString::createFromAscii("My second page"));
 
</source>
 
</source>
The XNamed interface is your friend as seen in this code. The corresponding IDL code is given now :
+
The <idl>com.sun.star.container.XNamed</idl> interface is your friend as seen in this code. The corresponding IDL code is given now :
 
<source lang="idl">
 
<source lang="idl">
 
// IDL
 
// IDL
Line 142: Line 116:
 
As seen only two methods are available setName already used in the example and getName.
 
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.
 
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.
+
===Copy===
 +
And now you want to copy a page : you have to query the <idl>com.sun.star.drawing.XDrawPageDuplicator</idl> 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 .
 
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 .
 
<source lang="cpp">
 
<source lang="cpp">
Line 156: Line 131:
 
// This last line doesn't work
 
// This last line doesn't work
 
</source>
 
</source>
If you want to remove a page known by its index
+
===Remove===
 +
If you want to remove a page known by its index (see <idl>com.sun.star.drawing.XDrawPagesSupplier</idl> and <idl>com.sun.star.container.XIndexAccess</idl> interfaces)
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 9 Index access
 
//Listing 9 Index access
Line 178: Line 154:
 
</source>
 
</source>
 
Removing a page known by its name is let as an exercise.
 
Removing a page known by its name is let as an exercise.
 
See also <idl>com.sun.star.drawing.XDrawPagesSupplier</idl>, <idl>com.sun.star.container.XIndexAccess</idl>, <idl>com.sun.star.drawing.XDrawPage</idl>, <idl>com.sun.star.container.XNamed</idl> and <idl>com.sun.star.drawing.XDrawPageDuplicator</idl>.
 
  
 
== Setting the Focus on a Slide==
 
== 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 :
+
If you obtain a <idl>com.sun.star.drawing.XDrawPage</idl> interface corresponding to a hidden page and you want to put it on the top, have a look on <idl>com.sun.star.frame.XModel</idl> and <idl>com.sun.star.drawing.XDrawView</idl> interfaces :
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 10 Setting a Slide as currently focused
 
//Listing 10 Setting a Slide as currently focused
Line 234: Line 208:
 
|}
 
|}
  
If you want for instance retrieve the page width (a property), use this code :
+
If you want for instance retrieve the page width (a property), use this code with the <idl>com.sun.star.beans.XPropertySet</idl> interface :
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 11 Slide Properties
 
//Listing 11 Slide Properties
Line 279: Line 253:
 
</source>
 
</source>
 
It's time now to draw shapes on pages.
 
It's time now to draw shapes on pages.
 
See also <idl>com.sun.star.beans.XPropertySet</idl>.
 
  
 
== Going further with Inspector ==
 
== Going further with Inspector ==
Line 296: Line 268:
 
</pre>
 
</pre>
  
The corresponding C++ code atomatically generated is :
+
The corresponding C++ code atomatically generated is presented below. It use <idl>com.sun.star.frame.XModel</idl>, <idl>com.sun.star.frame.XController</idl>, <idl>com.sun.star.drawing.XDrawView</idl>, <idl>com.sun.star.drawing.XDrawPage</idl> and <idl>com.sun.star.container.XNamed</idl> interfaces, but a closer look shows you have to add include directives :
 
<source lang="cpp">
 
<source lang="cpp">
 
#include "com/sun/star/frame/XModel.hpp"
 
#include "com/sun/star/frame/XModel.hpp"
Line 319: Line 291:
 
//...
 
//...
 
</source>
 
</source>
{{Documentation/Caution|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.}}
+
{{Warn|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=
 
=Drawing with OOoDraw=
 
==Inserting a Shape==
 
==Inserting a Shape==
With OOoDraw text is considered as a shape like rectangle, ellipses... Let's then start with a TextShape :
+
With OOoDraw text is considered as a shape like rectangle, ellipses... Let's then start with a <idl>com.sun.star.drawing.TextShape</idl> service and <idl>com.sun.star.drawing.XShape</idl>, <idl>com.sun.star.drawing.XShapes</idl> and <idl>com.sun.star.text.XText</idl> interfaces:
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 14 Inserting a text Shape
 
//Listing 14 Inserting a text Shape
Line 368: Line 340:
 
              OUString::createFromAscii("com.sun.star.drawing.TextShape") );
 
              OUString::createFromAscii("com.sun.star.drawing.TextShape") );
 
</source>
 
</source>
with :
+
with corresponding service <idl>com.sun.star.drawing.RectangleShape</idl>:
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 16 Inserting a Rectangle Shape
 
//Listing 16 Inserting a Rectangle Shape
Line 376: Line 348:
 
</source>
 
</source>
 
We shall examine how to draw a shape again later. Note that you can write text too with this new shape as explained now.
 
We shall examine how to draw a shape again later. Note that you can write text too with this new shape as explained now.
 
See also <idl>com.sun.star.drawing.XShape</idl>, <idl>com.sun.star.text.XText</idl>, <idl>com.sun.star.drawing.XShapes</idl>,  <idl>com.sun.star.drawing.TextShape</idl> and <idl>com.sun.star.drawing.RectangleShape</idl>.
 
  
 
==Writing Text in a Shape==
 
==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 :
+
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 <idl>com.sun.star.text.XText</idl> interface :
<<source lang="cpp">]
+
<source lang="cpp">
 
//Listing 17 setString method to insert a Text
 
//Listing 17 setString method to insert a Text
 
// C++
 
// C++
Line 392: Line 362:
 
==Giving a Name to the Shape==
 
==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 :
+
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 <idl>com.sun.star.beans.XPropertySet</idl> interface :
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 18 Naming a Shape
 
//Listing 18 Naming a Shape
Line 423: Line 393:
  
 
==Inserting a bitmap==
 
==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 :
+
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 <idl>com.sun.star.drawing.XShape</idl>, <idl>com.sun.star.drawing.XShapes</idl> and <idl>com.sun.star.beans.XPropertySet</idl> interfaces :
 
<source lang="cpp">
 
<source lang="cpp">
 
//Listing 20 Inserting an Image in a Slide
 
//Listing 20 Inserting an Image in a Slide
Line 538: Line 508:
  
 
==Inserting many Pictures==
 
==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.
+
Every time you insert a picture, you have to query many times the  <idl>com.sun.star.drawing.GraphicObjectShape</idl> service, even if you insert many times the same picture.
  
 
==Finding a Picture with its Name==
 
==Finding a Picture with its Name==
Line 549: Line 519:
  
 
= See also=
 
= See also=
 +
* [[FR/Documentation/OpenOffice_Draw|French version of this chapter]].
 
* Drawing Documents and Presentation Documents [[Documentation/DevGuide/Drawings/Drawing_Documents_and_Presentation_Documents|in Developer's Guide]]
 
* Drawing Documents and Presentation Documents [[Documentation/DevGuide/Drawings/Drawing_Documents_and_Presentation_Documents|in Developer's Guide]]
 
* [[Documentation/BASIC_Guide/Drawings_Presentations|Drawings ans Presentations]]
 
* [[Documentation/BASIC_Guide/Drawings_Presentations|Drawings ans Presentations]]
Line 555: Line 526:
  
 
[[Category:OOoDraw]]
 
[[Category:OOoDraw]]
[[Category:Development]]
 
 
[[Category:Uno]]
 
[[Category:Uno]]
 
[[Category:Cpp]]
 
[[Category:Cpp]]

Revision as of 10:16, 11 July 2018


Edit-find-replace.png This article should be checked for accuracy and conformity to 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