Chapter 11. Draw/Impress APIs Overview
This part discusses the APIs for both Draw and Impress since the presentations API is an extension of Office’s drawing functionality, adding such things as slide-related shapes (e.g. for the title, subtitle, header, and footer), more data views (e.g. an handout mode), and slide shows.
You’ll get a good feel for the APIs’ capabilities by reading the Draw and Impress user guides, downloadable from https://libreoffice.org/get-help/documentation.
This chapter gives a broad overview of the drawing and presentation APIs, with some small code snippets to illustrate the ideas. Subsequent chapters will return to these features in much more detail.
The APIs are organized around three services which subclass OfficeDocument, as depicted in Fig. 91.
The presentation API is mostly located in Office’s
com.sun.star.presentation package (or module), which is documented as presentation Module.
The interfaces highlighted in bold in Fig. 92 will be discussed in this chapter.
The DrawingDocument service is pretty much empty, with the real drawing ‘action’ in GenericDrawingDocument (which is in the
PresentationDocument subclasses GenericDrawingDocument to inherit its drawing capabilities,
and adds features for slide shows (via the XPresentationSupplier and XCustomPresentationSupplier interfaces).
The word “presentation” is a little overloaded in the API – PresentationDocument corresponds to the slide deck,
XPresentationSupplier.getPresentation() returns an XPresentation object which represents a slide show.
A drawing (or presentation) document consists of a series of draw pages, one for each page (or slide) inside the document. Perhaps the most surprising aspect of this is that a Draw document can contain multiple pages.
A document can also contain one or more master pages. A master page contains drawing/slide elements which appear on multiple draw page. This idea is probably most familiar from slide presentations where a master page holds the header, footer, and graphics that appear on every slide.
As illustrated in Fig. 91, GenericDrawingDocument supports an XDrawPagesSupplier interface whose
returns an XDrawPages object. It also has an XMasterPagesSupplier whose
getMasterPages() returns the master pages as an object.
Office views master pages as special kinds of draw pages, and so
getMasterPages() also returns an XDrawPages object.
A draw page is a collection of shapes: often text shapes, such as a title box or a box holding bullet points. But a shape can be many more things: an ellipse, a polygon, a bitmap, an embedded video, and so on.
This “page as shapes” notion is implemented by the API hierarchy shown in Fig. 94.
XPresentationPage is the interface for a slide’s page, but most of its functionality comes from XDrawPage. The XDrawPage interface doesn’t do much either, except for inheriting XShapes (note the “s”). XShapes inherits XIndexAccess, which means that an XShapes object can be manipulated as an indexed sequence of XShape objects.
The XDrawPage and XPresentationPage interfaces are supported by services, some of which are shown in Fig. 95. These services are in some ways more important than the interfaces, since they contain many properties related to pages and slides.
There are two
DrawPage services in the Office API, one in the drawing package (DrawPage), and another in the presentation package (Presentation).
This is represented in Fig. 95 by including the package names in brackets after the service names.
You can access the documentation for these services by typing
lodoc drawpage service drawing and
lodoc drawpage service presentation.
There is “(??)” next to the XDrawPage and XPresentationPage interfaces in Fig. 95 because they’re not listed in the GenericDrawPage and presentation DrawPage services in the documentation, but must be there because of the way that the code works. Also, the documentation for GenericDrawPage lists XShapes as an interface, rather than XDrawPage.
from ooodev.utils.lo import Lo loader = Lo.load_office(Lo.ConnectPipe()) doc = Lo.open_doc(fnm="foo", loader=loader)
from ooodev.utils.lo import Lo supplier = Lo.qi(XDrawPagesSupplier, doc) pages = supplier.getDrawPages() # XDrawPages
This code works whether the document is a sequence of draw pages (i.e. a Draw document) or slides (i.e. an Impress document).
Using the ideas shown in Fig. 93, a particular draw page is accessed based on its index position. The first draw page in the document is retrieved with:
from ooodev.utils.lo import Lo page = Lo.qi(XDrawPage, pages.getByIndex(0))
Pages are numbered from 0, and a newly created document always contains one page.
from ooodev.utils.props import Props width = int(Props.get(page, "Width")) page_number = int(Props.get(page, "Number"))
The “Width” and “Number” properties are documented in the GenericDrawPage service.
Once a single page has been retrieved, it’s possible to access its shapes (as shown in Fig. 94). The following code converts the XDrawPage object to XShapes, and accesses the first XShape in its indexed container:
from ooodev.utils.lo import Lo shapes = Lo.qi(XShapes, page) shape = Lo.qi(XShape, shapes.getByIndex(0))
Shapes fall into two groups – drawing shapes that subclass the Shape service in
and presentation-related shapes which subclass the Shape service in
The first type are described here, and the presentation shapes in 11.5 Shapes in a Presentation.
More about many of these shapes in Chapter 13. Drawing Basic Shapes and Chapter 15. Complex Shapes, but you can probably guess what most of them do
EllipseShape is for drawing ellipses and circles,
LineShape is for lines and arrows,
RectangleShape is for rectangles.
The two “??”s in Fig. 96 indicate that those services aren’t shown in the online documentation, but appear in examples.
The hardest aspect of this hierarchy is searching it for information on a shape’s properties.
Many general properties are located in the Shape service.
More specialized properties are located in the specific shape’s service.
For instance, RectangleShape has a
CornerRadius property which allows a rectangle’s corners to be rounded to make it more button-like.
Unfortunately, most shapes inherit a lot more properties than just those in Shape. Fig. 97 shows a typical example – RectangleShape inherits properties from at least eight services (I’ve not shown the complete hierarchy)!
Aside from RectangleShape inheriting properties from Shape, it also obtains its fill, shadow, line, and rotation attributes from the
FillProperties, ShadowProperties, LineProperties, and RotationDescriptor services. For instance, to make the rectangle red, the
defined in the FillProperties service, must be set. The code for doing this is not complex:
from ooodev.utils.props import Props from ooodev.utils.color import CommonColor Props.set(shape, FillColor=CommonColor.RED)
The complication comes in knowing that a property called
Follow RectangleShape link and look inside each inherited Property service until you find the relevant property.
There is a List of all members link on the top right side of all API pages.
If the shape contains some text (e.g. the rectangle has a label inside it), and you want to change one of the text’s properties, then you’ll need to look in the three property services above the Text service (see Fig. 97).
from ooodev.utils.props import Props from ooodev.utils.lo import Lo xtext = Lo.qi(XText, shape) cursor = xtext.createTextCursor() cursor.gotoStart(False) cursor.gotoEnd(True) # select all text Props.set(cursor, CharHeight=18);
First the shape is converted into an XText reference so that text selection can be done using a cursor.
CharHeight property is inherited from the CharacterProperties service.
The com.sun.star.presentation.Shape service doesn’t subclass the com.sun.star.drawing.Shape service. Instead, every presentation shape inherits the presentation Shape service and a drawing shape (usually TextShape). This means that all the presentation shapes can be treated as drawing shapes when being manipulated in code.
Most of the presentation shapes are special kinds of text shapes. For instance, TitleTextShape and OutlinerShape are text shapes which usually appear automatically when you create a new slide inside Impress – the slide’s title is typed into the TitleTextShape, and bullet points added to OutlinerShape. This is shown in Fig. 99.
OutlinerShape has at least nine property services that it inherits.
One difference between slides and drawings is that the presentations API supports slide shows.
This extra functionality can be seen in Fig. 92 since the PresentationDocument service offers an XPresentationSupplier interface
which has a
getPresentation() method for returning an XPresentation object. Don’t be confused by the name – an XPresentation object represents a slide show.
end() methods for starting and ending a slide show,
and the Presentation service contains properties for affecting how the show progresses, as illustrated by Fig. 101.
Code for starting a slide show for the “foo” document:
from ooodev.utils.lo import Lo loader = Lo.load_office(Lo.ConnectPipe()) doc = Lo.open_doc("foo", loader) ps = Lo.qi(XPresentationSupplier, doc) Lo.qi(XPresentation, ps.getPresentation()) show.start()
Alternatively a slide show can be started with a dispatch command.
from ooodev.utils.lo import Lo from ooodev.utils.dispatch.draw_view_dispatch import DrawViewDispatch loader = Lo.load_office(Lo.ConnectPipe()) doc = Lo.open_doc("foo", loader) Lo.delay(500) # wait half a sec Lo.dispatch_cmd(DrawViewDispatch.PRESENTATION)
The Presentation service is a bit lacking, so an extended service, Presentation2, was added more recently. It can access an XSlideShowController interface which gives finer-grained control over how the show progresses; examples will come later.