12 April 2014: The OpenOffice Wiki is not, and never was, affected by the heartbleed bug. Users' passwords are safe and wiki users do not need take any actions.

FR/Documentation/OpenOffice Draw

From Apache OpenOffice Wiki
Jump to: navigation, search

Introduction

OooDraw est mon application préférée d'OpenOffice.org . Je pense donc que je vais passer beaucoup de temps sur ce chapitre et le suivant.

Dans ce chapitre, nous utilisons encore le code décrit dans la section précédente. Cela consiste en un sous programme “ooConnect()” et un programme principal. Nous donnons pour la deuxième fois la fonction 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>
// on ajoute la ligne ci-apres
#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;
// ajouté aussi :
using namespace com::sun::star::frame;
 
using namespace rtl;
using namespace cppu;
 
// appel de la fonction de démarrage
Reference< XMultiServiceFactory > ooConnect(){
   // create the initial component context
   Reference< XComponentContext > rComponentContext = 
				defaultBootstrap_InitialComponentContext();
 
   // obtention du servicemanager à partir du 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 : vous devez éventuellement changer le port de "port=8100" avec "port=2083" pour les SDK récents (après 2.X).

Il serait bon de regarder aussi :

  1. les interfaces com.sun.star.uno.XComponentContext, com.sun.star.lang.XMultiComponentFactory, com.sun.star.uno.XInterface, com.sun.star.bridge.XUnoUrlResolver et com.sun.star.lang.XMultiServiceFactory,
  2. et aussi le service com.sun.star.bridge.UnoUrlResolver.

Nous donnons maintenant le programme principal à modifier, voir les commentaires correspondants :

Documentation caution.png N'oublier pas de changer aussi la chaîne de caractères "private:factory/scalc" en "private:factory/sdraw".
// code C++
//Listing 0b Notre programme principal
int main( ) {
//retrouve une instance service manager distant avec notre ooConnect()
    Reference< XMultiServiceFactory > rOfficeServiceManager;
    rOfficeServiceManager = ooConnect();
    if( rOfficeServiceManager.is() ){
        printf( "Connecté avec succès à OpenOffice\n" );
    }
 
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//demande de l'interface 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 >());
//*********************************
// c'est ici que l'on rajoute le code présenté dans ce chapitre;
//*********************************
    return 0;
}

Ce code est appelé un programme d'amorce ou de démarrage et utilise :

  1. les interfaces com.sun.star.lang.XMultiServiceFactory, com.sun.star.uno.XInterface, com.sun.star.frame.XComponentLoader et com.sun.star.lang.XComponent interfaces
  2. le service com.sun.star.frame.Desktop,
  3. la structure UNO com.sun.star.beans.PropertyValue.

Rappelez-vous que chaque fois que vous demandez une interface vous devez ajouter des lignes de code si elles n'existent pas dans le code source ainsi que dans le makefile. Je vais en général ajouter des commentaires pour éviter les omissions.

Documentation note.png Note importante : Le point le plus important dans la chaîne de compilation des exemples ci-après est que l'utilitaire cppumaker construira chacun des fichiers d'inclusion hpp et hdl que votre application utilisera. Le SDK ne fournit pas les fichiers hpp, mais vous devez les construire à partir des fichiers IDL qui eux sont fournis avec le SDK.
Documentation note.png Il est possible de construire tous les fichiers d'inclusion hpp lors de l'installation du SDK comme j'ai eu l'occasion de le mentionner pour l'installation sous Windows. C'est naturellement possible aussi avec les autres systèmes d'exploitation. En procédant ainsi il ne vous faudra plus modifier votre MakeFile (sauf peut-être le chemin pour atteindre ces fichiers).

Trouver la page de dessin

Il vous faut garder à l'esprit que si l'application tableur s'ouvre avec par défaut trois feuilles, OOoDraw s'ouvre seulement avec une seule page dont l'index est 0. Chaque page de dessin dans Draw comporte un onglet. Le nom des onglets est par défaut, dans la version localisée française, Page 1, Page 2, etc. Le numéro de page est le rang de l'onglet, de gauche à droite. Si vous déplacez avec la souris une page non renommée, le nom sur l'onglet va changer pour refléter sa position, ainsi que pour les pages suivantes non renommées.

Une page existante

Si vous connaissez juste l'index de la page, voici le code qu'il vous faudra mettre en oeuvre. Ce code vous parraîtra clair après avoir regarder les interfaces com.sun.star.drawing.XDrawPagesSupplier et com.sun.star.container.XIndexAccess :

//Listing 2
// C++
// Ne pas oublier d'ajouter : using namespace com::sun::star::drawing;
// Ne pas oublier la directive : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.drawing.XDrawPagesSupplier \" dans le makefile
// Ne pas oublier d'ajouter : using namespace com::sun::star::container;
// Ne pas oublier la directive : #include <com/sun/star/container/XIndexAccess.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.container.XIndexAccess \" dans lee 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);

Si vous voulez savoir combien de pages il y a dans votre document, vous pouvez y accéder depuis l'interface XIndexAccess utilisée ici à l'aide de la variable rPageIndexAccess :

//Listing 3
// C++
	rPageIndexAccess->getCount();
Documentation caution.png Attention : pour l’API les pages sont numérotées à partir de zéro, dans l’ordre affiché par l’interface Draw (toutes les pages, renommées ou non). Ainsi si l'utilisateur change l’ordre des pages, le programme écrira obstinément sur la même page de rang n.


Si vous connaissiez seulement le nom de la page (voir com.sun.star.container.XNameAccess) :

//Listing 4
//C++
// Ne pas oublier la directive : #include <com/sun/star/container/XNameAccess.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.container.XNameAccess \" dans le makefile
 
//query the XNameAccess Interface
	Reference< XNameAccess > rNameAccess(rDrawPages, UNO_QUERY);
 
	if (rNameAccess->hasByName(OUString::createFromAscii("Page 1"))) {
		Any DrawPage = rNameAccess->
					getByName(OUString::createFromAscii("Page 1"));
	}

Créer, renommer, copier et supprimer une page

Créer

Créer une nouvelle page avec un index connu (voir particulièrement les interfaces com.sun.star.drawing.XDrawPagesSupplier, com.sun.star.drawing.XDrawPage, com.sun.star.drawing.XDrawPages et com.sun.star.container.XIndexAccess) :

//Listing 5
// C++
// Ne pas oublier d'ajouter : using namespace com::sun::star::drawing;
// Ne pas oublier la directive : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.drawing.XDrawPagesSupplier \" dans le makefile
// Ne pas oublier d'ajouter : using namespace com::sun::star::container;
// Ne pas oublier la directive : #include <com/sun/star/container/XIndexAccess.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.container.XIndexAccess \" dans le 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);

Dans cet exemple, la nouvelle page aura un index de 2 et donc comme nom par défaut “Page 3”. Vous pouvez voir la différence avec l'ancien code de la section précédente et celui qui vient d'être tout juste présenté  : l'un utilise un objet Drawpage de type any tandis que le second obtient directement une interface com.sun.star.drawing.XDrawPage. Une étape supplémentaire est requise pour obtenir l'interface com.sun.star.drawing.XDrawPage à partir d'un type any ce qui est réalisé avec un UNO_QUERY.

//Listing 6
// C++
// Ne pas oublier la directive : #include <com/sun/star/drawing/XDrawPage.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.drawing.XDrawPage \" dans le makefile
// Query the XDrawPage Interface
	Reference< XDrawPage > rDrawPage(DrawPage, UNO_QUERY);

Renommer

Comment renommer votre page ? Vous devez changer la propriété du nom de la page (voir l'interface com.sun.star.container.XNamed).

Documentation caution.png Attention : l'API permet de récupérer le nom de l'onglet avec la propriété Name de la page. Pour les pages non renommées, le nom récupéré est : page1, page2, etc. L’espace a disparu, et le nom commence par une minuscule. Draw sait si l'onglet est renommé, mais l'API ne fournit pas cette information.
//Listing 7
// C++
// Ne pas oublier la directive : #include <com/sun/star/container/XNamed.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.container.XNamed \" dans le makefile
 
// query for the XNamed Interface
	Reference< XNamed > rNamed(rDrawPage, UNO_QUERY);
	rNamed->setName(OUString::createFromAscii("My second page"));

Nous avons déjà porté notre attention sur la différence entre les variables PageDraw et rPageDraw, notez cependant que l'on peut utiliser les deux dans le code précédent.

Copier

Et maintenant si vous désirez copier une page il vous faut utiliser l'interface com.sun.star.drawing.XDrawPageDuplicator. Nous avons à passer une référence à la méthode duplicate() de cette interface. Cela permet d'ajouter une nouvelle page à la fin de la liste des pages en utilisant la dénomination par défaut des pages, Page n .

//Listing 8
// C++ A tester (Ne fonctionne pas !!!)
// Ne pas oublier la directive : #include <com/sun/star/drawing/XDrawPageDuplicator.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.drawing.XDrawPageDuplicator \" dans le makefile
 
// query for the XDrawPageDuplicator Interface
	Reference< XDrawPageDuplicator > rDrawPageDuplicator(rDrawPage(s)???, UNO_QUERY);
 
	Reference< XDrawPage> rDrawPage2 = rDrawPageDuplicator->duplicate(rDrawPage);
// Cette dernière ligne ne marche pas

Supprimer

Si vous voulez supprimer une page connue par son index (voir les interfaces com.sun.star.drawing.XDrawPagesSupplier et com.sun.star.container.XIndexAccess):

//Listing 9
// C++
// Ne pas oublier d'ajouter : using namespace com::sun::star::drawing;
// Ne pas oublier la directive : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.drawing.XDrawPagesSupplier \" dans le makefile
// Ne pas oublier d'ajouter : using namespace com::sun::star::container;
// Ne pas oublier la directive : #include <com/sun/star/container/XIndexAccess.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.container.XIndexAccess \" dans le 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);

Supprimer une page dont on connaît le nom est laissé comme exercice.

Garder une page à l'écran

Si vous obtenez une interface com.sun.star.drawing.XDrawPage correspondant à une page cachée et que vous voulez faire apparaître cette page au devant de l'écran reagardez les interfaces com.sun.star.frame.XModel et com.sun.star.drawing.XDrawView:

//Listing 10
// C++
// En premier obtenir une interface XDrawPage pour cette page, et après :
 
// Ne pas oublier d'ajouter : using namespace com::sun::star::frame;
// Ne pas oublier la directive : #include <com/sun/star/frame/XModel.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.frame.XModel \" dans le makefile
 
// Ne pas oublier la directive : #include <com/sun/star/drawing/XDrawView.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.drawing.XDrawView \" dans le 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);

Propriété d'une page

Les propriétés appartenant à la page sont résumées dans le tableau suivant :

slide's properties
Propriété Signification
Name Nom de la page
BorderLeft Marge gauche en 1/100 mm
BorderRight Marge droite en 1/100 mm
BorderTop Marge du haut en 1/100 mm
MBorderBottom Marge du bas en 1/100 mm
Height Hauteur de page en 1/100 mm
Width Largeur de page en 1/100 mm
Number Number of the page begins from 1
Orientation Portrait : com.sun.star.view.PaperOrientation.PORTRAIT

ou paysage : com.sun.star.view.PaperOrientation.LANDSCAPE

Si vous voulez par exemple récupérer la largeur de page, utilisez ce code qui utilise l'interface com.sun.star.beans.XPropertySet :

//Listing 11
// C++
// Ne pas oublier d'ajouter : using namespace com::sun::star::beans;
// Ne pas oublier la directive : #include <com/sun/star/beans/XPropertySet.hpp>
// Ne pas oublier d'ajouter : "com.sun.star.beans.XPropertySet \" dan le makefile
	// find out page width
	Reference< XPropertySet > rPageProps(rDrawPage, UNO_QUERY);
 
	Any ApageWidth = rPageProps->getPropertyValue(OUString::createFromAscii("Width"));
	sal_Int32 pageWidth;
	ApageWidth >>= pageWidth;

Si vous voulez positionner les marges de vos pages cela peut se faire à l'aide du code ci-dessous :

//Listing 12
// C++
// Obtenir rPageProps comme dans le code précédent
	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]);

Un autre moyen plus simple est d'utiliser la fonction makeAny :

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

Aller plus loin avec l'Inspector Java

The new object inspector est capable de générer du code C++, Java ou OOoBasic. Pour essayer une génération C++ nous voulons l'utiliser pour résoudre le problème suivant : obtenir la page sélectionnée d'un document Draw. Voir aussi un problème similaire avec les document witer et particulièrement la définition d'un arbre IDL.

L'utilisation de l'Inspector Java nous donne l'arbre IDL suivant :

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

Le code C++ automatiquement généré est présenté maintenant. Il utilise les interfaces com.sun.star.frame.XModel, com.sun.star.frame.XController, com.sun.star.drawing.XDrawView, com.sun.star.drawing.XDrawPage et com.sun.star.container.XNamed mais un examen attentif montre qu'il manque quelques directives d'inclusions pour un bon fonctionnement.

#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 Je n'ai pas testé ce code pour le moment. Il faut certainement lui ajouter quelques directives d'inclusion mais parceque nous ne rencontrons pas de type Any durant la traversée de l'arbre IDL, nous n'aurons pas à modifier le code.


Il est temps maintenant de dessiner des formes (shapes en anglais) sur des pages.

Dessiner avec Draw

Insérer une Forme

Avec OOoDraw, le texte est considéré comme une forme de la même manière que les rectangles, les ellipses... alors commençons avec le service com.sun.star.drawing.TextShape et les interfaces com.sun.star.drawing.XShape, com.sun.star.drawing.XShapes et com.sun.star.text.XText :

//Listing 14
// C++
// N'oubliez pas d'ajouter :using namespace com::sun::star::awt; for Point and Size
 
// Ne pas oublier la directive : #include <com/sun/star/drawing/XShape.hpp>
// N'oubliez pas d'ajouter "com.sun.star.drawing.XShape \" dans le makefile
 
// Ne pas oublier la directive : #include <com/sun/star/drawing/XShapes.hpp>
// N'oubliez pas d'ajouter "com.sun.star.drawing.XShapes \" dans le makefile
// N'oubliez pas d'ajouter : using namespace com::sun::star::text;
// Ne pas oublier la directive : #include <com/sun/star/text/XText.hpp>
// N'oubliez pas d'ajouter "com.sun.star.text.XText \" dans le 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"));

Quand est exécuté ce code, un “Hello people around the world” est écrit sur une page. Changer une forme est simple: si vous voulez dessiner un rectangle, la seule ligne à changer est:

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

à remplacer par le service correspondant com.sun.star.drawing.RectangleShape, soit en C++ :

//Listing 16 Obtenir le service Rectangle Shape
// C++
	Reference< XInterface > textshape = DocFactory->createInstance(
	               OUString::createFromAscii("com.sun.star.drawing.RectangleShape") );

Nous examinerons encore plus tard le dessin des formes. Remarquez que vous pouvez écrire aussi un texte avec cette nouvelle forme comme expliqué maintenant.

Ecrire un texte dans une forme

Ecrire un texte dans une forme est obtenu de la même façon que l'écriture d'un texte dans un TextShape. Pour une forme de rectangle (rRecShape) on a alors à demander une interface com.sun.star.text.XText, ce qui se fait en C++ par :

//Listing 17
// C++
// Query the XText Interface
	Reference< XText > rText(rRecShape, UNO_QUERY);
        rText->setString(OUString::createFromAscii("Bonjour"));

lequel trace un rectangle et écrit “Bonjour” dans ce rectangle.

Donner un nom à cette forme

Toute forme peut être nommée. Ce point est très intéressant si vous voulez transformer OOoDraw comme un outil graphique frontal. Voici un exemple du code qui donne un nom à une forme à l'aide de l'interface com.sun.star.beans.XPropertySet:

//Listing 18
// C++
// N'oubliez pas d'ajouter : using namespace com::sun::star::beans;
// Ne pas oublier la directive : #include <com/sun/star/beans/XPropertySet.hpp>
// N'oubliez pas d'ajouter : "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")));

L'interface XShapes autorise les ajouts, les déplacements comme on l'a vu. Le fichier IDL correspondant vous donne les possibilités de cette interface :

//Listing 19
// 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 );
};

Puisque cette interface hérite de l'interface XIndexAccess, elle dispose aussi des méthodes getcount() and getByIndex. Cela autorise la construction d'une boucle sur toutes les formes.

Les graphiques et OOoDraw

Avec OOoDraw un graphique est un dessin bitmap ou vectoriel. Nous nous intéressons dans cette section aux images bitmap.

Insérer un bitmap

Voici un exemple d'insertion d'une image bitmap. Nous commençons comme dans le chapitre précédent : avec une page de dessin. La seule différence est encore avec la forme qui est maintenant un GraphicObjectShape. Et nous devons donner un lien vers un répertoire tout ceci en utilisant les interfaces file com.sun.star.drawing.XShape, com.sun.star.drawing.XShapes et com.sun.star.beans.XPropertySet :

//Listing 20
// C++
// Ne pas oublier la directive : #include <osl/file.hxx>
 
// N'oubliez pas d'ajouter :using namespace com::sun::star::awt; for Point and size
 
// Ne pas oublier la directive : #include <com/sun/star/drawing/XShape.hpp>
// N'oubliez pas d'ajouter "com.sun.star.drawing.XShape \" dans le makefile
 
// Ne pas oublier la directive : #include <com/sun/star/drawing/XShapes.hpp>
// N'oubliez pas d'ajouter "com.sun.star.drawing.XShapes \" dans le makefile
 
// N'oubliez pas d'ajouter : using namespace com::sun::star::beans;
// Ne pas oublier la directive : #include <com/sun/star/beans/XPropertySet.hpp>
// N'oubliez pas d'ajouter "com.sun.star.beans.XPropertySet \" dans le 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);

Ce code n'insert pas l'image véritablement dans le document mais son lien. Effectivement l'insertion n'est pas possible avec l'API mais avec les menus :

1.Edition -> Liens selectionner tous les liens vers les images clicker sur le bouton deconnecter; confirmer

2.Sauver le document.

Vous pouvez aussi embarquer l'image dans le document plutôt que son lien. Cela peut se faire avec un code comme :

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

Voir aussi les interfaces com.sun.star.drawing.XShape, com.sun.star.drawing.XShapes, com.sun.star.beans.XPropertySet et le service com.sun.star.drawing.GraphicObjectShape.

Changer la taille d'un dessin

Pour garder les proportions tout en changeant la taille, vous devez en premier la calculer. Pour cela nous obtenons en premier la dimension de l'image en pixels mais c'est seulement possible après l'insertion effective par l'instruction “Shapes->add(rGrafShape);” Voici un exemple qui redimentionne l'image avec une largeur choisie et une hauteur à calculer et utilise l'interface com.sun.star.awt.XBitmap.

//Listing 21
//C++
// Ne pas oublier la directive : #include <com/sun/star/awt/XBitmap.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.XBitmap \" dans le 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);

Insérer plusieurs images

Chaque fois que vous insérez une image, vous devez demander beaucoup de fois le service com.sun.star.drawing.GraphicObjectShape, même si vous insérez beaucoup de fois la même image.

Trouver une Image par son nom

L'accès à l'image comme pour les autres formes peut être réalisé à l'aide d'un index, ce qui n'est pas très commode à utiliser. Mais nous pouvons leur donner un nom (voyez Donner un Nom à la Forme). Nous nous attaquerons plus tard à ce problème.

Si vous voulez aller plus loin avec les formes allez au prochain chapitre.

Retour à la page d'accueil

Page d'accueil du développement C++ à l'aide du SDK

Voir aussi

Personal tools