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