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) 2002-2004 William Lachance (wrlach@gmail.com)
11  * Copyright (C) 2004 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 #ifndef _ODFGENERATOR_HXX_
28 #define _ODFGENERATOR_HXX_
29 
30 #include <map>
31 #include <memory>
32 #include <set>
33 #include <stack>
34 #include <string>
35 
36 #include <librevenge/librevenge.h>
37 
38 #include "libodfgen/OdfDocumentHandler.hxx"
39 
40 #include "FilterInternal.hxx"
41 #include "FillManager.hxx"
42 #include "FontStyle.hxx"
43 #include "GraphicStyle.hxx"
44 #include "InternalHandler.hxx"
45 #include "ListStyle.hxx"
46 #include "NumberingStyle.hxx"
47 #include "PageSpan.hxx"
48 #include "TableStyle.hxx"
49 #include "TextRunStyle.hxx"
50 
51 class DocumentElement;
52 class ListStyle;
53 
54 class OdfGenerator
55 {
56 public:
57 	//! constructor
58 	OdfGenerator();
59 	//! destructor
60 	virtual ~OdfGenerator();
61 	//! retrieve data from another odfgenerator ( the list and the embedded handler)
62 	void initStateWith(OdfGenerator const &orig);
63 
64 	//
65 	// general
66 	//
67 
68 	//! returns the document type corresponding to stream type
69 	static std::string getDocumentType(OdfStreamType streamType);
70 	//! store the document meta data
71 	void setDocumentMetaData(const librevenge::RVNGPropertyList &propList);
72 	//! write the document meta data
73 	void writeDocumentMetaData(OdfDocumentHandler *pHandler);
74 
75 	/** looks if there is a vector "librevenge:childs" in propList ;
76 		if yes, goes through each child to see if some elements must
77 		be added at the beginning of the main body child: office:text,
78 		office:spreadsheet, ...
79 
80 		\note:
81 		Must be called with the argument of startDocument
82 		\par
83 		Actually, only child with "librevenge:type"
84 		"table:calculation-settings" is retrieved
85 	*/
86 	void appendBodySettings(const librevenge::RVNGPropertyList &propList);
87 
88 	//
89 	// document handler
90 	//
91 
92 	//! basic container used to store objects of not flat odf files
93 	struct ObjectContainer
94 	{
95 		//! constructor
ObjectContainerOdfGenerator::ObjectContainer96 		ObjectContainer(librevenge::RVNGString const &type, bool isDir)
97 			: mType(type), mIsDir(isDir), mStorage(), mInternalHandler(&mStorage)
98 		{
99 		}
100 		//! destructor
101 		~ObjectContainer();
102 		//! the file type
103 		librevenge::RVNGString mType;
104 		//! true if the file is not a plain file
105 		bool mIsDir;
106 		//! the contain storage
107 		libodfgen::DocumentElementVector mStorage;
108 		//! the handler
109 		InternalHandler mInternalHandler;
110 	private:
111 		ObjectContainer(ObjectContainer const &orig);
112 		ObjectContainer &operator=(ObjectContainer const &orig);
113 	};
114 	/** creates a new object */
115 	ObjectContainer &createObjectFile(librevenge::RVNGString const &objectName,
116 	                                  librevenge::RVNGString const &objectType,
117 	                                  bool isDir=false);
118 	/** returns the list created embedded object (needed to create chart) */
119 	librevenge::RVNGStringVector getObjectNames() const;
120 	/** retrieve an embedded object content via a document handler */
121 	bool getObjectContent(librevenge::RVNGString const &objectName, OdfDocumentHandler *pHandler);
122 
123 	//! add a document handler
124 	void addDocumentHandler(OdfDocumentHandler *pHandler, const OdfStreamType streamType);
125 	//! calls writeTargetDocument on each document handler
126 	void writeTargetDocuments();
127 	//! appends local files in the manifest
128 	void appendFilesInManifest(OdfDocumentHandler *pHandler);
129 	//! a virtual function used to write final data
130 	virtual bool writeTargetDocument(OdfDocumentHandler *pHandler, OdfStreamType streamType) = 0;
131 
132 	//
133 	// embedded image/object handler
134 	//
135 
136 	//! register an embedded object handler
137 	void registerEmbeddedObjectHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedObject objectHandler);
138 	//! register an embedded image handler
139 	void registerEmbeddedImageHandler(const librevenge::RVNGString &mimeType, OdfEmbeddedImage imageHandler);
140 	//! returns a embedded object handler if it exists
141 	OdfEmbeddedObject findEmbeddedObjectHandler(const librevenge::RVNGString &mimeType) const;
142 	//! returns a embedded image handler if it exists
143 	OdfEmbeddedImage findEmbeddedImageHandler(const librevenge::RVNGString &mimeType) const;
144 
145 	//! append layer in master styles
146 	void appendLayersMasterStyles(OdfDocumentHandler *pHandler);
147 
148 
149 	//
150 	// storage
151 	//
152 
153 	//! returns the current storage
getCurrentStorage()154 	const std::shared_ptr<libodfgen::DocumentElementVector> &getCurrentStorage()
155 	{
156 		return mpCurrentStorage;
157 	}
158 	//! push a storage
159 	void pushStorage(const std::shared_ptr<libodfgen::DocumentElementVector> &newStorage);
160 	/** pop a storage */
161 	bool popStorage();
162 	//! returns the body storage
getBodyStorage()163 	const std::shared_ptr<libodfgen::DocumentElementVector> &getBodyStorage()
164 	{
165 		return mpBodyStorage;
166 	}
167 	//! returns the meta data storage
getMetaDataStorage()168 	libodfgen::DocumentElementVector &getMetaDataStorage()
169 	{
170 		return mMetaDataStorage;
171 	}
172 	//! write the storage data to a document handler
173 	static void sendStorage(libodfgen::DocumentElementVector const *storage, OdfDocumentHandler *pHandler);
174 
175 	// page, header/footer, master page
176 
177 	//! return the page span manager
getPageSpanManager()178 	PageSpanManager &getPageSpanManager()
179 	{
180 		return mPageSpanManager;
181 	}
182 
183 	//! starts a header/footer page.
184 	void startHeaderFooter(bool header, const librevenge::RVNGPropertyList &propList);
185 	//! ends a header/footer page
186 	void endHeaderFooter();
187 	//! returns if we are in a master page
inHeaderFooter() const188 	bool inHeaderFooter() const
189 	{
190 		return mbInHeaderFooter;
191 	}
192 
193 	//! starts a master page.
194 	void startMasterPage(const librevenge::RVNGPropertyList &propList);
195 	//! ends a master page
196 	void endMasterPage();
197 	//! returns if we are in a master page
inMasterPage() const198 	bool inMasterPage() const
199 	{
200 		return mbInMasterPage;
201 	}
202 
203 	//! returns if we must store the automatic style in the style or in the content xml zones
useStyleAutomaticZone() const204 	bool useStyleAutomaticZone() const
205 	{
206 		return mbInHeaderFooter || mbInMasterPage;
207 	}
208 
209 	//
210 	// basic to the font/paragraph/span manager
211 	//
212 
213 	void insertTab();
214 	void insertSpace();
215 	void insertLineBreak(bool forceParaClose=false);
216 	void insertField(const librevenge::RVNGPropertyList &field);
217 	void insertText(const librevenge::RVNGString &text);
218 
219 	//! open a link
220 	void openLink(const librevenge::RVNGPropertyList &propList);
221 	//! close a link
222 	void closeLink();
223 
224 	//! return the font manager
getFontManager()225 	FontStyleManager &getFontManager()
226 	{
227 		return mFontManager;
228 	}
229 	//! return the numbering manager
getNumberingManager()230 	NumberingManager &getNumberingManager()
231 	{
232 		return mNumberingManager;
233 	}
234 
235 	//! define a character style
236 	void defineCharacterStyle(const librevenge::RVNGPropertyList &propList);
237 	//! open a span
238 	void openSpan(const librevenge::RVNGPropertyList &propList);
239 	//! close a span
240 	void closeSpan();
241 
242 	//! define a paragraph style
243 	void defineParagraphStyle(const librevenge::RVNGPropertyList &propList);
244 	//! open a paragraph
245 	void openParagraph(const librevenge::RVNGPropertyList &propList);
246 	//! close a paragraph
247 	void closeParagraph();
248 
249 	//
250 	// list function
251 	//
252 
253 	/// pop the list state (if possible)
254 	void popListState();
255 	/// push the list state by adding an empty value
256 	void pushListState();
257 
258 	/// call to open a list level
259 	void openListLevel(const librevenge::RVNGPropertyList &propList, bool ordered);
260 	/// call to close a list level
261 	void closeListLevel();
262 	/// call to open a list element
263 	void openListElement(const librevenge::RVNGPropertyList &propList);
264 	/// call to close a list element
265 	void closeListElement();
266 
267 	//
268 	// table
269 	//
270 
271 	/// call to open a table
272 	void openTable(const librevenge::RVNGPropertyList &propList);
273 	/// call to close a table
274 	void closeTable();
275 	/// call to open a table row
276 	bool openTableRow(const librevenge::RVNGPropertyList &propList, bool compatibleOdp=false);
277 	/// call to close a table row
278 	void closeTableRow();
279 	/// returns true if a table row is opened
280 	bool isInTableRow(bool &inHeaderRow) const;
281 	/// call to open a table cell
282 	bool openTableCell(const librevenge::RVNGPropertyList &propList);
283 	/// call to close a table cell
284 	void closeTableCell();
285 	void insertCoveredTableCell(const librevenge::RVNGPropertyList &propList);
286 
287 	//
288 	// frame/group/layer
289 	//
290 
291 	/// call to open a frame
292 	void openFrame(const librevenge::RVNGPropertyList &propList);
293 	/// call to close a frame
294 	void closeFrame();
295 	//! return a frame id corresponding to a name ( or a new frame id)
296 	unsigned getFrameId(librevenge::RVNGString name="");
297 	/// call to open a group
298 	void openGroup(const librevenge::RVNGPropertyList &propList);
299 	/// call to close a group
300 	void closeGroup();
301 	/// call to open layer.
302 	void openLayer(const librevenge::RVNGPropertyList &propList);
303 	/// call to close a layer
304 	void closeLayer();
305 	/// return the layer name: either propList[draw:layer] if it exists or the current layer name
306 	librevenge::RVNGString getLayerName(const librevenge::RVNGPropertyList &propList) const;
307 
308 	//
309 	// image
310 	//
311 
312 	//! inserts a binary object
313 	void insertBinaryObject(const librevenge::RVNGPropertyList &propList);
314 
315 	//
316 	// equation
317 	//
318 
319 	//! inserts a binary object
320 	void insertEquation(const librevenge::RVNGPropertyList &propList);
321 
322 	//
323 	// graphic
324 	//
325 
326 	//! call to define a graphic style
327 	void defineGraphicStyle(const librevenge::RVNGPropertyList &propList);
328 	//! returns the last graphic style (REMOVEME)
getGraphicStyle() const329 	librevenge::RVNGPropertyList const &getGraphicStyle() const
330 	{
331 		return mGraphicStyle;
332 	}
333 
334 	//! call to draw an ellipse
335 	void drawEllipse(const librevenge::RVNGPropertyList &propList);
336 	//! call to draw a path
337 	void drawPath(const librevenge::RVNGPropertyList &propList);
338 	//! call to draw a polygon or a polyline
339 	void drawPolySomething(const librevenge::RVNGPropertyList &vertices, bool isClosed);
340 	//! call to draw a rectangle
341 	void drawRectangle(const librevenge::RVNGPropertyList &propList);
342 	//! call to draw a connector
343 	void drawConnector(const librevenge::RVNGPropertyList &propList);
344 
345 	//
346 	// chart
347 	//
348 
349 	//! define a chart style
350 	void defineChartStyle(const librevenge::RVNGPropertyList &propList);
351 
352 	//
353 	// font
354 	//
355 
356 	//! add embedded font
357 	void defineEmbeddedFont(const librevenge::RVNGPropertyList &propList);
358 
359 protected:
360 
361 	//
362 	// frame/graphic
363 	//
364 
365 	//! returns the list of properties which must be add to a frame, shape, ...
366 	void addFrameProperties(const librevenge::RVNGPropertyList &propList, TagOpenElement &element) const;
367 	//! call to draw a path
368 	void drawPath(const librevenge::RVNGPropertyListVector &path, const librevenge::RVNGPropertyList &propList);
369 	//! returns the current graphic style name ( MODIFYME)
370 	librevenge::RVNGString getCurrentGraphicStyleName(const librevenge::RVNGPropertyList &shapeList);
371 	//! returns the current graphic style name ( MODIFYME)
372 	librevenge::RVNGString getCurrentGraphicStyleName();
373 
374 	//! unescape all xml caracters (replacing them by their unicode representation)
375 	void unescapeXML(const char *s, const unsigned long sz, librevenge::RVNGString &res);
376 
377 	// the current set of elements that we're writing to
378 	std::shared_ptr<libodfgen::DocumentElementVector> mpCurrentStorage;
379 	// the stack of all storage
380 	std::stack<std::shared_ptr<libodfgen::DocumentElementVector>> mStorageStack;
381 	// the meta data elements
382 	libodfgen::DocumentElementVector mMetaDataStorage;
383 	// content elements
384 	std::shared_ptr<libodfgen::DocumentElementVector> mpBodyStorage;
385 
386 	// page span manager
387 	PageSpanManager mPageSpanManager;
388 	// font manager
389 	FontStyleManager mFontManager;
390 	// fill manager
391 	FillManager mFillManager;
392 	// graphic manager
393 	GraphicStyleManager mGraphicManager;
394 	// span manager
395 	SpanStyleManager mSpanManager;
396 	// paragraph manager
397 	ParagraphStyleManager mParagraphManager;
398 	// numbering manager
399 	NumberingManager mNumberingManager;
400 	// list manager
401 	ListManager mListManager;
402 	// table manager
403 	TableManager mTableManager;
404 
405 	// a flag to know if we are in a header/footer zone
406 	bool mbInHeaderFooter;
407 
408 	// a flag to know if we are in a master page
409 	bool mbInMasterPage;
410 
411 	// id to span map
412 	std::map<int, librevenge::RVNGPropertyList> mIdSpanMap;
413 	// id to span name map
414 	std::map<int, librevenge::RVNGString> mIdSpanNameMap;
415 	// the last span name
416 	librevenge::RVNGString mLastSpanName;
417 
418 	// id to paragraph map
419 	std::map<int, librevenge::RVNGPropertyList> mIdParagraphMap;
420 	// id to paragraph name map
421 	std::map<int, librevenge::RVNGString> mIdParagraphNameMap;
422 	// the last paragraph name
423 	librevenge::RVNGString mLastParagraphName;
424 
425 	// the number of created frame
426 	unsigned miFrameNumber;
427 	// the list of frame seens
428 	std::map<librevenge::RVNGString, unsigned > mFrameNameIdMap;
429 
430 	// the layer name stack
431 	std::stack<librevenge::RVNGString> mLayerNameStack;
432 	// the list of layer (final name)
433 	std::set<librevenge::RVNGString> mLayerNameSet;
434 	// the layer original name to final name
435 	std::map<librevenge::RVNGString, librevenge::RVNGString> mLayerNameMap;
436 
437 	// the last graphic style
438 	librevenge::RVNGPropertyList mGraphicStyle;
439 
440 	// id to chart map
441 	std::map<int, librevenge::RVNGPropertyList> mIdChartMap;
442 	// id to chart name map
443 	std::map<int, librevenge::RVNGString> mIdChartNameMap;
444 
445 	//
446 	// handler and/or object creation
447 	//
448 
449 	// the document handlers
450 	std::map<OdfStreamType, OdfDocumentHandler *> mDocumentStreamHandlers;
451 
452 	// the number of created object
453 	int miObjectNumber;
454 	// name to object map
455 	std::map<librevenge::RVNGString, std::unique_ptr<ObjectContainer>> mNameObjectMap;
456 
457 	// embedded image handlers
458 	std::map<librevenge::RVNGString, OdfEmbeddedImage > mImageHandlers;
459 	// embedded object handlers
460 	std::map<librevenge::RVNGString, OdfEmbeddedObject > mObjectHandlers;
461 
462 	/// stack of bool to know if we close a single paragraph or a heading paragraph
463 	std::stack<bool> mParagraphHeadingStack;
464 
465 	//! map xml caracter to unicode
466 	std::map<std::string, unsigned long> mXmlToUnicodeMap;
467 private:
468 	// copy constructor (unimplemented)
469 	OdfGenerator(OdfGenerator const &);
470 	// copy operator (unimplemented)
471 	OdfGenerator &operator=(OdfGenerator const &);
472 };
473 #endif
474 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
475