1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* libodfgen
3  * Version: MPL 2.0 / LGPLv2.1+
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * Major Contributor(s):
10  * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
11  * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch)
12  *
13  * For minor contributions see the git repository.
14  *
15  * Alternatively, the contents of this file may be used under the terms
16  * of the GNU Lesser General Public License Version 2.1 or later
17  * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
18  * applicable instead of those above.
19  *
20  * For further information visit http://libwpd.sourceforge.net
21  */
22 
23 /* "This product is not manufactured, approved, or supported by
24  * Corel Corporation or Corel Corporation Limited."
25  */
26 
27 #include <libodfgen/libodfgen.hxx>
28 
29 #include <locale.h>
30 #include <math.h>
31 
32 #include <deque>
33 #include <string>
34 #include <map>
35 #include <memory>
36 #include <stack>
37 
38 #include "DocumentElement.hxx"
39 #include "FilterInternal.hxx"
40 
41 #include "FontStyle.hxx"
42 #include "GraphicStyle.hxx"
43 #include "ListStyle.hxx"
44 #include "PageSpan.hxx"
45 #include "TableStyle.hxx"
46 #include "TextRunStyle.hxx"
47 
48 #include "OdfGenerator.hxx"
49 
50 // Workaround for the incapacity of impress to have multiple page
51 // sizes in the same document. Once that limitation is lifted,
52 // remove this
53 #define MULTIPAGE_WORKAROUND 1
54 
55 using namespace libodfgen;
56 
57 namespace
58 {
59 
60 struct GeneratorState
61 {
62 	bool mbIsTextBox;
63 	bool mbIsParagraph;
64 	bool mbIsTextOnPath;
65 	bool mInComment;
66 	bool mTableCellOpened;
67 	bool mInNotes;
68 
69 	GeneratorState();
70 };
71 
GeneratorState()72 GeneratorState::GeneratorState()
73 	: mbIsTextBox(false)
74 	, mbIsParagraph(false)
75 	, mbIsTextOnPath(false)
76 	, mInComment(false)
77 	, mTableCellOpened(false)
78 	, mInNotes(false)
79 {
80 }
81 
82 }
83 
84 class OdpGeneratorPrivate : public OdfGenerator
85 {
86 public:
87 	OdpGeneratorPrivate();
88 	~OdpGeneratorPrivate() override;
89 
90 	void openTextBoxFrame(const librevenge::RVNGPropertyList &propList);
91 	void closeTextBoxFrame();
92 
getGraphicManager()93 	GraphicStyleManager &getGraphicManager()
94 	{
95 		return mGraphicManager;
96 	}
97 
98 	void updatePageSpanPropertiesToCreatePage(librevenge::RVNGPropertyList &propList);
99 
100 	static void writeNotesStyles(OdfDocumentHandler *pHandler);
101 
102 	//! returns the document type
103 	bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) override;
104 	void _writeSettings(OdfDocumentHandler *pHandler) const;
105 	void _writeStyles(OdfDocumentHandler *pHandler);
106 	void _writeAutomaticStyles(OdfDocumentHandler *pHandler, OdfStreamType streamType);
107 
108 	// union of page size
109 	double mfMaxWidth;
110 	double mfMaxHeight;
111 
112 	//! the current page
113 	PageSpan *mpCurrentPageSpan;
114 	//! the actual page index
115 	int miPageIndex;
116 
117 	// generator state
118 	GeneratorState mState;
119 
120 	libodfgen::DocumentElementVector mDummyMasterSlideStorage;
121 
122 private:
123 	OdpGeneratorPrivate(const OdpGeneratorPrivate &);
124 	OdpGeneratorPrivate &operator=(const OdpGeneratorPrivate &);
125 
126 };
127 
OdpGeneratorPrivate()128 OdpGeneratorPrivate::OdpGeneratorPrivate() :
129 	mfMaxWidth(0.0), mfMaxHeight(0.0),
130 	mpCurrentPageSpan(nullptr), miPageIndex(0),
131 	mState(),
132 	mDummyMasterSlideStorage()
133 {
134 }
135 
~OdpGeneratorPrivate()136 OdpGeneratorPrivate::~OdpGeneratorPrivate()
137 {
138 }
139 
updatePageSpanPropertiesToCreatePage(librevenge::RVNGPropertyList & pList)140 void OdpGeneratorPrivate::updatePageSpanPropertiesToCreatePage(librevenge::RVNGPropertyList &pList)
141 {
142 	double width=0;
143 	if (pList["svg:width"] && !pList["fo:page-width"])
144 		pList.insert("fo:page-width", pList["svg:width"]->clone());
145 	if (pList["fo:page-width"] && getInchValue(*pList["fo:page-width"], width) && width>mfMaxWidth)
146 		mfMaxWidth=width;
147 	double height=0;
148 	if (pList["svg:height"] && !pList["fo:page-height"])
149 		pList.insert("fo:page-height", pList["svg:height"]->clone());
150 	if (pList["fo:page-height"] && getInchValue(*pList["fo:page-height"], height) && height>mfMaxHeight)
151 		mfMaxHeight=height;
152 
153 	// generate drawing-page style
154 	// TODO: This is duplicated in OdpGenerator.cxx. Refactor.
155 	if (!pList["draw:fill"]) // it will be removed in a moment again...
156 		pList.insert("draw:fill", "none");
157 	librevenge::RVNGPropertyList drawingPageStyle;
158 	mFillManager.addProperties(pList, drawingPageStyle);
159 	if (pList["presentation:duration"])
160 		drawingPageStyle.insert("presentation:duration", pList["presentation:duration"]->getStr());
161 	else if (pList["presentation:transition-speed"])
162 		drawingPageStyle.insert("presentation:transition-speed", pList["presentation:transition-speed"]->getStr());
163 	if (pList["smil:type"])
164 		drawingPageStyle.insert("smil:type", pList["smil:type"]->getStr());
165 	if (pList["smil:subtype"])
166 		drawingPageStyle.insert("smil:subtype", pList["smil:subtype"]->getStr());
167 	librevenge::RVNGPropertyListVector drawingPageVector;
168 	drawingPageVector.append(drawingPageStyle);
169 	pList.insert("librevenge:drawing-page", drawingPageVector);
170 	// remove the drawing page props
171 	std::deque<std::string> removedKeys;
172 	librevenge::RVNGPropertyList::Iter i(pList);
173 	for (i.rewind(); i.next();)
174 	{
175 		if ((strncmp(i.key(), "draw:", 5) == 0) || (strncmp(i.key(), "smil:", 5) == 0) ||
176 		        (strncmp(i.key(), "presentation:", 13) == 0) || (strcmp(i.key(), "style:repeat") == 0))
177 			removedKeys.push_back(i.key());
178 	}
179 	for (const auto &removedKey : removedKeys)
180 		pList.remove(removedKey.c_str());
181 
182 	// do not generate footnote separator data
183 	pList.insert("librevenge:footnote", librevenge::RVNGPropertyListVector());
184 }
185 
openTextBoxFrame(const librevenge::RVNGPropertyList & propList)186 void OdpGeneratorPrivate::openTextBoxFrame(const librevenge::RVNGPropertyList &propList)
187 {
188 	librevenge::RVNGPropertyList tmpList(propList), graphicStyle;
189 	if (!propList["draw:stroke"])
190 		tmpList.insert("draw:stroke", "none");
191 	if (!propList["draw:fill"])
192 		tmpList.insert("draw:fill", "none");
193 	mGraphicManager.addGraphicProperties(tmpList, graphicStyle);
194 	GraphicStyleManager::addFrameProperties(propList, graphicStyle);
195 	librevenge::RVNGString sValue=mGraphicManager.findOrAdd
196 	                              (graphicStyle, useStyleAutomaticZone() ? Style::Z_StyleAutomatic : Style::Z_ContentAutomatic);
197 
198 	auto pDrawFrameOpenElement = std::make_shared<TagOpenElement>("draw:frame");
199 	pDrawFrameOpenElement->addAttribute("draw:style-name", sValue);
200 	pDrawFrameOpenElement->addAttribute("draw:layer", "layout");
201 
202 	if (!propList["svg:width"] && !propList["svg:height"])
203 	{
204 		pDrawFrameOpenElement->addAttribute("fo:min-width", "1in");
205 		pDrawFrameOpenElement->addAttribute("svg:width", "10in");
206 	}
207 	else
208 	{
209 		if (propList["svg:width"])
210 			pDrawFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr());
211 		if (propList["svg:height"])
212 			pDrawFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr());
213 	}
214 	static char const *attrib[]=
215 	{
216 		"fo:min-width", "fo:min-height", "fo:max-width", "fo:max-height", "fo:padding-top", "fo:padding-bottom",
217 		"fo:padding-left", "fo:padding-right", "draw:textarea-vertical-align", "draw:fill", "draw:fill-color"
218 	};
219 	for (auto &i : attrib)
220 	{
221 		if (propList[i])
222 			pDrawFrameOpenElement->addAttribute(i, propList[i]->getStr());
223 	}
224 
225 	double x = 0.0;
226 	double y = 0.0;
227 	if (propList["svg:x"])
228 		libodfgen::getInchValue(*propList["svg:x"], x);
229 	if (propList["svg:y"])
230 		libodfgen::getInchValue(*propList["svg:y"], y);
231 	double angle(propList["librevenge:rotate"] ? - M_PI * propList["librevenge:rotate"]->getDouble() / 180.0 : 0.0);
232 	if (angle < 0 || angle > 0)
233 	{
234 		// compute position: make sure that the center position remains invariant
235 		double width = 0.0;
236 		double height = 0.0;
237 		if (propList["librevenge:rotate-cx"])
238 		{
239 			getInchValue(*propList["librevenge:rotate-cx"],width);
240 			width = 2.0*(width-x);
241 		}
242 		else if (propList["svg:width"])
243 			getInchValue(*propList["svg:width"],width);
244 		if (propList["librevenge:rotate-cy"])
245 		{
246 			getInchValue(*propList["librevenge:rotate-cy"],height);
247 			height = 2.0*(height-y);
248 		}
249 		else if (propList["svg:height"])
250 			getInchValue(*propList["svg:height"],height);
251 		double deltax((width*cos(angle)+height*sin(angle)-width)/2.0);
252 		double deltay((-width*sin(angle)+height*cos(angle)-height)/2.0);
253 		x -= deltax;
254 		y -= deltay;
255 	}
256 	std::shared_ptr<librevenge::RVNGProperty> svg_x(librevenge::RVNGPropertyFactory::newInchProp(x));
257 	std::shared_ptr<librevenge::RVNGProperty> svg_y(librevenge::RVNGPropertyFactory::newInchProp(y));
258 	if (angle < 0 || angle > 0)
259 	{
260 		std::shared_ptr<librevenge::RVNGProperty> librevenge_rotate(librevenge::RVNGPropertyFactory::newDoubleProp(angle));
261 		sValue.sprintf("rotate (%s) translate(%s, %s)",
262 		               librevenge_rotate->getStr().cstr(),
263 		               svg_x->getStr().cstr(),
264 		               svg_y->getStr().cstr());
265 		pDrawFrameOpenElement->addAttribute("draw:transform", sValue);
266 	}
267 	else
268 	{
269 		if (propList["svg:x"])
270 			pDrawFrameOpenElement->addAttribute("svg:x", svg_x->getStr());
271 		if (propList["svg:y"])
272 			pDrawFrameOpenElement->addAttribute("svg:y", svg_y->getStr());
273 	}
274 	getCurrentStorage()->push_back(pDrawFrameOpenElement);
275 }
276 
closeTextBoxFrame()277 void OdpGeneratorPrivate::closeTextBoxFrame()
278 {
279 	getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:frame"));
280 }
281 
writeNotesStyles(OdfDocumentHandler * pHandler)282 void OdpGeneratorPrivate::writeNotesStyles(OdfDocumentHandler *pHandler)
283 {
284 	{
285 		librevenge::RVNGPropertyList styleProps;
286 		styleProps.insert("style:name", "PresentationNotesPage");
287 		styleProps.insert("style:family", "drawing-page");
288 
289 		pHandler->startElement("style:style", styleProps);
290 
291 		librevenge::RVNGPropertyList pageProps;
292 		pageProps.insert("presentation:display-header", "true");
293 		pageProps.insert("presentation:display-footer", "true");
294 		pageProps.insert("presentation:display-date-time", "true");
295 		pageProps.insert("presentation:display-page-number", "false");
296 
297 		pHandler->startElement("style:drawing-page-properties", pageProps);
298 		pHandler->endElement("style:drawing-page-properties");
299 
300 		pHandler->endElement("style:style");
301 	}
302 
303 	{
304 		librevenge::RVNGPropertyList styleProps;
305 		styleProps.insert("style:name", "PresentationNotesFrame");
306 		styleProps.insert("style:family", "presentation");
307 
308 		pHandler->startElement("style:style", styleProps);
309 
310 		librevenge::RVNGPropertyList graphicProps;
311 		graphicProps.insert("draw:fill", "none");
312 		graphicProps.insert("fo:min-height", "5in");
313 
314 		pHandler->startElement("style:graphic-properties", graphicProps);
315 		pHandler->endElement("style:graphic-properties");
316 
317 		librevenge::RVNGPropertyList paraProps;
318 		paraProps.insert("fo:margin-left", "0.24in");
319 		paraProps.insert("fo:margin-right", "0in");
320 		paraProps.insert("fo:text-indent", "0in");
321 
322 		pHandler->startElement("style:paragraph-properties", paraProps);
323 		pHandler->endElement("style:paragraph-properties");
324 
325 		pHandler->endElement("style:style");
326 	}
327 
328 	{
329 		librevenge::RVNGPropertyList styleProps;
330 		styleProps.insert("style:name", "PresentationNotesTextBox");
331 		styleProps.insert("style:family", "graphic");
332 
333 		pHandler->startElement("style:style", styleProps);
334 
335 		librevenge::RVNGPropertyList graphicProps;
336 		graphicProps.insert("draw:fill", "none");
337 
338 		pHandler->startElement("style:graphic-properties", graphicProps);
339 		pHandler->endElement("style:graphic-properties");
340 
341 		pHandler->endElement("style:style");
342 	}
343 }
344 
_writeSettings(OdfDocumentHandler * pHandler) const345 void OdpGeneratorPrivate::_writeSettings(OdfDocumentHandler *pHandler) const
346 {
347 	TagOpenElement("office:settings").write(pHandler);
348 
349 	TagOpenElement configItemSetOpenElement("config:config-item-set");
350 	configItemSetOpenElement.addAttribute("config:name", "ooo:view-settings");
351 	configItemSetOpenElement.write(pHandler);
352 
353 	TagOpenElement configItemOpenElement("config:config-item");
354 
355 	configItemOpenElement.addAttribute("config:name", "VisibleAreaTop");
356 	configItemOpenElement.addAttribute("config:type", "int");
357 	configItemOpenElement.write(pHandler);
358 	pHandler->characters("0");
359 	pHandler->endElement("config:config-item");
360 
361 	configItemOpenElement.addAttribute("config:name", "VisibleAreaLeft");
362 	configItemOpenElement.addAttribute("config:type", "int");
363 	configItemOpenElement.write(pHandler);
364 	pHandler->characters("0");
365 	pHandler->endElement("config:config-item");
366 
367 	configItemOpenElement.addAttribute("config:name", "VisibleAreaWidth");
368 	configItemOpenElement.addAttribute("config:type", "int");
369 	configItemOpenElement.write(pHandler);
370 	librevenge::RVNGString sWidth;
371 	sWidth.sprintf("%li", (unsigned long)(2540 * mfMaxWidth));
372 	pHandler->characters(sWidth);
373 	pHandler->endElement("config:config-item");
374 
375 	configItemOpenElement.addAttribute("config:name", "VisibleAreaHeight");
376 	configItemOpenElement.addAttribute("config:type", "int");
377 	configItemOpenElement.write(pHandler);
378 	librevenge::RVNGString sHeight;
379 	sHeight.sprintf("%li", (unsigned long)(2540 * mfMaxHeight));
380 	pHandler->characters(sHeight);
381 	pHandler->endElement("config:config-item");
382 
383 	pHandler->endElement("config:config-item-set");
384 
385 	pHandler->endElement("office:settings");
386 }
387 
_writeAutomaticStyles(OdfDocumentHandler * pHandler,OdfStreamType streamType)388 void OdpGeneratorPrivate::_writeAutomaticStyles(OdfDocumentHandler *pHandler, OdfStreamType streamType)
389 {
390 	TagOpenElement("office:automatic-styles").write(pHandler);
391 
392 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML))
393 	{
394 		mPageSpanManager.writePageStyles(pHandler, Style::Z_StyleAutomatic);
395 
396 		mSpanManager.write(pHandler, Style::Z_StyleAutomatic);
397 		mParagraphManager.write(pHandler, Style::Z_StyleAutomatic);
398 		mListManager.write(pHandler, Style::Z_StyleAutomatic);
399 		mGraphicManager.write(pHandler, Style::Z_StyleAutomatic);
400 		mNumberingManager.write(pHandler, Style::Z_StyleAutomatic);
401 		mTableManager.write(pHandler, Style::Z_StyleAutomatic, true);
402 	}
403 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML))
404 	{
405 		mPageSpanManager.writePageStyles(pHandler, Style::Z_ContentAutomatic);
406 
407 		mSpanManager.write(pHandler, Style::Z_ContentAutomatic);
408 		mParagraphManager.write(pHandler, Style::Z_ContentAutomatic);
409 		mListManager.write(pHandler, Style::Z_ContentAutomatic);
410 		mGraphicManager.write(pHandler, Style::Z_ContentAutomatic);
411 		mNumberingManager.write(pHandler, Style::Z_ContentAutomatic);
412 		mTableManager.write(pHandler, Style::Z_ContentAutomatic, true);
413 	}
414 
415 	// checkme: do we want to write in the Z_ContentAutomatic or in Z_StyleAutomatic
416 	writeNotesStyles(pHandler);
417 
418 	pHandler->endElement("office:automatic-styles");
419 }
420 
_writeStyles(OdfDocumentHandler * pHandler)421 void OdpGeneratorPrivate::_writeStyles(OdfDocumentHandler *pHandler)
422 {
423 	TagOpenElement("office:styles").write(pHandler);
424 	mPageSpanManager.writePageStyles(pHandler, Style::Z_Style);
425 
426 	mParagraphManager.write(pHandler, Style::Z_Style);
427 	mSpanManager.write(pHandler, Style::Z_Style);
428 	mListManager.write(pHandler, Style::Z_Style);
429 	mFillManager.write(pHandler);
430 	mGraphicManager.write(pHandler, Style::Z_Style);
431 	pHandler->endElement("office:styles");
432 }
433 
writeTargetDocument(OdfDocumentHandler * pHandler,OdfStreamType streamType)434 bool OdpGeneratorPrivate::writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType)
435 {
436 	if (streamType == ODF_MANIFEST_XML)
437 	{
438 		pHandler->startDocument();
439 		TagOpenElement manifestElement("manifest:manifest");
440 		manifestElement.addAttribute("xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0");
441 		manifestElement.write(pHandler);
442 
443 		TagOpenElement mainFile("manifest:file-entry");
444 		mainFile.addAttribute("manifest:media-type", "application/vnd.oasis.opendocument.presentation");
445 		mainFile.addAttribute("manifest:full-path", "/");
446 		mainFile.write(pHandler);
447 		TagCloseElement("manifest:file-entry").write(pHandler);
448 		appendFilesInManifest(pHandler);
449 
450 		TagCloseElement("manifest:manifest").write(pHandler);
451 		pHandler->endDocument();
452 		return true;
453 	}
454 
455 	pHandler->startDocument();
456 
457 	std::string const documentType=getDocumentType(streamType);
458 	TagOpenElement docContentPropList(documentType.c_str());
459 	docContentPropList.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
460 	docContentPropList.addAttribute("xmlns:presentation", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0");
461 	docContentPropList.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0");
462 	docContentPropList.addAttribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0");
463 	docContentPropList.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
464 	docContentPropList.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
465 	docContentPropList.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/");
466 	docContentPropList.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
467 	docContentPropList.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
468 	docContentPropList.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
469 	docContentPropList.addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
470 	docContentPropList.addAttribute("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
471 	docContentPropList.addAttribute("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0");
472 	// WARNING: this is not ODF!
473 	docContentPropList.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office");
474 	docContentPropList.addAttribute("xmlns:officeooo", "http://openoffice.org/2009/office");
475 	docContentPropList.addAttribute("xmlns:anim","urn:oasis:names:tc:opendocument:xmlns:animation:1.0");
476 	docContentPropList.addAttribute("xmlns:smil","urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0");
477 	docContentPropList.addAttribute("office:version", "1.0", true);
478 	if (streamType == ODF_FLAT_XML)
479 		docContentPropList.addAttribute("office:mimetype", "application/vnd.oasis.opendocument.presentation");
480 	docContentPropList.write(pHandler);
481 
482 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_META_XML))
483 		writeDocumentMetaData(pHandler);
484 
485 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_SETTINGS_XML))
486 		_writeSettings(pHandler);
487 
488 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML) || (streamType == ODF_STYLES_XML))
489 	{
490 		TagOpenElement("office:font-face-decls").write(pHandler);
491 		mFontManager.write(pHandler, Style::Z_Font);
492 		TagCloseElement("office:font-face-decls").write(pHandler);
493 	}
494 
495 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML))
496 		_writeStyles(pHandler);
497 
498 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML) || (streamType == ODF_STYLES_XML))
499 		_writeAutomaticStyles(pHandler, streamType);
500 
501 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_STYLES_XML))
502 	{
503 		TagOpenElement("office:master-styles").write(pHandler);
504 		mPageSpanManager.writeMasterPages(pHandler);
505 		appendLayersMasterStyles(pHandler);
506 		pHandler->endElement("office:master-styles");
507 	}
508 
509 	if ((streamType == ODF_FLAT_XML) || (streamType == ODF_CONTENT_XML))
510 	{
511 		TagOpenElement("office:body").write(pHandler);
512 		TagOpenElement("office:presentation").write(pHandler);
513 		sendStorage(mpBodyStorage.get(), pHandler);
514 		pHandler->endElement("office:presentation");
515 		pHandler->endElement("office:body");
516 	}
517 
518 	pHandler->endElement(documentType.c_str());
519 
520 	pHandler->endDocument();
521 	return true;
522 }
523 
OdpGenerator()524 OdpGenerator::OdpGenerator(): mpImpl(new OdpGeneratorPrivate)
525 {
526 }
527 
~OdpGenerator()528 OdpGenerator::~OdpGenerator()
529 {
530 	delete mpImpl;
531 }
532 
addDocumentHandler(OdfDocumentHandler * pHandler,const OdfStreamType streamType)533 void OdpGenerator::addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType)
534 {
535 	if (mpImpl)
536 		mpImpl->addDocumentHandler(pHandler, streamType);
537 }
538 
getObjectNames() const539 librevenge::RVNGStringVector OdpGenerator::getObjectNames() const
540 {
541 	if (mpImpl)
542 		return mpImpl->getObjectNames();
543 	return librevenge::RVNGStringVector();
544 }
545 
getObjectContent(librevenge::RVNGString const & objectName,OdfDocumentHandler * pHandler)546 bool OdpGenerator::getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler)
547 {
548 	if (!mpImpl)
549 		return false;
550 	return mpImpl->getObjectContent(objectName, pHandler);
551 }
552 
startDocument(const librevenge::RVNGPropertyList & propList)553 void OdpGenerator::startDocument(const librevenge::RVNGPropertyList &propList)
554 {
555 	mpImpl->appendBodySettings(propList);
556 }
557 
endDocument()558 void OdpGenerator::endDocument()
559 {
560 #ifdef MULTIPAGE_WORKAROUND
561 	if (mpImpl->miPageIndex>1)
562 		mpImpl->getPageSpanManager().resetPageSizeAndMargins(mpImpl->mfMaxWidth, mpImpl->mfMaxHeight);
563 #endif
564 	// Write out the collected document
565 	mpImpl->writeTargetDocuments();
566 }
567 
setDocumentMetaData(const librevenge::RVNGPropertyList & propList)568 void OdpGenerator::setDocumentMetaData(const librevenge::RVNGPropertyList &propList)
569 {
570 	mpImpl->setDocumentMetaData(propList);
571 }
572 
defineEmbeddedFont(const librevenge::RVNGPropertyList & propList)573 void OdpGenerator::defineEmbeddedFont(const librevenge::RVNGPropertyList &propList)
574 {
575 	mpImpl->defineEmbeddedFont(propList);
576 }
577 
startSlide(const librevenge::RVNGPropertyList & propList)578 void OdpGenerator::startSlide(const librevenge::RVNGPropertyList &propList)
579 {
580 	librevenge::RVNGPropertyList pList(propList);
581 
582 	mpImpl->mpCurrentPageSpan=nullptr;
583 	if (!mpImpl->mpCurrentPageSpan)
584 	{
585 		mpImpl->updatePageSpanPropertiesToCreatePage(pList);
586 		mpImpl->mpCurrentPageSpan=mpImpl->getPageSpanManager().add(pList);
587 	}
588 	++mpImpl->miPageIndex;
589 	librevenge::RVNGString pageName;
590 	if (propList["draw:name"])
591 		pageName.appendEscapedXML(propList["draw:name"]->getStr());
592 	else
593 		pageName.sprintf("page%i", mpImpl->miPageIndex);
594 	auto pDrawPageOpenElement = std::make_shared<TagOpenElement>("draw:page");
595 	pDrawPageOpenElement->addAttribute("draw:name", pageName);
596 	pDrawPageOpenElement->addAttribute("draw:style-name", mpImpl->mpCurrentPageSpan->getDrawingName());
597 	pDrawPageOpenElement->addAttribute("draw:master-page-name", mpImpl->mpCurrentPageSpan->getMasterName());
598 	mpImpl->getCurrentStorage()->push_back(pDrawPageOpenElement);
599 }
600 
endSlide()601 void OdpGenerator::endSlide()
602 {
603 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:page"));
604 }
605 
startMasterSlide(const librevenge::RVNGPropertyList & propList)606 void OdpGenerator::startMasterSlide(const librevenge::RVNGPropertyList &propList)
607 {
608 	if (mpImpl->inMasterPage())
609 	{
610 		ODFGEN_DEBUG_MSG(("OdpGenerator::startMasterSlide oops a master page is already started\n"));
611 		return;
612 	}
613 	mpImpl->startMasterPage(propList);
614 	bool ok=mpImpl->inMasterPage() && propList["librevenge:master-page-name"];
615 	if (ok)
616 	{
617 		librevenge::RVNGPropertyList pList(propList);
618 		mpImpl->updatePageSpanPropertiesToCreatePage(pList);
619 
620 		PageSpan *pageSpan=mpImpl->getPageSpanManager().add(pList, true);
621 		if (pageSpan)
622 		{
623 			auto pMasterElements = std::make_shared<libodfgen::DocumentElementVector>();
624 			pageSpan->setMasterContent(pMasterElements);
625 			mpImpl->pushStorage(pMasterElements);
626 		}
627 		else
628 			ok=false;
629 	}
630 	if (!ok)
631 	{
632 		ODFGEN_DEBUG_MSG(("OdpGenerator::startMasterSlide creation of the master page has failed\n"));
633 		mpImpl->pushStorage(std::shared_ptr<libodfgen::DocumentElementVector>(&mpImpl->mDummyMasterSlideStorage, libodfgen::DummyDeleter()));
634 	}
635 }
636 
endMasterSlide()637 void OdpGenerator::endMasterSlide()
638 {
639 	if (!mpImpl->inMasterPage())
640 	{
641 		ODFGEN_DEBUG_MSG(("OdpGenerator::endMasterSlide: find no opend master page\n"));
642 		return;
643 	}
644 	mpImpl->popStorage();
645 	mpImpl->endMasterPage();
646 	mpImpl->mDummyMasterSlideStorage.clear();
647 }
648 
setStyle(const librevenge::RVNGPropertyList & propList)649 void OdpGenerator::setStyle(const librevenge::RVNGPropertyList &propList)
650 {
651 	mpImpl->defineGraphicStyle(propList);
652 }
653 
setSlideTransition(const librevenge::RVNGPropertyList &)654 void OdpGenerator::setSlideTransition(const librevenge::RVNGPropertyList &/*propList*/)
655 {
656 	// TODO: implement me
657 }
658 
startLayer(const librevenge::RVNGPropertyList &)659 void OdpGenerator::startLayer(const librevenge::RVNGPropertyList & /* propList */)
660 {
661 }
662 
endLayer()663 void OdpGenerator::endLayer()
664 {
665 }
666 
drawRectangle(const librevenge::RVNGPropertyList & propList)667 void OdpGenerator::drawRectangle(const librevenge::RVNGPropertyList &propList)
668 {
669 	mpImpl->drawRectangle(propList);
670 }
671 
drawEllipse(const librevenge::RVNGPropertyList & propList)672 void OdpGenerator::drawEllipse(const librevenge::RVNGPropertyList &propList)
673 {
674 	mpImpl->drawEllipse(propList);
675 }
676 
drawPolyline(const librevenge::RVNGPropertyList & propList)677 void OdpGenerator::drawPolyline(const librevenge::RVNGPropertyList &propList)
678 {
679 	mpImpl->drawPolySomething(propList, false);
680 }
681 
drawPolygon(const librevenge::RVNGPropertyList & propList)682 void OdpGenerator::drawPolygon(const librevenge::RVNGPropertyList &propList)
683 {
684 	mpImpl->drawPolySomething(propList, true);
685 }
686 
drawPath(const librevenge::RVNGPropertyList & propList)687 void OdpGenerator::drawPath(const librevenge::RVNGPropertyList &propList)
688 {
689 	mpImpl->drawPath(propList);
690 }
691 
drawGraphicObject(const librevenge::RVNGPropertyList & propList)692 void OdpGenerator::drawGraphicObject(const librevenge::RVNGPropertyList &propList)
693 {
694 	if (!propList["librevenge:xlink"] || propList["librevenge:xlink"]->getStr().empty())
695 	{
696 		if (!propList["librevenge:mime-type"] || propList["librevenge:mime-type"]->getStr().len() <= 0)
697 			return;
698 		if (!propList["office:binary-data"])
699 			return;
700 	}
701 	if (!propList["svg:x"] || !propList["svg:y"] || !propList["svg:width"] || !propList["svg:height"])
702 		return;
703 
704 	bool flipX(propList["draw:mirror-horizontal"] && propList["draw:mirror-horizontal"]->getInt());
705 	bool flipY(propList["draw:mirror-vertical"] && propList["draw:mirror-vertical"]->getInt());
706 
707 	librevenge::RVNGPropertyList style=mpImpl->getGraphicStyle();
708 	if ((flipX && !flipY) || (!flipX && flipY))
709 		style.insert("style:mirror", "horizontal");
710 	else
711 		style.insert("style:mirror", "none");
712 	if (propList["fo:clip"])
713 		style.insert("fo:clip", propList["fo:clip"]->getStr());
714 	if (propList["draw:color-mode"])
715 		style.insert("draw:color-mode", propList["draw:color-mode"]->getStr());
716 	if (propList["draw:luminance"])
717 		style.insert("draw:luminance", propList["draw:luminance"]->getStr());
718 	if (propList["draw:contrast"])
719 		style.insert("draw:contrast", propList["draw:contrast"]->getStr());
720 	if (propList["draw:gamma"])
721 		style.insert("draw:gamma", propList["draw:gamma"]->getStr());
722 	if (propList["draw:red"])
723 		style.insert("draw:red", propList["draw:red"]->getStr());
724 	if (propList["draw:green"])
725 		style.insert("draw:green", propList["draw:green"]->getStr());
726 	if (propList["draw:blue"])
727 		style.insert("draw:blue", propList["draw:blue"]->getStr());
728 
729 	double x, y;
730 	double height, width;
731 	getInchValue(*propList["svg:x"], x);
732 	getInchValue(*propList["svg:y"], y);
733 	getInchValue(*propList["svg:height"], height);
734 	getInchValue(*propList["svg:width"], width);
735 
736 	if (flipY)
737 	{
738 		x += width;
739 		y += height;
740 		width *= -1.0;
741 		height *= -1.0;
742 	}
743 
744 	double angle(propList["librevenge:rotate"] ? - M_PI * propList["librevenge:rotate"]->getDouble() / 180.0 : 0.0);
745 	if (angle < 0 || angle > 0)
746 	{
747 		double deltax((width*cos(angle)+height*sin(angle)-width)/2.0);
748 		double deltay((-width*sin(angle)+height*cos(angle)-height)/2.0);
749 		x -= deltax;
750 		y -= deltay;
751 	}
752 
753 	librevenge::RVNGPropertyList framePropList;
754 
755 	framePropList.insert("svg:x", x);
756 	framePropList.insert("svg:y", y);
757 	framePropList.insert("svg:height", height);
758 	framePropList.insert("svg:width", width);
759 
760 	auto pDrawFrameElement = std::make_shared<TagOpenElement>("draw:frame");
761 
762 	librevenge::RVNGPropertyList finalStyle;
763 	mpImpl->getGraphicManager().addGraphicProperties(style, finalStyle);
764 	pDrawFrameElement->addAttribute
765 	("draw:style-name", mpImpl->getGraphicManager().findOrAdd
766 	 (finalStyle, mpImpl->useStyleAutomaticZone() ? Style::Z_StyleAutomatic : Style::Z_ContentAutomatic));
767 
768 	pDrawFrameElement->addAttribute("svg:height", framePropList["svg:height"]->getStr());
769 	pDrawFrameElement->addAttribute("svg:width", framePropList["svg:width"]->getStr());
770 
771 	if (angle < 0 || angle > 0)
772 	{
773 		framePropList.insert("librevenge:rotate", angle, librevenge::RVNG_GENERIC);
774 		librevenge::RVNGString sValue;
775 		sValue.sprintf("rotate (%s) translate(%s, %s)",
776 		               framePropList["librevenge:rotate"]->getStr().cstr(),
777 		               framePropList["svg:x"]->getStr().cstr(),
778 		               framePropList["svg:y"]->getStr().cstr());
779 		pDrawFrameElement->addAttribute("draw:transform", sValue);
780 	}
781 	else
782 	{
783 		pDrawFrameElement->addAttribute("svg:x", framePropList["svg:x"]->getStr());
784 		pDrawFrameElement->addAttribute("svg:y", framePropList["svg:y"]->getStr());
785 	}
786 	mpImpl->getCurrentStorage()->push_back(pDrawFrameElement);
787 
788 	mpImpl->insertBinaryObject(propList);
789 
790 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:frame"));
791 }
792 
drawConnector(const librevenge::RVNGPropertyList & propList)793 void OdpGenerator::drawConnector(const librevenge::RVNGPropertyList &propList)
794 {
795 	mpImpl->drawConnector(propList);
796 }
797 
startEmbeddedGraphics(const librevenge::RVNGPropertyList &)798 void OdpGenerator::startEmbeddedGraphics(const librevenge::RVNGPropertyList &)
799 {
800 }
801 
endEmbeddedGraphics()802 void OdpGenerator::endEmbeddedGraphics()
803 {
804 }
805 
openGroup(const librevenge::RVNGPropertyList & propList)806 void OdpGenerator::openGroup(const librevenge::RVNGPropertyList &propList)
807 {
808 	mpImpl->openGroup(propList);
809 }
810 
closeGroup()811 void OdpGenerator::closeGroup()
812 {
813 	mpImpl->closeGroup();
814 }
815 
startTextObject(const librevenge::RVNGPropertyList & propList)816 void OdpGenerator::startTextObject(const librevenge::RVNGPropertyList &propList)
817 {
818 	mpImpl->openTextBoxFrame(propList);
819 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagOpenElement>("draw:text-box"));
820 	mpImpl->mState.mbIsTextBox = true;
821 	mpImpl->pushListState();
822 }
823 
endTextObject()824 void OdpGenerator::endTextObject()
825 {
826 	if (!mpImpl->mState.mbIsTextBox)
827 		return;
828 
829 	mpImpl->popListState();
830 	mpImpl->mState.mbIsTextBox = false;
831 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:text-box"));
832 	mpImpl->closeTextBoxFrame();
833 }
834 
defineParagraphStyle(const librevenge::RVNGPropertyList & propList)835 void OdpGenerator::defineParagraphStyle(const librevenge::RVNGPropertyList &propList)
836 {
837 	mpImpl->defineParagraphStyle(propList);
838 }
839 
openParagraph(const librevenge::RVNGPropertyList & propList)840 void OdpGenerator::openParagraph(const librevenge::RVNGPropertyList &propList)
841 {
842 	mpImpl->openParagraph(propList);
843 }
844 
closeParagraph()845 void OdpGenerator::closeParagraph()
846 {
847 	mpImpl->closeParagraph();
848 }
849 
defineCharacterStyle(const librevenge::RVNGPropertyList & propList)850 void OdpGenerator::defineCharacterStyle(const librevenge::RVNGPropertyList &propList)
851 {
852 	mpImpl->defineCharacterStyle(propList);
853 }
854 
openSpan(const librevenge::RVNGPropertyList & propList)855 void OdpGenerator::openSpan(const librevenge::RVNGPropertyList &propList)
856 {
857 	mpImpl->openSpan(propList);
858 }
859 
closeSpan()860 void OdpGenerator::closeSpan()
861 {
862 	mpImpl->closeSpan();
863 }
864 
openLink(const librevenge::RVNGPropertyList & propList)865 void OdpGenerator::openLink(const librevenge::RVNGPropertyList &propList)
866 {
867 	mpImpl->openLink(propList);
868 }
869 
closeLink()870 void OdpGenerator::closeLink()
871 {
872 	mpImpl->closeLink();
873 }
874 
insertText(const librevenge::RVNGString & text)875 void OdpGenerator::insertText(const librevenge::RVNGString &text)
876 {
877 	mpImpl->insertText(text);
878 }
879 
insertTab()880 void OdpGenerator::insertTab()
881 {
882 	mpImpl->insertTab();
883 }
884 
insertSpace()885 void OdpGenerator::insertSpace()
886 {
887 	mpImpl->insertSpace();
888 }
889 
insertLineBreak()890 void OdpGenerator::insertLineBreak()
891 {
892 	mpImpl->insertLineBreak();
893 }
894 
insertField(const librevenge::RVNGPropertyList & propList)895 void OdpGenerator::insertField(const librevenge::RVNGPropertyList &propList)
896 {
897 	mpImpl->insertField(propList);
898 }
899 
openOrderedListLevel(const librevenge::RVNGPropertyList & propList)900 void OdpGenerator::openOrderedListLevel(const librevenge::RVNGPropertyList &propList)
901 {
902 	mpImpl->openListLevel(propList, true);
903 }
904 
openUnorderedListLevel(const librevenge::RVNGPropertyList & propList)905 void OdpGenerator::openUnorderedListLevel(const librevenge::RVNGPropertyList &propList)
906 {
907 	mpImpl->openListLevel(propList, false);
908 }
909 
closeOrderedListLevel()910 void OdpGenerator::closeOrderedListLevel()
911 {
912 	mpImpl->closeListLevel();
913 }
914 
closeUnorderedListLevel()915 void OdpGenerator::closeUnorderedListLevel()
916 {
917 	mpImpl->closeListLevel();
918 }
919 
openListElement(const librevenge::RVNGPropertyList & propList)920 void OdpGenerator::openListElement(const librevenge::RVNGPropertyList &propList)
921 {
922 	mpImpl->openListElement(propList);
923 }
924 
closeListElement()925 void OdpGenerator::closeListElement()
926 {
927 	mpImpl->closeListElement();
928 }
929 
startTableObject(const librevenge::RVNGPropertyList & propList)930 void OdpGenerator::startTableObject(const librevenge::RVNGPropertyList &propList)
931 {
932 	if (mpImpl->mState.mInComment)
933 		return;
934 	mpImpl->pushListState();
935 
936 	// table must be inside a frame
937 	auto pFrameOpenElement = std::make_shared<TagOpenElement>("draw:frame");
938 
939 	pFrameOpenElement->addAttribute("draw:style-name", "standard");
940 	if (propList["svg:x"])
941 		pFrameOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr());
942 	if (propList["svg:y"])
943 		pFrameOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr());
944 	if (propList["svg:width"])
945 		pFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr());
946 	if (propList["svg:height"])
947 		pFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr());
948 
949 	mpImpl->getCurrentStorage()->push_back(pFrameOpenElement);
950 	mpImpl->openTable(propList);
951 }
952 
endTableObject()953 void OdpGenerator::endTableObject()
954 {
955 	if (mpImpl->mState.mInComment)
956 		return;
957 	mpImpl->closeTable();
958 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:frame"));
959 	mpImpl->popListState();
960 }
961 
openTableRow(const librevenge::RVNGPropertyList & propList)962 void OdpGenerator::openTableRow(const librevenge::RVNGPropertyList &propList)
963 {
964 	if (mpImpl->mState.mInComment)
965 		return;
966 	mpImpl->openTableRow(propList, true);
967 }
968 
closeTableRow()969 void OdpGenerator::closeTableRow()
970 {
971 	if (mpImpl->mState.mInComment)
972 		return;
973 	mpImpl->closeTableRow();
974 }
975 
openTableCell(const librevenge::RVNGPropertyList & propList)976 void OdpGenerator::openTableCell(const librevenge::RVNGPropertyList &propList)
977 {
978 	if (mpImpl->mState.mInComment)
979 		return;
980 
981 	if (mpImpl->mState.mTableCellOpened)
982 	{
983 		ODFGEN_DEBUG_MSG(("a table cell in a table cell?!\n"));
984 		return;
985 	}
986 
987 	librevenge::RVNGPropertyList pList(propList);
988 	pList.insert("fo:padding", "0.0382in");
989 	pList.insert("draw:fill", "none");
990 	pList.insert("draw:textarea-horizontal-align", "center");
991 
992 	if (pList["fo:background-color"])
993 	{
994 		pList.insert("draw:fill", "solid");
995 		pList.insert("draw:fill-color", pList["fo:background-color"]->getStr());
996 	}
997 	if (!propList["fo:border"])
998 		pList.insert("fo:border", "0.03pt solid #000000");
999 	mpImpl->mState.mTableCellOpened = mpImpl->openTableCell(pList);
1000 }
1001 
closeTableCell()1002 void OdpGenerator::closeTableCell()
1003 {
1004 	if (mpImpl->mState.mInComment)
1005 		return;
1006 
1007 	if (!mpImpl->mState.mTableCellOpened)
1008 	{
1009 		ODFGEN_DEBUG_MSG(("no table cell is opened\n"));
1010 		return;
1011 	}
1012 
1013 	mpImpl->closeTableCell();
1014 	mpImpl->mState.mTableCellOpened = false;
1015 }
1016 
insertCoveredTableCell(const librevenge::RVNGPropertyList & propList)1017 void OdpGenerator::insertCoveredTableCell(const librevenge::RVNGPropertyList &propList)
1018 {
1019 	if (mpImpl->mState.mInComment)
1020 		return;
1021 
1022 	mpImpl->insertCoveredTableCell(propList);
1023 }
1024 
startComment(const librevenge::RVNGPropertyList & propList)1025 void OdpGenerator::startComment(const librevenge::RVNGPropertyList &propList)
1026 {
1027 	if (mpImpl->mState.mInComment)
1028 	{
1029 		ODFGEN_DEBUG_MSG(("a comment within a comment?!\n"));
1030 		return;
1031 	}
1032 	mpImpl->pushListState();
1033 	mpImpl->mState.mInComment = true;
1034 
1035 	auto const commentElement = std::make_shared<TagOpenElement>("officeooo:annotation");
1036 
1037 	// position & size
1038 	double val;
1039 	if (propList["svg:x"] && getInchValue(*propList["svg:x"], val))
1040 		commentElement->addAttribute("svg:x", doubleToString(72 * val));
1041 	if (propList["svg:y"] && getInchValue(*propList["svg:y"], val))
1042 		commentElement->addAttribute("svg:y", doubleToString(72 * val));
1043 	if (propList["svg:width"] && getInchValue(*propList["svg:width"], val))
1044 		commentElement->addAttribute("svg:width", doubleToString(72 * val));
1045 	if (propList["svg:height"] && getInchValue(*propList["svg:height"], val))
1046 		commentElement->addAttribute("svg:height", doubleToString(72 * val));
1047 
1048 	mpImpl->getCurrentStorage()->push_back(commentElement);
1049 }
1050 
endComment()1051 void OdpGenerator::endComment()
1052 {
1053 	if (!mpImpl->mState.mInComment)
1054 	{
1055 		ODFGEN_DEBUG_MSG(("there is no comment to close\n"));
1056 		return;
1057 	}
1058 	mpImpl->popListState();
1059 	mpImpl->mState.mInComment = false;
1060 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("officeooo:annotation"));
1061 }
1062 
startNotes(const librevenge::RVNGPropertyList &)1063 void OdpGenerator::startNotes(const librevenge::RVNGPropertyList &/*propList*/)
1064 {
1065 	if (mpImpl->mState.mInNotes)
1066 	{
1067 		ODFGEN_DEBUG_MSG(("notes in notes?!\n"));
1068 		return;
1069 	}
1070 
1071 	mpImpl->pushListState();
1072 	auto const notesElement = std::make_shared<TagOpenElement>("presentation:notes");
1073 	notesElement->addAttribute("draw:style-name", "PresentationNotesPage");
1074 
1075 	mpImpl->getCurrentStorage()->push_back(notesElement);
1076 
1077 	auto const thumbnailElement = std::make_shared<TagOpenElement>("draw:page-thumbnail");
1078 	thumbnailElement->addAttribute("draw:layer", "layout");
1079 	thumbnailElement->addAttribute("presentation:class", "page");
1080 	// TODO: should the dimensions be hardcoded? If not, where
1081 	// should they come from?
1082 	thumbnailElement->addAttribute("svg:width", "5.5in");
1083 	thumbnailElement->addAttribute("svg:height", "4.12in");
1084 	thumbnailElement->addAttribute("svg:x", "1.5in");
1085 	thumbnailElement->addAttribute("svg:y", "0.84in");
1086 	librevenge::RVNGString pageNumber;
1087 	pageNumber.sprintf("%i", mpImpl->miPageIndex);
1088 	thumbnailElement->addAttribute("draw:page-number", pageNumber);
1089 
1090 	mpImpl->getCurrentStorage()->push_back(thumbnailElement);
1091 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:page-thumbnail"));
1092 
1093 	auto const frameElement = std::make_shared<TagOpenElement>("draw:frame");
1094 	frameElement->addAttribute("presentation:style-name", "PresentationNotesFrame");
1095 	frameElement->addAttribute("draw:layer", "layout");
1096 	frameElement->addAttribute("presentation:class", "notes");
1097 	frameElement->addAttribute("svg:width", "6.8in");
1098 	frameElement->addAttribute("svg:height", "4.95in");
1099 	frameElement->addAttribute("svg:x", "0.85in");
1100 	frameElement->addAttribute("svg:y", "5.22in");
1101 
1102 	mpImpl->getCurrentStorage()->push_back(frameElement);
1103 
1104 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagOpenElement>("draw:text-box"));
1105 
1106 	mpImpl->mState.mInNotes = true;
1107 }
1108 
endNotes()1109 void OdpGenerator::endNotes()
1110 {
1111 	if (!mpImpl->mState.mInNotes)
1112 	{
1113 		ODFGEN_DEBUG_MSG(("no notes opened\n"));
1114 		return;
1115 	}
1116 	mpImpl->popListState();
1117 	mpImpl->mState.mInNotes = false;
1118 
1119 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:text-box"));
1120 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("draw:frame"));
1121 	mpImpl->getCurrentStorage()->push_back(std::make_shared<TagCloseElement>("presentation:notes"));
1122 }
1123 
defineChartStyle(const librevenge::RVNGPropertyList &)1124 void OdpGenerator::defineChartStyle(const librevenge::RVNGPropertyList &)
1125 {
1126 	// TODO: implement me
1127 }
1128 
openChart(const librevenge::RVNGPropertyList &)1129 void OdpGenerator::openChart(const librevenge::RVNGPropertyList &)
1130 {
1131 	// TODO: implement me
1132 }
1133 
closeChart()1134 void OdpGenerator::closeChart()
1135 {
1136 	// TODO: implement me
1137 }
1138 
openChartTextObject(const librevenge::RVNGPropertyList &)1139 void OdpGenerator::openChartTextObject(const librevenge::RVNGPropertyList &)
1140 {
1141 	// TODO: implement me
1142 }
1143 
closeChartTextObject()1144 void OdpGenerator::closeChartTextObject()
1145 {
1146 	// TODO: implement me
1147 }
1148 
openChartPlotArea(const librevenge::RVNGPropertyList &)1149 void OdpGenerator::openChartPlotArea(const librevenge::RVNGPropertyList &)
1150 {
1151 	// TODO: implement me
1152 }
1153 
closeChartPlotArea()1154 void OdpGenerator::closeChartPlotArea()
1155 {
1156 	// TODO: implement me
1157 }
1158 
insertChartAxis(const librevenge::RVNGPropertyList &)1159 void OdpGenerator::insertChartAxis(const librevenge::RVNGPropertyList &)
1160 {
1161 	// TODO: implement me
1162 }
1163 
openChartSeries(const librevenge::RVNGPropertyList &)1164 void OdpGenerator::openChartSeries(const librevenge::RVNGPropertyList &)
1165 {
1166 	// TODO: implement me
1167 }
1168 
closeChartSeries()1169 void OdpGenerator::closeChartSeries()
1170 {
1171 	// TODO: implement me
1172 }
1173 
openAnimationSequence(const librevenge::RVNGPropertyList &)1174 void OdpGenerator::openAnimationSequence(const librevenge::RVNGPropertyList &/*propList*/)
1175 {
1176 	// TODO: implement me
1177 }
1178 
closeAnimationSequence()1179 void OdpGenerator::closeAnimationSequence()
1180 {
1181 	// TODO: implement me
1182 }
1183 
openAnimationGroup(const librevenge::RVNGPropertyList &)1184 void OdpGenerator::openAnimationGroup(const librevenge::RVNGPropertyList &/*propList*/)
1185 {
1186 	// TODO: implement me
1187 }
1188 
closeAnimationGroup()1189 void OdpGenerator::closeAnimationGroup()
1190 {
1191 	// TODO: implement me
1192 }
1193 
openAnimationIteration(const librevenge::RVNGPropertyList &)1194 void OdpGenerator::openAnimationIteration(const librevenge::RVNGPropertyList &/*propList*/)
1195 {
1196 	// TODO: implement me
1197 }
1198 
closeAnimationIteration()1199 void OdpGenerator::closeAnimationIteration()
1200 {
1201 	// TODO: implement me
1202 }
1203 
insertMotionAnimation(const librevenge::RVNGPropertyList &)1204 void OdpGenerator::insertMotionAnimation(const librevenge::RVNGPropertyList &/*propList*/)
1205 {
1206 	// TODO: implement me
1207 }
1208 
insertColorAnimation(const librevenge::RVNGPropertyList &)1209 void OdpGenerator::insertColorAnimation(const librevenge::RVNGPropertyList &/*propList*/)
1210 {
1211 	// TODO: implement me
1212 }
1213 
insertAnimation(const librevenge::RVNGPropertyList &)1214 void OdpGenerator::insertAnimation(const librevenge::RVNGPropertyList &/*propList*/)
1215 {
1216 	// TODO: implement me
1217 }
1218 
insertEffect(const librevenge::RVNGPropertyList &)1219 void OdpGenerator::insertEffect(const librevenge::RVNGPropertyList &/*propList*/)
1220 {
1221 	// TODO: implement me
1222 }
1223 
1224 
initStateWith(OdfGenerator const & orig)1225 void OdpGenerator::initStateWith(OdfGenerator const &orig)
1226 {
1227 	mpImpl->initStateWith(orig);
1228 }
1229 
registerEmbeddedObjectHandler(const librevenge::RVNGString & mimeType,OdfEmbeddedObject objectHandler)1230 void OdpGenerator::registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler)
1231 {
1232 	mpImpl->registerEmbeddedObjectHandler(mimeType, objectHandler);
1233 }
1234 
registerEmbeddedImageHandler(const librevenge::RVNGString & mimeType,OdfEmbeddedImage imageHandler)1235 void OdpGenerator::registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler)
1236 {
1237 	mpImpl->registerEmbeddedImageHandler(mimeType, imageHandler);
1238 }
1239 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
1240