FR/Documentation/OpenOffice Draw

From Apache OpenOffice Wiki
Jump to: navigation, search

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 le programme principal suivant:

//Listing 1
// C++ 
// adapted for OOoDraw
int main( ) {
//retrieve an instance of the remote service manager
    Reference< XMultiServiceFactory > rOfficeServiceManager;
    rOfficeServiceManager = ooConnect();
    if( rOfficeServiceManager.is() ){
        printf( "Connected sucessfully to the office\n" );
    }
 
//get the desktop service using createInstance returns an XInterface type
    Reference< XInterface  > Desktop = rOfficeServiceManager->createInstance(
    OUString::createFromAscii( "com.sun.star.frame.Desktop" ));
 
//query for the XComponentLoader interface
    Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY);
    if( rComponentLoader.is() ){
        	printf( "XComponentloader successfully instanciated\n" );
    	}
 
//get an instance of the OOoDraw document
    Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
	OUString::createFromAscii("private:factory/sdraw"),
        OUString::createFromAscii("_blank"),
        0,
        Sequence < ::com::sun::star::beans::PropertyValue >());
// ajouter du code ici
    return 0;
}

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 :

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

//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 une nouvelle page avec un index connu :

//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 le code du chapitre 6.1.1 et celui qui vient d'être présenté  : l'un utilise un objet Drawpage de type any tandis que le second obtient directement une interface XDrawpage. Une étape supplémentaire est requise pour obtenir l'interface 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);

Comment renommer votre page ? Vous devez changer la propriété du nom de la page.

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.

Et maintenant si vous désirez copier une page il vous faut utiliser l'interface 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

Si vous voulez supprimer une page connue par son index :

//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 XDrawPage correspondant à une page cachée et que vous voulez faire apparaître cette page au devant de l'écran :

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

//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 similar problem with writer document 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 :

#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 un TextShape :

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

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

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

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

Insérer un bitmap

Voici un exemple d'insertion d'un 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 :

//Listing 82
// 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 le dessin 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.

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.

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

Insérer plusieurs images

Chaque fois que vous insérez une image, vous devez demander beaucoup de fois le 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-en 6.2.3 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