[ Previous document | Content Table | Next document ]

10  Drawing Documents and Presentation Documents

 

 

10.1  Overview

Draw and Impress are vector-oriented applications with the ability to create drawings and presentations. The drawing capabilities of Draw and Impress are identical. Both programs support a number of different shape types, such as rectangle, text, curve, or graphic shapes, that can be edited and arranged in various ways. Impress offers a presentation functionality where Draw does not. Impress is the ideal application to create and show presentations. It supports special presentation features, such as an enhanced page structure, presentation objects, and many slide transition and object effects. Draw is especially adapted  for printed or standalone graphics, whereas Impress is optimized to fit screen dimensions and offers effects for business presentations.

The following diagrams show the document structure of Draw and Impress Documents. 

In contrast to text documents and spreadsheet documents, the main content of drawing and presentation documents are their draw pages. Therefore the illustrations show the draw page container as integral part of the drawing and presentation document model. The drawing elements on the draw pages have to be created by the document service manager and are added to the draw pages afterwards. 

Note the master pages and the layer manager, which are specific to drawings and presentations. Like for texts and spreadsheets, a controller is used to present the drawing in the GUI and services for styles and layout are available to handle overall document features such as styles. 

Overview graphic of the Chart Document modelIllustration 10.1: Drawing Document Overview

In addition to drawing documents, a presentation document has special presentation aspects, which are shown on the lower left of Illustration 10.2 Presentation Document Overview. There is a presentation supplier to obtain a presentation object, which is used to start and stop presentations, it is possible to edit and run custom presentations and the page layout for presentation handouts is accessible through a handout master supplier.

Overview graphic of the Presentation Document modelIllustration 10.2: Presentation Document Overview

10.1.1  Example: Creating a Simple Organizational Chart

The following example creates a simple organizational chart with two levels. It consists of five rectangle shapes and four connectors that connect the boxes on the second level with the root box on the first level. 

The graphic shows a sample organigramIllustration 10.3: Sample Organigram

The method getRemoteServiceManager()that is used in the example connects to the office. The 2 First Steps discussed this method. First an empty drawing document is loaded and retrieves the draw page object of slide number 1 to find the page dimensions. Then the organigram data is prepared and the shape sizes are calculated. The shapes are added in a for loop that iterates over the organigram data, and connectors are added for all shapes on the second level of the organigram. (Drawing/Organigram.java).

public void drawOrganigram() throws java.lang.Exception {

    xRemoteServiceManager = this.getRemoteServiceManager(

        "uno:socket,host=localhost,port=2083;urp;StarOffice.ServiceManager");

    Object desktop = xRemoteServiceManager.createInstanceWithContext(

        "com.sun.star.frame.Desktop", xRemoteContext);

    XComponentLoader xComponentLoader = (XComponentLoader)UnoRuntime.queryInterface(

        XComponentLoader.class, desktop);

    PropertyValue[] loadProps = new PropertyValue[0];

    XComponent xDrawComponent = xComponentLoader.loadComponentFromURL(

        "private:factory/sdraw", "_blank", 0, loadProps);

           

    // get draw page by index

    com.sun.star.drawing.XDrawPagesSupplier xDrawPagesSupplier =

        (com.sun.star.drawing.XDrawPagesSupplier)

            UnoRuntime.queryInterface(

    com.sun.star.drawing.XDrawPagesSupplier.class, xDrawComponent );

    com.sun.star.drawing.XDrawPages xDrawPages = xDrawPagesSupplier.getDrawPages();

    Object drawPage = xDrawPages.getByIndex(0);

    com.sun.star.drawing.XDrawPage xDrawPage = (com.sun.star.drawing.XDrawPage)

        UnoRuntime.queryInterface(

            com.sun.star.drawing.XDrawPage.class, drawPage);

       

    // find out page dimensions

    com.sun.star.beans.XPropertySet xPageProps = (com.sun.star.beans.XPropertySet)

        UnoRuntime.queryInterface(

            com.sun.star.beans.XPropertySet.class, xDrawPage);

           int pageWidth = AnyConverter.toInt(xPageProps.getPropertyValue("Width"));

    int pageHeight = AnyConverter.toInt(xPageProps.getPropertyValue("Height"));

    int pageBorderTop = AnyConverter.toInt(xPageProps.getPropertyValue("BorderTop"));

    int pageBorderLeft = AnyConverter.toInt(xPageProps.getPropertyValue("BorderLeft"));

    int pageBorderRight = AnyConverter.toInt(xPageProps.getPropertyValue("BorderRight"));

    int drawWidth = pageWidth - pageBorderLeft - pageBorderRight;

    int horCenter = pageBorderLeft + drawWidth / 2;

    // data for organigram

    String[][] orgUnits = new String[2][4];

    orgUnits[0][0] = "Management";  // level 0

    orgUnits[1][0] = "Production";  // level 1

    orgUnits[1][1] = "Purchasing";  // level 1

    orgUnits[1][2] = "IT Services"; // level 1

    orgUnits[1][3] = "Sales";       // level 1

    int[] levelCount = {1, 4};

       

    // calculate shape sizes and positions

    int horSpace = 300;

    int verSpace = 3000;

    int shapeWidth = (drawWidth - (levelCount[1] - 1) * horSpace) / levelCount[1];

    int shapeHeight = pageHeight / 20;

    int shapeX = pageWidth / 2 - shapeWidth / 2;

    int levelY = 0;

    com.sun.star.drawing.XShape xStartShape = null;

    // get document factory

    com.sun.star.lang.XMultiServiceFactory xDocumentFactory = (com.sun.star.lang.XMultiServiceFactory)

        UnoRuntime.queryInterface(

            com.sun.star.lang.XMultiServiceFactory.class, xDrawComponent);

    // creating and adding RectangleShapes and Connectors        

    for (int level = 0; level <= 1; level++) {

        levelY = pageBorderTop + 2000 + level * (shapeHeight + verSpace);

        for (int i = levelCount[level] - 1; i > -1; i--) {

            shapeX = horCenter -

                     (levelCount[level] * shapeWidth + (levelCount[level] - 1) * horSpace) / 2 +

                     i * shapeWidth + i * horSpace;

            Object shape = xDocumentFactory.createInstance("com.sun.star.drawing.RectangleShape");

            com.sun.star.drawing.XShape xShape = (com.sun.star.drawing.XShape)

                UnoRuntime.queryInterface(

                    com.sun.star.drawing.XShape.class, shape);

            xShape.setPosition(new com.sun.star.awt.Point(shapeX, levelY));

            xShape.setSize(new com.sun.star.awt.Size(shapeWidth, shapeHeight));  

            xDrawPage.add(xShape);

           

            // set the text

            com.sun.star.text.XText xText = (com.sun.star.text.XText)

                UnoRuntime.queryInterface(

                    com.sun.star.text.XText.class, xShape);

            xText.setString(orgUnits[level][i]);                

            // memorize the root shape, for connectors

            if (level == 0 && i == 0)

                xStartShape = xShape;  

               

            // add connectors for level 1

            if (level == 1) {

                Object connector = xDocumentFactory.createInstance(

                    "com.sun.star.drawing.ConnectorShape");

                com.sun.star.drawing.XShape xConnector = (com.sun.star.drawing.XShape)

                    UnoRuntime.queryInterface(

                        com.sun.star.drawing.XShape.class, connector);                    

                xDrawPage.add(xConnector);

                com.sun.star.beans.XPropertySet xConnectorProps = (com.sun.star.beans.XPropertySet)

                    UnoRuntime.queryInterface(

                        com.sun.star.beans.XPropertySet.class, connector);

                xConnectorProps.setPropertyValue("StartShape", xStartShape);

                xConnectorProps.setPropertyValue("EndShape", xShape);

                // glue point positions: 0=top 1=left 2=bottom 3=right

                xConnectorProps.setPropertyValue("StartGluePointIndex", new Integer(2));

                xConnectorProps.setPropertyValue("EndGluePointIndex", new Integer(0));  

            }

           

        }

    }

}

10.2  Handling Drawing Document Files

10.2.1  Creating and Loading Drawing Documents

If a document in OpenOffice.org is required, begin by getting the com.sun.star.frame.Desktop service from the service manager. The desktop handles all document components in OpenOffice.org among other things. It is discussed thoroughly in the chapter 7 Office Development. Office documents are often called components because they support the com.sun.star.lang.XComponent interface. An XComponent is a UNO object that can be disposed explicitly and broadcast an event to other UNO objects when this happens.

The Desktop loads new and existing components from a URL. The desktop has a com.sun.star.frame.XComponentLoader interface that has one single method to load and instantiate components from a URL into a frame:

com::sun::star::lang::XComponent loadComponentFromURL( [in] string aURL,

                                     [in] string aTargetFrameName,

                                     [in] long nSearchFlags,

                                     [in] sequence< com::sun::star::beans::PropertyValue > aArgs )

The parameters in our context are the URL that describes the resource to be loaded, and the load arguments. For the target frame pass in "_blank" and set the search flags to 0. In most cases, you will not want to reuse an existing frame.

The URL can be a file: URL, an http: URL, an ftp: URL or a private: URL. The correct URL format is located in the load URL box at the function bar of OpenOffice.org. For new Draw documents, a special URL scheme is used. The scheme is "private:", followed by "factory" as the hostname and the resource is "sdraw" for OpenOffice.org Draw documents. Thus, for a new Draw document, use "private:factory/sdraw".

The load arguments are described in com.sun.star.document.MediaDescriptor. The properties AsTemplate and Hidden are boolean values and used for programming. If AsTemplate is true, the loader creates a new untitled document from the given URL. If it is false, template files are loaded for editing. If Hidden is true, the document is loaded in the background. This is useful to generate a document in the background without letting the user observe what is happening. For instance, use it to generate a document and print it out without previewing. Refer to  7 Office Development or other available options.

The introductory example shows how to load a drawing document. This snippet loads a new drawing document in hidden mode: 

    // the method getRemoteServiceManager is described in the chapter First Steps

    mxRemoteServiceManager = this.getRemoteServiceManager();

 

    // retrieve the Desktop object, we need its XComponentLoader

    Object desktop = mxRemoteServiceManager.createInstanceWithContext(

        "com.sun.star.frame.Desktop", mxRemoteContext);

 

    // query the XComponentLoader interface from the Desktop service

    XComponentLoader xComponentLoader = (XComponentLoader)UnoRuntime.queryInterface(

        XComponentLoader.class, desktop);

 

    // define load properties according to com.sun.star.document.MediaDescriptor

    // the boolean property Hidden tells the office to open a file in hidden mode

    PropertyValue[] loadProps = new PropertyValue[1];

    loadProps[0] = new PropertyValue();

    loadProps[0].Name = "Hidden";

    loadProps[0].Value = new Boolean(true);  

 

    /* or simply create an empty array of com.sun.star.beans.PropertyValue structs:

       PropertyValue[] loadProps = new PropertyValue[0]

     */

 

    // load

    com.sun.star.lang.XComponent xComponentLoader.loadComponentFromURL(

        "private:factory/sdraw", "_blank", 0, loadProps);          

10.2.2  Saving Drawing Documents

The normal File – Save command for drawing documents can only store the current document in the native OpenOffice.org Draw format and its predecessors. There are other formats that can be stored through the File – Export option. This is mirrored in the API. Exporting in the current version of OpenOffice.org Draw and Impress is a different procedure than storing.

Storing

Documents are storable through their interface com.sun.star.frame.XStorable. The 7 Office Development discusses this in detail. An XStorable implements these operations:

boolean hasLocation()

string getLocation()

boolean isReadonly()

void store()

void storeAsURL( [in] string aURL, [in] sequence < com::sun::star::beans::PropertyValue > aArgs)

void storeToURL( [in] string aURL, [in] sequence < com::sun::star::beans::PropertyValue > aArgs)

The method names should be evident. The method storeAsUrl() is the exact representation of File – Save As, that is, it changes the current document location. In contrast, storeToUrl() stores a copy to a new location, but leaves the current document URL untouched. There are also store arguments. A filter name can be passed that tells OpenOffice.org to use older StarOffice Draw file formats. Exporting is a different matter as shown below. The property needed is FilterName which is a string argument that takes filter names defined in the configuration file:

<OfficePath>\share\config\registry\instance\org\openoffice\Office\TypeDetection.xml

In TypeDetection.xml, find <Filter/> elements, their cfg:name attribute contains the required strings for FilterName. The correct filter name for StarDraw 5.x files is "StarDraw 5.0". The following is the element in TypeDetection.xml  that describes the StarDraw 5.0 document filter:

<Filter cfg:name="StarDraw 5.0"> 

    <Installed cfg:type="boolean">true</Installed>

    <UIName cfg:type="string" cfg:localized="true">

        <cfg:value xml:lang="en-US">StarDraw 5.0</cfg:value>

    </UIName>

    <Data cfg:type="string">

        10,draw_StarDraw_50,com.sun.star.drawing.DrawingDocument,,268435559,,5050,,

    </Data>

</Filter> 

The following method stores a document using this filter: 

/** Store a document, using the StarDraw 5.0 Filter */ 

protected void storeDocComponent(XComponent xDoc, String storeUrl) throws java.lang.Exception { 

    XStorable xStorable = (XStorable)UnoRuntime.queryInterface(XStorable.class, xDoc);

    PropertyValue[] storeProps = new PropertyValue[1];

    storeProps[0] = new PropertyValue();

    storeProps[0].Name = "FilterName";

    storeProps[0].Value = "StarDraw 5.0";        

    xStorable.storeAsURL(storeUrl, storeProps);          

}  

If an empty array of PropertyValue structs is passed, the native .odg format of OpenOffice.org is used.

Exporting

Exporting is not a feature of drawing documents. There is a separate service available from the global service manager for exporting, com.sun.star.drawing.GraphicExportFilter. It supports three interfaces: com.sun.star.document.XFilter, com.sun.star.document.XExporter and com.sun.star.document.XMimeTypeInfo.

UML diagram shwoing the com.sun.star.drawing.GraphicExportFilter serviceIllustration 10.4: GraphicExportFilter

Exporting is a simple process. After getting a GraphicExportFilter from the ServiceManager, use its XExporter interface to inform the filter which draw page, shape or shape collection to export.

Method of com.sun.star.document.XExporter: 

void setSourceDocument ( [in] com::sun::star::lang::XComponent xDoc)

The method name setSourceDocument() may be confusing. Actually, the method would allow  exporting entire documents, however, it is only possible to export draw pages, single shapes or shape collections from a drawing document. Since these objects support the XComponent interface, the method specification allows maximum flexibility.

Next, run the method filter() at the XFilter interface. To interrupt the exporting process, call cancel() on the same interface.

Methods of com.sun.star.document.XFilter: 

boolean filter( [in] sequence< com::sun::star::beans::PropertyValue > aDescriptor)

void cancel()

Filter Options

The method filter() takes a sequence of PropertyValue structs describing the filter parameters. The following properties from the com.sun.star.document.MediaDescriptor are supported:

Properties of com.sun.star.document.MediaDescriptor supported by GraphicExportFilter

MediaType

Depending on the export filters supported by this component, this is the mime type of the target graphic file. The mime types currently supported are: 

image/x-MS-bmp
application/dxf
application/postscript
image/gif
image/jpeg
image/png
image/x-pict
image/x-pcx
image/x-portable-bitmap
image/x-portable-graymap
image/x-portable-pixmap
image/x-cmu-raster
image/targa
image/tiff
image/x-xbitmap
image/x-xpixmap
image/svg+xml

FilterName

This property can been used if no MediaType exists with "Windows Metafile" or "Enhanced Metafile". FilterName has to be set to the extension of these graphic formats (WMF, EMF, BMP).

URL

The target URL of the file that is created during export.  

 

Note graphics marks a special text section

If necessary, use the interface XMimeTypeInfo to get all mime types supported by the GraphicExportFilter. It offers the following methods:

boolean supportsMimeType( [in] string MimeTypeName )

sequence< string > getSupportedMimeTypeNames()

XMimeTypeInfo is currently not supported by the GraphicExportFilter

The following example exports a draw page xPage from a given document xDrawDoc: (Drawing/GraphicExportDemo.java)

    //get draw pages

    com.sun.star.drawing.XDrawPagesSupplier xPageSupplier = (com.sun.star.drawing.XDrawPagesSupplier)

        UnoRuntime.queryInterface(com.sun.star.drawing.XDrawPagesSupplier.class, xDrawDoc);

    com.sun.star.drawing.XDrawPages xDrawPages = xPageSupplier.getDrawPages();

 

    // first page

    Object page = xDrawPages.getByIndex(0);

    com.sun.star.drawing.XDrawPage xPage = (com.sun.star.drawing.XDrawPage)UnoRuntime.queryInterface(

        com.sun.star.drawing.XDrawPage.class, page);

 

    Object GraphicExportFilter = xServiceFactory.createInstance(

        "com.sun.star.drawing.GraphicExportFilter");

 

    // use the XExporter interface to set xPage as source component

    // for the GraphicExportFilter

    XExporter xExporter = (XExporter)UnoRuntime.queryInterface(

        XExporter.class, GraphicExportFilter );

 

    XComponent xComp = (XComponent)UnoRuntime.queryInterface(XComponent.class, xPage);

    xExporter.setSourceDocument(xComp);

       

    // prepare the media descriptor for the filter() method in XFilter

    PropertyValue aProps[] = new PropertyValue[2];

 

    aProps[0] = new PropertyValue();

    aProps[0].Name = "MediaType";

    aProps[0].Value = "image/gif";

 

    // for some graphic formats, e.g. Windows Metafile, there is no Mime type,

    // therefore it is also possible to use the property FilterName with

    // Filter names as defined in the file TypeDetection.xml (see "Storing")

    /* aProps[0].Name = "FilterName";

       aProps[0].Value = "WMF - MS Windows Metafile";

    */

 

    aProps[1] = new PropertyValue();

    aProps[1].Name = "URL";

    aProps[1].Value = "file:///home/images/page1.gif";

 

    // get XFilter interface and launch the export

    XFilter xFilter = (XFilter) UnoRuntime.queryInterface(

        XFilter.class, GraphicExportFilter);

    xFilter.filter(aProps);

10.2.3  Printing Drawing Documents

Printer and Print Job Settings

Printing is a common office functionality. Refer to Chapter 7 Office Development for additional information. The Draw document implements the com.sun.star.view.XPrintable interface for printing. It consists of three methods:

sequence< com::sun::star::beans::PropertyValue > getPrinter()

void setPrinter( [in] sequence< com::sun::star::beans::PropertyValue > aPrinter)

void print( [in] sequence< com::sun::star::beans::PropertyValue > xOptions)

To print to the standard printer without settings, use the snippet below with a given document xDoc:

    // query the XPrintable interface from your document

    XPrintable xPrintable = (XPrintable)UnoRuntime.queryInterface(XPrintable.class, xDoc);

       

    // create an empty printOptions array

    PropertyValue[] printOpts = new PropertyValue[0];

       

    // kick off printing       

    xPrintable.print(printOpts);

There are two groups of properties involved in general printing. The first one is used with setPrinter() and getPrinter(),and controls the printer, the second one is passed to print() and controls the print job.

The method getPrinter() returns a sequence of PropertyValue structs describing the printer containing the properties specified in the service com.sun.star.view.PrinterDescriptor. It comprises the following properties:

Properties of com.sun.star.view.PrinterDescriptor

Name

string Specifies the name of the printer queue to be used.

PaperOrientation

com.sun.star.view.PaperOrientation. Specifies the orientation of the paper.

PaperFormat

com.sun.star.view.PaperFormat. Specifies a predefined paper size or if the paper size is a user-defined size.

PaperSize

com.sun.star.awt.Size. Specifies the size of the paper in  1/100 mm.

IsBusy

boolean Indicates if the printer is busy.

CanSetPaperOrientation

boolean Indicates if the printer allows changes to PaperOrientation.

CanSetPaperFormat

boolean Indicates if the printer allows changes to PaperFormat.

CanSetPaperSize

boolean Indicates if the printer allows changes to PaperSize.

The PrintOptions offer the following choices for a print job:

Properties of com.sun.star.view.PrintOptions

CopyCount

short Specifies the number of copies to print.

FileName

string If set, specifies the name of a file to print to.

Collate

boolean Advises the printer to collate the pages of the copies. If true, a whole document is printed prior to the next copy, otherwise copies for each page are completed together.

Pages

string Specifies the pages to print. It has the same format as in the print dialog of the GUI, for example, 1, 3, 4-7, 9.

The following method uses PrinterDescriptor and PrintOptions to print to a specific printer, and preselect the pages to print:

The following method uses both, PrinterDescriptor and PrintOptions, to print to a specific printer and preselect the pages to print:

protected void printDocComponent(XComponent xDoc) throws java.lang.Exception { 

    XPrintable xPrintable = (XPrintable)UnoRuntime.queryInterface(XPrintable.class, xDoc);

    PropertyValue[] printerDesc = new PropertyValue[1];

    printerDesc[0] = new PropertyValue();

    printerDesc[0].Name = "Name";

    printerDesc[0].Value = "5D PDF Creator";        

 

    xPrintable.setPrinter(printerDesc);        

       

    PropertyValue[] printOpts = new PropertyValue[1];

    printOpts[0] = new PropertyValue();

    printOpts[0].Name = "Pages";

    printOpts[0].Value = "1-4,7";        

       

    xPrintable.print(printOpts);

In Draw documents, one slide is printed as one page on the printer by default. In the example above, slide one through four and slide seven are printed. 

Special Print Settings

The printed drawing view (drawings, notes, handout pages, outline), the print quality (color, grayscale), the page options (tile, fit to page, brochure, paper tray) and additional options (page name, date, time, hidden pages) can all be controlled. 10.6.2 Drawing - Overall Document Features - Settings describes how these settings are used.

10.3  Working with Drawing Documents

10.3.1  Drawing Document

Document Structure

UML diagram showing the com.sun.star.drawing.DrawingDocument serviceIllustration 10.5: DrawingDocument Structure

Draw documents maintain their drawing content on draw pages, master pages and layers. If a new draw document is opened, it contains one slide that corresponds to a com.sun.star.drawing.DrawPage service. Switching to Master View brings up the master page handled by the service com.sun.star.drawing.MasterPage. The Layer View allows access to layers to structure your drawings. These layers can be controlled through com.sun.star.drawing.Layer and com.sun.star.drawing.LayerManager.

Page Handling

Draw and Impress documents supply their pages (slides) through the interface com.sun.star.drawing.XDrawPagesSupplier. The method com.sun.star.drawing.XDrawPagesSupplier:getDrawPages() returns a container of draw pages with a com.sun.star.drawing.XDrawPages interface that is derived from com.sun.star.container.XIndexAccess. That is, XDrawPages allows accessing, inserting and removing pages of a drawing document:

type getElementType()

boolean hasElements()

long getCount()

any getByIndex(long Index)

 

com::sun::star::drawing::XDrawPage insertNewByIndex(long nIndex)

void remove(com::sun::star::drawing::XDrawPage xPage)

The example below demonstrates how to access and create draw and master pages. Layers will be described later. 

    XDrawPagesSupplier xDrawPagesSupplier = (XDrawPagesSupplier)UnoRuntime.queryInterface(

        XDrawPagesSupplier.class, xComponent);
   

    // XDrawPages inherits from com.sun.star.container.XIndexAccess

    XDrawPages xDrawPages = xDrawPagesSupplier.getDrawPages();

    // get the page count for standard pages
   int nPageCount = xDrawPages.getCount();

    // get draw page by index

    XDrawPage xDrawPage = (XDrawPage)UnoRuntime.queryInterface(XDrawPage .class,

        xDrawPages.getByIndex(nIndex));

    /* create and insert a draw page into the given position,
      the method returns the newly created page

    */
   XDrawPage xNewDrawPage = xDrawPages.insertNewByIndex(0);

    // remove the given page

    xDrawPages.remove( xDrawPage );

    /* now repeat the same procedure as described above for the master pages,
      the main difference is to get the XDrawPages from the XMasterPagesSupplier
      interface

    */

    XMasterPagesSupplier xMasterPagesSupplier = (XMasterPagesSupplier)UnoRuntime.queryInterface(

        XMasterPagesSupplier.class, xComponent);

    XDrawPages xMasterPages = xMasterPagesSupplier.getMasterPages();

    // xMasterPages can now be used in the same manner as xDrawPages is used above

Each draw page always has one master page. The interface
com.sun.star.drawing.XMasterPageTarget offers methods to get and set the master page that is correlated to a draw page.

    // query for MasterPageTarget

    XMasterPageTarget xMasterPageTarget = (XMasterPageTarget)UnoRuntime.queryInterface(

        XMasterPageTarget.class, xDrawPage);

    // now we can get the corresponding master page

    XDrawPage xMasterPage = xMasterPageTarget.getMasterPage();

    /* this method now sets a new master page,

       it is important to mention that the applied page must be part of the MasterPages

    */

    xMasterPageTarget.setMasterPage(xMasterPage);

It is possible to copy pages using the interface com.sun.star.drawing.XDrawPageDuplicator of drawing or presentation documents.

Methods of com.sun.star.drawing.XDrawPageDuplicator:

com::sun::star::drawing::XDrawPage duplicate( [in] com::sun::star::drawing::XDrawPage xPage)

Pass a draw page reference to the method duplicate(). It appends a new draw page at the end of the page list, using the default naming scheme for pages, “slide n”.

Page Partitioning

All units and dimensions are measured in 1/100th of a millimeter. The coordinates are increasing from left to right, and from top to bottom. The upper-left position of a page is (0, 0).

The page size, margins and orientation can be determined using the following properties of a draw page (generic draw page): 

Properties of com.sun.star.drawing.GenericDrawPage

Height

long Height of the page.

Width

long Width of the page.

BorderBottom

long Bottom margin of the page.

BorderLeft

long Left margin of the page.

BorderRight

long Right margin of the page.

BorderTop

long Top margin of the page.

Orientation

com.sun.star.view.PaperOrientation. Determines if the printer output should be turned by 90°. Possible values are: PORTRAIT and LANDSCAPE.

10.3.2  Shapes

Drawings consist of shapes on draw pages. Shapes are drawing elements, such as rectangles, circles, polygons, and lines. To create a drawing, get a shape by its service name at the ServiceFactory of a drawing document and add it to the appropriate DrawPage.

The code below demonstrates how to create shapes. It consists of a static helper method located in the class ShapeHelper and will be used throughout this chapter to create shapes. The parameter xComponent must be a reference to a loaded drawing document. The x, y, height and width are the desired position and size, and sShapeType expects a service name for the shape, such as "com.sun.star.drawing.RectangleShape". The method does not actually insert the shape into a page. It instantiates it and returns the instance to the caller.

UML diagram showing the com.sun.star.drawing.Shape serviceIllustration 10.6: Shape

The size and position of a shape can be set before adding a shape to a page. After adding the shape, change the shape properties through com.sun.star.beans.XPropertySet. (Drawing/Helper.java)

public static XShape createShape( XComponent xComponent, 

    int x, int y, int width, int height, String sShapeType) throws java.lang.Exception {

    // query the document for the document-internal service factory

    XMultiServiceFactory xFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(

        XMultiServiceFactory.class, xComponent);

 

    // get the given Shape service from the factory

    Object xObj = xFactory.createInstance(sShapeType);

    Point  aPos = new Point(x, y);

    Size   aSize = new Size(width, height);

 

    // use its XShape interface to determine position and size before insertion

    xShape = (XShape)UnoRuntime.queryInterface(XShape.class, xObj);

    xShape.setPosition(aPos);

    xShape.setSize(aSize);

    return xShape;

Pay attention to the following important text section

Notice, the following restrictions: A shape cannot be inserted into multiple pages, and most methods do not work before the shape is inserted into a draw page. 

The previously declared method will be used to create a simple rectangle shape with a size of 10 cm x 5 cm that is positioned in the upper-left, and inserted into a drawing page. 

The graphic shows a sample RectangleShape

    // query DrawPage for XShapes interface

    XShapes xShapes = (XShapes)UnoRuntime.queryInterface(XShapes.class, xDrawPage);

    // create the shape

    XShape xShape = createShape(xComponent, 0, 0, 10000, 5000, “com.sun.star.drawing.RectangleShape”);

    // add shape to DrawPage

    xShapes.add(xShape);

    // set text

    XText xText = (XText)UnoRuntime.queryInterface( XText.class, xShape );

    xText.setString("My new RectangleShape");

    // to be able to set Properties a XPropertySet interface is needed

    XPropertySet xPropSet = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xShape);

    xPropSet.setPropertyValue("CornerRadius", new Integer(1000));

    xPropSet.setPropertyValue("Shadow", new Boolean(true));

    xPropSet.setPropertyValue("ShadowXDistance", new Integer(250));

    xPropSet.setPropertyValue("ShadowYDistance", new Integer(250));

    // blue fill color

    xPropSet.setPropertyValue("FillColor", new Integer(0xC0C0C0));

    // black line color

    xPropSet.setPropertyValue("LineColor", new Integer(0x000000));

    xPropSet.setPropertyValue("Name", "Rounded Gray Rectangle");

 

The UML diagram in Illustration 10.3 describes all services that are included by the com.sun.star.drawing.RectangleShape service and provides an overview of properties that can be used with such a simple shape.

UML diagram showing the com.sun.star.drawing.RectangleShape serviceIllustration 10.7: RectangleShape

Shape Types 

Overview graphic of different Shape typesOverview graphic of different Shape typesIllustration 10.8 ShapeTypes

The following table lists all shapes supported in Draw and Impress documents. They come from the com.sun.star.drawing. Each shape is based on com.sun.star.drawing.Shape. Additionally, there are five services in the module com.sun.star.drawing that most of the shapes have in common:

com.sun.star.drawing.Text, com.sun.star.drawing.LineProperties, com.sun.star.drawing.FillProperties and com.sun.star.drawing.ShadowProperties handle shape formatting, whereas com.sun.star.drawing.RotationDescriptor controls rotation and shearing. The section 10.3.2 Drawing - Working with Drawing Documents - Shapes - Shape Operations - General Drawing Properties below discusses shape formatting in more detail. Refer to the section 10.3.2 Drawing - Working with Drawing Documents - Shapes - Shape Operations for information on rotation and shearing.

Note graphics marks a special text section

The service com.sun.star.drawing.Text is different from other Text services. It consists of the service com.sun.star.drawing.TextProperties and the interface com.sun.star.text.XText that was introduced in the chapter 2 First Steps. Drawing text does not supports text contents other than paragraphs consisting of character strings.

An x denotes which of these services are supported by each shape. The rightmost column shows the services, interfaces and properties that are specific for the various shapes.

ShapeType 

Text 

LineProperties 

FillProperties 

ShadowProperties 

RotationDescriptor 

supported services, 

exported interfaces, 

properties 

ClosedBezierShape

included service:
com.sun.star.drawing.PolyPolygonBezierDescriptor

ConnectorShape

 

included service:
com.sun.star.drawing.ConnectorProperties

properties:
com.sun.star.drawing.XShape StartShape
com.sun.star.drawing.XShape EndShape
com.sun.star.awt.Point StartPosition
com.sun.star.awt.Point EndPosition
long StartGluePointIndex
long EndGluePointIndex
long EdgeLine1Delta
long EdgeLine2Delta
long EdgeLine3Delta

ControlShape

 

 

 

 

 

exported interface:
com.sun.star.drawing.XControlShape

EllipseShape

properties:
com.sun.star.drawing.CircleKind CircleKind
long CircleStartAngle
long CircleEndAngle

GraphicObjectShape

 

 

properties:
string GraphicURL
string GraphicStreamURL
short AdjustLuminance
short AdjustContrast
short AdjustRed
short AdjustGreen
short AdjustBlue
double Gamma
short Transparency
com.sun.star.drawing.ColorMode GraphicColorMode
optional properties:
com.sun.star.awt.XBitmap GraphicObjectFillBitmap
com.sun.star.container.XIndexContainer ImageMap

GroupShape

 

 

 

 

 

exported interfaces:
com.sun.star.drawing.XShapeGroup
com.sun.star.drawing.XShapes

LineShape

 

included service:
com.sun.star.drawing.PolyPolygonDescriptor

MeasureShape

 

included service:
com.sun.star.drawing.MeasureProperties

properties:
com.sun.star.awt.Point StartingPosition
com.sun.star.awt.Point EndPosition

OLE2Shape

 

 

 

 

 

properties:
string CLSID

readonly properties:
com.sun.star.frame.XModel Model
boolean IsInternal

OpenBezierShape

 

included service:
com.sun.star.drawing.PolyPolygonBezierDescriptor

PageShape

 

 

 

 

 

 

PolyLineShape

 

included service:
com.sun.star.drawing.PolyPolygonDescriptor

PolyPolygonBezierShape

included service:
com.sun.star.drawing.PolyPolygonBezierDescriptor

PolyPolygonShape

included service:
com.sun.star.drawing.PolyPolygonDescriptor

RectangleShape

properties:
long CornerRadius

TextShape

properties:
long CornerRadius

PluginShape

 

 

 

 

 

properties:
string PluginMimeType
string PluginURL
sequence<
com.sun.star.beans.PropertyValue > PluginCommands

Bezier Shapes

Draw supports three different kinds of Bezier curves: OpenBezierShape, ClosedBezierShape and PolyPolygonBezierShape. They are all controlled by com.sun.star.drawing.PolyPolygonBezierDescriptor which is made up of the following properties:

Properties of com.sun.star.drawing.PolyPolygonBezierDescriptor

PolygonKind

[readonly] com.sun.star.drawing.PolygonKind. Type of the polygon. Possible values are:

LINE for a LineShape.

POLY for a PolyPolygonShape.

PLIN for a PolyLineShape.

PATHLINE for an OpenBezierShape.

PATHFILL for a ClosedBezierShape.

 

PolyPolygonBezier

struct com.sun.star.drawing.PolyPolygonBezierCoords. These are the bezier points of the polygon. The struct members are Coordinates and Flags, which are both sequences of sequences. The Coordinates sequence contains com.sun.star.awt.Point structs and the Flags sequence contains com::com.sun.star.drawing.PolygonFlags enums. Point members are X and Y. Possible PolygonFlags values are:

  • NORMAL the point is normal, from the curve discussion view.

  • SMOOTH the point is smooth, the first derivation from the curve discussion view.

  • CONTROL the point is a control point, to control the curve from the user interface.

  • SYMMETRIC the point is symmetric, the second derivation from the curve discussion view.

Geometry

com.sun.star.drawing.PolyPolygonBezierCoords. These are the untransformed bezier coordinates of the polygon. The property has the same type as PolyPolygonBezier.

The next Java example will demonstrate how to create a ClosedBezierShape that looks like the following picture. (Drawing/DrawingDemo.java)

The graphic shows a BezierShape

    XShape xPolyPolygonBezier = createShape( xComponent, 0, 0, 0, 0,

        "com.sun.star.drawing.ClosedBezierShape");

    // take care of the fact that the shape must have been added

    // to the page before it is possible to apply changes

    XShapes xShapes = (XShapes)UnoRuntime.queryInterface( XShapes.class, xDrawPage);

    xShapes.add(xPolyPolygonBezier);

    // now it is possible to edit the PropertySet

    XPropertySet xShapeProperties = (XPropertySet)UnoRuntime.queryInterface(

        XPropertySet.class, xPolyPolygonBezier);

    // The following values are exemplary and provokes that a PolyPolygon of

    // sixteen single polygons containing four points each is created. The

    // PolyPolygon total point count will be 64.

    // If control points are used they are allowed to appear as pair only,

    // before and after such pair has to be a normal point.

    // A bezier point sequence may look like

    // this (n=normal, c=control) : n c c n c c n n c c n

    int nPolygonCount   = 16;

    int nPointCount     = 4;

    int nWidth          = 10000;

    int nHeight         = 10000;

    PolyPolygonBezierCoords aCoords = new PolyPolygonBezierCoords();

    // allocating the outer sequence

    aCoords.Coordinates = new Point[nPolygonCount][];

    aCoords.Flags       = new PolygonFlags[nPolygonCount][];

    int i, n, nY;

       

    // fill the inner point sequence now

    for (nY = 0, i = 0; i < nPolygonCount; i++, nY += nHeight / nPolygonCount) {

        // create a polygon using two normal and two control points

        // allocating the inner sequence

        Point[]                 pPolyPoints = new Point[nPointCount];

        PolygonFlags[]        pPolyFlags  = new PolygonFlags[nPointCount];

        for (n = 0; n < nPointCount; n++)

            pPolyPoints[n] = new Point();

        pPolyPoints[0].X = 0;

        pPolyPoints[0].Y = nY;

        pPolyFlags [0] = PolygonFlags.NORMAL;

        pPolyPoints[1].X = nWidth / 2;

        pPolyPoints[1].Y = nHeight;

        pPolyFlags[1] = PolygonFlags.CONTROL;

        pPolyPoints[2].X = nWidth / 2;

        pPolyPoints[2].Y = nHeight;

        pPolyFlags [2] = PolygonFlags.CONTROL;

        pPolyPoints[3].X = nWidth;

        pPolyPoints[3].Y = nY;

        pPolyFlags [3] = PolygonFlags.NORMAL;

        aCoords.Coordinates[i] = pPolyPoints;

        aCoords.Flags[i] = pPolyFlags;

    }

    try {

        xShapeProperties.setPropertyValue("PolyPolygonBezier", aCoords);

    } catch (Exception ex)

    {

    }

Shape Operations

Moving and Scaling

Moving and scaling of a shape can be done by using the corresponding methods getPosition(), setPosition(), getSize() and setSize() of the com.sun.star.drawing.XShape interface:

string getShapeType()

com::sun::star::awt::Point getPosition()

void setPosition( [in] com::sun::star::awt::Point aPosition)

com::sun::star::awt::Size getSize()

void setSize( [in] com::sun::star::awt::Size aSize)

Point and Size are IDL structs. In Java, these structs are mapped to classes with constructors that take values for the struct members. Therefore, when new is used to instantiate these classes, the coordinates and dimensions are passed to initialize the class members X, Y, Width and Height.

Rotating and Shearing

Most shapes, except OLE and group objects, can be rotated and sheared. All of these objects include the com.sun.star.drawing.RotationDescriptor service that has the properties RotateAngle and ShearAngle.

Setting the com.sun.star.drawing.RotationDescriptor rotates or shears a shape:

Properties of com.sun.star.drawing.RotationDescriptor

RotateAngle

long This is the angle for rotation of this shape in 1/100th of a degree. The shape is rotated counter-clockwise around the center of the bounding box.

ShearAngle

long This is the amount of shearing for this shape in 1/100th of a degree. The shape is sheared clockwise around the center of the bounding box.

Note graphics marks a special text section

Notice that the rotation works counter-clockwise, while shearing works clockwise. 

Graphic which illustrates the meaning of Rotation and ShearingIllustration 10.9 Rotation and Shearing by 25 degrees

The following example shows how a shape can be rotated by 25 degrees counterclockwise: 

 

// xShape will be rotated by 25 degrees

    XPropertySet xPropSet = (XPropertySet)UnoRuntime.queryInterface(

        XPropertySet.class, xShape );

    xPropSet.setPropertyValue( "RotateAngle", new Integer( 2500 ) );

Transforming

Changing the size, rotation and shearing of an object can be done by using the transformation mechanism provided by OpenOffice.org. The matrix of our API is a standard homogenous 3x3 matrix that may be used together with the java.awt.geom.AffineTransform class from Java. The transformation received describes the actual values of the transformations as a linear combination of the single matrices. The basic object without transformation has a size of (1, 1) and a position of (0, 0), and is not rotated or sheared. Thus, to transform an object get its matrix and multiply from the left side to influence the current appearance. To set the whole transformation directly, build a combined matrix of the single values mentioned above and apply it to the object. (Drawing/ObjectTransformationDemo.java

    XPropertySet xPropSet = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, xShape );

    // take the current tranformation matrix

    HomogenMatrix3 aHomogenMatrix3 = (HomogenMatrix3)xPropSet.getPropertyValue("Transformation");

    java.awt.geom.AffineTransform aOriginalMatrix = new java.awt.geom.AffineTransform(
       aHomogenMatrix3.Line1.Column1, aHomogenMatrix3.Line2.Column1,

        aHomogenMatrix3.Line1.Column2, aHomogenMatrix3.Line2.Column2,

        aHomogenMatrix3.Line1.Column3, aHomogenMatrix3.Line2.Column3 );

    // rotate the object by 15 degrees

    AffineTransform aNewMatrix1 = new AffineTransform();

    aNewMatrix1.setToRotation(Math.PI /180 * 15);

    aNewMatrix1.concatenate(aOriginalMatrix);

    // and translate the object by 2cm on the x-axis

    AffineTransform aNewMatrix2 = new AffineTransform();
   aNewMatrix2.setToTranslation(2000, 0);
   aNewMatrix2.concatenate(aNewMatrix1);

    double aFlatMatrix[] = new double[6];
   aNewMatrix2.getMatrix(aFlatMatrix);

    // convert the flatMatrix to our HomogenMatrix3 structure

    aHomogenMatrix3.Line1.Column1 = aFlatMatrix[0];
   aHomogenMatrix3.Line2.Column1 = aFlatMatrix[1];
   aHomogenMatrix3.Line1.Column2 = aFlatMatrix[2];
   aHomogenMatrix3.Line2.Column2 = aFlatMatrix[3];

    aHomogenMatrix3.Line1.Column3 = aFlatMatrix[4];
   aHomogenMatrix3.Line2.Column3 = aFlatMatrix[5];

       
   xPropSet.setPropertyValue("Transformation", aHomogenMatrix3);

Ordering

The property ZOrder of the com.sun.star.drawing.Shape service defines the order a shape is drawn. That is, if there are many shapes on a page, the shape that has the lowest ZOrder value is drawn first, and the shape that has the highest ZOrder is drawn last. By using this property it is possible to bring an object to the back or front of a page. It is also possible to switch the order of two shapes as demonstrated in the following example: (Drawing/ChangeOrderDemo.java)

    XPropertySet xPropSet1 = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xShape1);

    XPropertySet xPropSet2 = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xShape2);

    // get current positions

    int nOrderOfShape1 = ((Integer)xPropSet1.getPropertyValue("ZOrder")).intValue();