OpenOffice.org Macros Explained

The primary function of Draw and Impress documents is to contain graphical data, which is stored in draw pages. The primary draw-page functionality is implemented by a GenericDrawPage. There are two types of draw pages-the MasterPage and the DrawPage. Both draw-page types implement the GenericDrawPage and are therefore able to hold and manipulate the same content.

A master page acts as a common background for zero or more draw pages. Each draw page may link to one master page. Each master page is constrained as follows :

The method getMasterPages() returns the document's collection of master pages. The method getDrawPages() returns the document's collection of draw pages. Both methods return the same object type; they differ only in how their contents are used (see Table 1 ).

Table 1: Methods supported by the com.sun.star.drawing.XDrawPages interface.

Method

Description

insertNewBylndex(Long)

Create and insert a new draw page at the specified index.

hasByName(String)

Return True if the named page exists.

hasElements()

Return True if any draw pages exist.

remove(DrawPage)

Remove a specific draw page.

getCount()

Return the number of contained objects as a Long Integer.

getBylndex(Long)

Get the specified draw page.

getByName(String)

Get the specified draw page.

duplicate(DrawPage)

Duplicate the DrawPage and return the new DrawPage.

hasElements()

Return True if there are draw pages to return.

Each draw page has a name , which you can access by using the methods getName() and setName(). A draw page that is not a master supports the methods getMasterPage() and setMasterPage() to get and set the master page. Listing 2 demonstrates enumerating the document's draw pages and their corresponding master pages.

Listing 2: getPages is found in the Graphic module in this chapter's source code files as SC15.sxi.

Sub getPages() Dim s$ s = s & getPagesInfo(ThisComponent.getDrawPages(), "Draw Pages") s = s & CHR$(10) s = s & getPagesInfo(ThisComponent.getMasterPages(), "Master Pages") MsgBox s, 0, "Pages" End Sub Function getPagesInfo(oDPages, sType$) As String Dim i%, s$ Dim oDPage, oMPage s = s & "*** There are " & oDPages.getCount() & " " & sType & CHR$(10) For i = 0 To oDPages.getCount()-1 oDPage = oDPages.getByIndex(i) s = s & "Page " & i & " = '" & oDPage.getName() & " ' " If NOT oDPage.supportsService("com.sun.star.drawing.MasterPage") Then oMPage = oDPage.getMasterPage() s = s & " master = " If NOT IsNull(oMPage) AND NOT IsEmpty(oMPage) Then s = s & "'" & oMPage.getName() & " ' " End If End If s = s & CHR$(10) Next getPagesInfo = s End Function

 

Although you can get a draw page based on its name, you can have more than one draw page with the same name. If multiple draw pages use the same name and you retrieve the draw page based on the name, it is not specified which draw page is returned. The macro in Listing 3 , which searches for a draw page with a specific name, is used in numerous places in this chapter.

Listing 3: createDrawPage is found in the Graphic module in this chapter's source code files as SC15.sxi.

Function createDrawPage(oDoc, sName$, bForceNew As boolean) As Variant Dim oPages 'All of the draw pages Dim oPage 'A single draw page Dim i% 'General index variable oPages = oDoc.getDrawPages() If oPages.hasByName(sName) Then REM If we require a new page then delete REM the page and get out of the for loop. If bForceNew Then oPages.remove(oPages.getByName(sName)) Else REM Did not request a new page so return the found page REM and then get out of the function. createDrawPage = oPages.getByName(sName) Exit Function End If End If REM Did not find the page, or found the page and removed it. REM Create a new page, set the name, and return the page. oPages.insertNewByIndex(oPages.getCount()) oPage = oPages.getByIndex(oPages.getCount()-1) oPage.setName(sName) createDrawPage = oPage End Function

 

Generic Draw Page

Both regular and master draw pages support the GenericDrawPage service. As its name implies, the GenericDrawPage service provides the primary generic drawing functionality. Writer and Calc documents provide specific styles for formatting entire pages. Draw pages, however, use the properties shown in Table 2 .

Table 2: Properties defined by the com.sun.star.drawing.GenericDrawPage service.

Property

Description

BorderBottom

Bottom border in 1/100 mm, represented as a Long Integer.

BorderLeft

Left border in 1/100 mm, represented as a Long Integer.

BorderRight

Right border in 1/100 mm, represented as a Long Integer.

BorderTop

Top border in 1/100 mm, represented as a Long Integer.

Height

Height in 1/100 mm, represented as a Long Integer.

Width

Width in 1/100 mm, represented as a Long Integer.

Number

Draw page number as a Short Integer. This read-only value labels the first page 1.

Orientation

Page orientation as a com.sun.star.view.PaperOrientation enumeration. Two values are supported-PORTRAIT and LANDSCAPE.

UserDefinedAttributes

User-defined XML attributes.

IsBackgroundDark

True if the averaged background fill color 's luminance is below a specified threshold value.

The primary purpose of a draw page is to contain shapes . The methods addShape(Shape) and removeShape (Shape) add and remove a shape from a document. Before a shape can be added to a draw page, it must be created by the document. Each line produced by Listing 4 and shown in Figure 1 is a separate, unrelated shape. You can indepently manipulate each of these shapes.

Figure 1: Twenty lines in an Impress document.

Listing 4: drawFirstGraphic is found in the Graphic module in this chapter's source code files as SC15.sxi.

Sub drawFirstGraphic() Dim oPage 'Page on which to draw Dim oShape 'Shape to insert Dim oPoint 'Initial start point of the line Dim oSize 'Width and height of the line Dim i% 'Index variable Dim n% 'Number of iterations to perform oPage = createDrawPage(ThisComponent, "Test Draw", True) n = 20 For i = 0 To n oShape = ThisComponent.createInstance("com.sun.star.drawing.LineShape") oShape.LineColor = RGB( 255, 0, i+20 ) oShape.LineWidth = 20 oPoint = oShape.Position oPoint.X = oPage.Width / 4 oPoint.Y = i * oPage.Height / n / 4 oShape.Position = oPoint oSize = oShape.Size oSize.Height = (oPage.Height - 2 * i * oPage.Height / n) / 4 oSize.Width = oPage.Width / 2 oShape.Size = oSize oPage.add(oShape) Next End Sub

 

Combining Shapes

The macro in Listing 4 creates 20 independent lines. You can group shapes together and then manipulate them as a single shape. The method group(XShapes) accepts a collection of shapes and turns them into a single group ; an XShapeObject is returned. The macro in Listing 5 starts by calling Listing 4 and then it adds all of the lines to a single group.

Listing 5: groupShapes is found in the Graphic module in this chapter's source code files as SC15.sxi.

Sub groupShapes Dim oPage 'Page on which to draw Dim oShapes 'Shapes to group Dim i% 'Index variable REM Create the shapes! drawFirstGraphic() oPage = ThisComponent.getDrawPages().getByName("Test Draw") REM Create a shape collection object to group the shapes oShapes = createUnoService("com.sun.star.drawing.ShapeCollection") For i = 0 To oPage.getCount()-1 oShapes.add(oPage.getByIndex(i)) Next oPage.group(oShapes) End Sub

 

When several shapes are grouped together using the group() method, the entire group is added as a single shape into the draw page, which you can retrieve by using oPage.getByIndex(). It's no longer possible to select a single line and independently manipulate it. To convert a group of shapes back to independent shapes, use the ungroup (XShapeObject) method. The ungroup() method removes the objects from the group and adds them back to the draw page as individual objects (see Listing 6 ).

Listing 6: unGroupShapes is found in the Graphic module in this chapter's source code files as SC15.sxi.

Sub unGroupShapes Dim oPage 'Page on which to draw Dim oShape 'Single shape Dim i% 'Index variable oPage = ThisComponent.getDrawPages().getByName("Test Draw") For i = 0 To oPage.getCount()-1 oShape = oPage.getByIndex(i) If oShape.supportsService("com.sun.star.drawing.GroupShape") Then oPage.ungroup(oShape) End If Next End Sub

 

Although shapes that are grouped together are manipulated as one shape, they are really a collection of shapes. The combine(XShapes) method, on the other hand, converts each shape into a PolyPolygonBezierShape and then combines them into one PolyPolygonBezierShape. See Listing 7 . The new shape is added to the draw page, and the original shapes are removed and deleted. The split(XShape) method converts the shape to a PolyPolygonBezierShape (if it is not already) and then the shape is split into several shapes of type PolyPolygonBezierShape. The new shapes are added to the draw page and the original shape is removed and deleted.

Listing 7: combineShapes is found in the Graphic module in this chapter's source code files as SC15.sxi.

Sub combineShapes Dim oPage, oShapes, i% REM Create the shapes! drawFirstGraphic() oPage = ThisComponent.getDrawPages().getByName("Test Draw") oShapes = createUnoService("com.sun.star.drawing.ShapeCollection") For i = 0 To oPage.getCount()-1 oShapes.add(oPage.getByIndex(i)) Next oPage.combine(oShapes) End Sub

 

The bind(XShapes) method is similar to combine() except that the individual shapes are connected before they are combined. The output from Listing 7, therefore, is the same as Figure 1. Listing 8 , on the other hand, produces the output in Figure 2 . The shapes are connected by a line, each of which is really a Bezier curve.

Figure 2: Twenty lines bound together are connected with a line.

Listing 8: bindShapes is found in the Graphic module in this chapter's source code files as SC15.sxi.

Sub bindShapes() Dim oPage, oShapes, i% REM Create the shapes! drawFirstGraphic() oPage = ThisComponent.getDrawPages().getByName("Test Draw") oShapes = createUnoService("com.sun.star.drawing.ShapeCollection") For i = 0 To oPage.getCount()-1 oShapes.add(oPage.getByIndex(i)) Next oPage.bind(oShapes) End Sub

 

The unbind(XShape) method converts the shape to a PolyPolygonBezierShape (if it is not already) and then each line segment is converted to a new PolyPolygonBezierShape. The original shape is removed from the draw page and deleted. If unbind() is used on the shape in Figure 2, the output still looks like Figure 2, but 776 shapes are used.

Tip  

The methods group() and ungroup() act like "undo" for each other. The methods bind() and combine() are not "undo" for unbind() and split(), primarily because each shape is converted to a PolyPolygonBezierShape.

Категории