LCOV - code coverage report
Current view: top level - libreoffice/writerperfect/source/filter - OdtGenerator.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 731 0.0 %
Date: 2012-12-27 Functions: 0 70 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* OdtGenerator: Collects sections and runs of text from a
       3             :  * wordperfect file (and styles to go along with them) and writes them
       4             :  * to a Writer target document
       5             :  *
       6             :  * This Source Code Form is subject to the terms of the Mozilla Public
       7             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       8             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       9             :  *
      10             :  * For further information visit http://libwpd.sourceforge.net
      11             :  */
      12             : 
      13             : /* "This product is not manufactured, approved, or supported by
      14             :  * Corel Corporation or Corel Corporation Limited."
      15             :  */
      16             : 
      17             : #include <libwpd/libwpd.h>
      18             : #include <vector>
      19             : #include <map>
      20             : #include <stack>
      21             : #include <string>
      22             : 
      23             : #include "OdtGenerator.hxx"
      24             : #include "DocumentElement.hxx"
      25             : #include "TextRunStyle.hxx"
      26             : #include "FontStyle.hxx"
      27             : #include "ListStyle.hxx"
      28             : #include "PageSpan.hxx"
      29             : #include "SectionStyle.hxx"
      30             : #include "TableStyle.hxx"
      31             : #include "FilterInternal.hxx"
      32             : #include "InternalHandler.hxx"
      33             : 
      34             : // the state we use for writing the final document
      35             : typedef struct _WriterDocumentState WriterDocumentState;
      36             : struct _WriterDocumentState
      37             : {
      38             :     _WriterDocumentState();
      39             : 
      40             :     bool mbFirstElement;
      41             :     bool mbFirstParagraphInPageSpan;
      42             :     bool mbInFakeSection;
      43             :     bool mbListElementOpenedAtCurrentLevel;
      44             :     bool mbTableCellOpened;
      45             :     bool mbHeaderRow;
      46             :     bool mbInNote;
      47             :     bool mbInTextBox;
      48             :     bool mbInFrame;
      49             : };
      50             : 
      51             : // list state
      52             : typedef struct _WriterListState WriterListState;
      53           0 : struct _WriterListState
      54             : {
      55             :     _WriterListState();
      56             : 
      57             :     ListStyle *mpCurrentListStyle;
      58             :     unsigned int miCurrentListLevel;
      59             :     unsigned int miLastListLevel;
      60             :     unsigned int miLastListNumber;
      61             :     bool mbListContinueNumbering;
      62             :     bool mbListElementParagraphOpened;
      63             :     std::stack<bool> mbListElementOpened;
      64             : };
      65             : 
      66             : enum WriterListType { unordered, ordered };
      67             : 
      68           0 : _WriterDocumentState::_WriterDocumentState() :
      69             :     mbFirstElement(true),
      70             :     mbFirstParagraphInPageSpan(true),
      71             :     mbInFakeSection(false),
      72             :     mbListElementOpenedAtCurrentLevel(false),
      73             :     mbTableCellOpened(false),
      74             :     mbHeaderRow(false),
      75             :     mbInNote(false),
      76             :     mbInTextBox(false),
      77           0 :     mbInFrame(false)
      78             : {
      79           0 : }
      80             : 
      81           0 : _WriterListState::_WriterListState() :
      82             :     mpCurrentListStyle(0),
      83             :     miCurrentListLevel(0),
      84             :     miLastListLevel(0),
      85             :     miLastListNumber(0),
      86             :     mbListContinueNumbering(false),
      87             :     mbListElementParagraphOpened(false),
      88           0 :     mbListElementOpened()
      89             : {
      90           0 : }
      91             : 
      92             : class OdtGeneratorPrivate
      93             : {
      94             : public:
      95             :     OdtGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType);
      96             :     ~OdtGeneratorPrivate();
      97             :     bool _writeTargetDocument(OdfDocumentHandler *pHandler);
      98             :     void _writeDefaultStyles(OdfDocumentHandler *pHandler);
      99             :     void _writeMasterPages(OdfDocumentHandler *pHandler);
     100             :     void _writePageLayouts(OdfDocumentHandler *pHandler);
     101             : 
     102             :     void _openListLevel(TagOpenElement *pListLevelOpenElement);
     103             :     void _closeListLevel();
     104             : 
     105             :     OdfEmbeddedObject _findEmbeddedObjectHandler(const WPXString &mimeType);
     106             :     OdfEmbeddedImage _findEmbeddedImageHandler(const WPXString &mimeType);
     107             : 
     108             :     OdfDocumentHandler *mpHandler;
     109             :     bool mbUsed; // whether or not it has been before (you can only use me once!)
     110             : 
     111             :     std::stack<WriterDocumentState> mWriterDocumentStates;
     112             : 
     113             :     std::stack<WriterListState> mWriterListStates;
     114             : 
     115             :     // paragraph styles
     116             :     ParagraphStyleManager mParagraphManager;
     117             : 
     118             :     // span styles
     119             :     SpanStyleManager mSpanManager;
     120             : 
     121             :     // font styles
     122             :     FontStyleManager mFontManager;
     123             : 
     124             :     // section styles
     125             :     std::vector<SectionStyle *> mSectionStyles;
     126             : 
     127             :     // table styles
     128             :     std::vector<TableStyle *> mTableStyles;
     129             : 
     130             :     // frame styles
     131             :     std::vector<DocumentElement *> mFrameStyles;
     132             : 
     133             :     std::vector<DocumentElement *> mFrameAutomaticStyles;
     134             : 
     135             :     // embedded object handlers
     136             :     std::map<WPXString, OdfEmbeddedObject, ltstr > mObjectHandlers;
     137             :     std::map<WPXString, OdfEmbeddedImage, ltstr > mImageHandlers;
     138             : 
     139             :     // metadata
     140             :     std::vector<DocumentElement *> mMetaData;
     141             : 
     142             :     // list styles
     143             :     unsigned int miNumListStyles;
     144             : 
     145             :     // content elements
     146             :     std::vector<DocumentElement *> mBodyElements;
     147             :     // the current set of elements that we're writing to
     148             :     std::vector<DocumentElement *> * mpCurrentContentElements;
     149             : 
     150             :     // page state
     151             :     std::vector<PageSpan *> mPageSpans;
     152             :     PageSpan *mpCurrentPageSpan;
     153             :     int miNumPageStyles;
     154             : 
     155             :     // list styles
     156             :     std::vector<ListStyle *> mListStyles;
     157             : 
     158             :     // object state
     159             :     unsigned miObjectNumber;
     160             : 
     161             :     // table state
     162             :     TableStyle *mpCurrentTableStyle;
     163             : 
     164             :     const OdfStreamType mxStreamType;
     165             : 
     166             :     const char *mpPassword;
     167             : 
     168             : };
     169             : 
     170           0 : OdtGeneratorPrivate::OdtGeneratorPrivate(OdfDocumentHandler *pHandler, const OdfStreamType streamType) :
     171             :     mpHandler(pHandler),
     172             :     mbUsed(false),
     173             :     mWriterDocumentStates(),
     174             :     mWriterListStates(),
     175             :     mParagraphManager(), mSpanManager(), mFontManager(),
     176             :     mSectionStyles(), mTableStyles(), mFrameStyles(), mFrameAutomaticStyles(),
     177             :     mObjectHandlers(), mImageHandlers(), mMetaData(),
     178             :     miNumListStyles(0),
     179             :     mBodyElements(),
     180             :     mpCurrentContentElements(&mBodyElements),
     181             :     mPageSpans(),
     182             :     mpCurrentPageSpan(0),
     183             :     miNumPageStyles(0),
     184             :     mListStyles(),
     185             :     miObjectNumber(0),
     186             :     mpCurrentTableStyle(0),
     187             :     mxStreamType(streamType),
     188           0 :     mpPassword(0)
     189             : {
     190           0 :     mWriterDocumentStates.push(WriterDocumentState());
     191           0 :     mWriterListStates.push(WriterListState());
     192           0 : }
     193             : 
     194           0 : OdtGeneratorPrivate::~OdtGeneratorPrivate()
     195             : {
     196             :     // clean up the mess we made
     197             :     WRITER_DEBUG_MSG(("WriterWordPerfect: Cleaning up our mess..\n"));
     198             : 
     199             :     WRITER_DEBUG_MSG(("Destroying the body elements\n"));
     200           0 :     for (std::vector<DocumentElement *>::iterator iterBody = mBodyElements.begin(); iterBody != mBodyElements.end(); ++iterBody)
     201             :     {
     202           0 :         delete (*iterBody);
     203           0 :         (*iterBody) = 0;
     204             :     }
     205             : 
     206           0 :     mParagraphManager.clean();
     207           0 :     mSpanManager.clean();
     208           0 :     mFontManager.clean();
     209             : 
     210           0 :     for (std::vector<ListStyle *>::iterator iterListStyles = mListStyles.begin();
     211           0 :             iterListStyles != mListStyles.end(); ++iterListStyles)
     212             :     {
     213           0 :         delete(*iterListStyles);
     214             :     }
     215           0 :     for (std::vector<SectionStyle *>::iterator iterSectionStyles = mSectionStyles.begin();
     216           0 :             iterSectionStyles != mSectionStyles.end(); ++iterSectionStyles)
     217             :     {
     218           0 :         delete(*iterSectionStyles);
     219             :     }
     220           0 :     for (std::vector<TableStyle *>::iterator iterTableStyles = mTableStyles.begin();
     221           0 :             iterTableStyles != mTableStyles.end(); ++iterTableStyles)
     222             :     {
     223           0 :         delete((*iterTableStyles));
     224             :     }
     225             : 
     226           0 :     for (std::vector<PageSpan *>::iterator iterPageSpans = mPageSpans.begin();
     227           0 :             iterPageSpans != mPageSpans.end(); ++iterPageSpans)
     228             :     {
     229           0 :         delete(*iterPageSpans);
     230             :     }
     231           0 :     for (std::vector<DocumentElement *>::iterator iterFrameStyles = mFrameStyles.begin();
     232           0 :             iterFrameStyles != mFrameStyles.end(); ++iterFrameStyles)
     233             :     {
     234           0 :         delete(*iterFrameStyles);
     235             :     }
     236           0 :     for (std::vector<DocumentElement *>::iterator iterFrameAutomaticStyles = mFrameAutomaticStyles.begin();
     237           0 :             iterFrameAutomaticStyles != mFrameAutomaticStyles.end(); ++iterFrameAutomaticStyles)
     238             :     {
     239           0 :         delete(*iterFrameAutomaticStyles);
     240             :     }
     241           0 :     for (std::vector<DocumentElement *>::iterator iterMetaData = mMetaData.begin();
     242           0 :             iterMetaData != mMetaData.end(); ++iterMetaData)
     243             :     {
     244           0 :         delete(*iterMetaData);
     245             :     }
     246           0 : }
     247             : 
     248           0 : OdfEmbeddedObject OdtGeneratorPrivate::_findEmbeddedObjectHandler(const WPXString &mimeType)
     249             : {
     250           0 :     std::map<WPXString, OdfEmbeddedObject, ltstr>::iterator i = mObjectHandlers.find(mimeType);
     251           0 :     if (i != mObjectHandlers.end())
     252           0 :         return i->second;
     253             : 
     254           0 :     return 0;
     255             : }
     256             : 
     257           0 : OdfEmbeddedImage OdtGeneratorPrivate::_findEmbeddedImageHandler(const WPXString &mimeType)
     258             : {
     259           0 :     std::map<WPXString, OdfEmbeddedImage, ltstr>::iterator i = mImageHandlers.find(mimeType);
     260           0 :     if (i != mImageHandlers.end())
     261           0 :         return i->second;
     262             : 
     263           0 :     return 0;
     264             : }
     265             : 
     266           0 : OdtGenerator::OdtGenerator(OdfDocumentHandler *pHandler, const OdfStreamType streamType) :
     267           0 :     mpImpl(new OdtGeneratorPrivate(pHandler, streamType))
     268             : {
     269           0 : }
     270             : 
     271           0 : OdtGenerator::~OdtGenerator()
     272             : {
     273           0 :     if (mpImpl)
     274           0 :         delete mpImpl;
     275           0 : }
     276             : 
     277           0 : void OdtGeneratorPrivate::_writeDefaultStyles(OdfDocumentHandler *pHandler)
     278             : {
     279           0 :     TagOpenElement("office:styles").write(pHandler);
     280             : 
     281           0 :     TagOpenElement defaultParagraphStyleOpenElement("style:default-style");
     282           0 :     defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph");
     283           0 :     defaultParagraphStyleOpenElement.write(pHandler);
     284             : 
     285           0 :     TagOpenElement defaultParagraphStylePropertiesOpenElement("style:paragraph-properties");
     286           0 :     defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5in");
     287           0 :     defaultParagraphStylePropertiesOpenElement.write(pHandler);
     288           0 :     TagCloseElement defaultParagraphStylePropertiesCloseElement("style:paragraph-properties");
     289           0 :     defaultParagraphStylePropertiesCloseElement.write(pHandler);
     290             : 
     291           0 :     pHandler->endElement("style:default-style");
     292             : 
     293           0 :     TagOpenElement defaultTableRowStyleOpenElement("style:default-style");
     294           0 :     defaultTableRowStyleOpenElement.addAttribute("style:family", "table-row");
     295           0 :     defaultTableRowStyleOpenElement.write(pHandler);
     296             : 
     297           0 :     TagOpenElement defaultTableRowPropertiesOpenElement("style:table-row-properties");
     298           0 :     defaultTableRowPropertiesOpenElement.addAttribute("fo:keep-together", "auto");
     299           0 :     defaultTableRowPropertiesOpenElement.write(pHandler);
     300             : 
     301           0 :     pHandler->endElement("style:table-row-properties");
     302           0 :     pHandler->endElement("style:default-style");
     303             : 
     304           0 :     TagOpenElement standardStyleOpenElement("style:style");
     305           0 :     standardStyleOpenElement.addAttribute("style:name", "Standard");
     306           0 :     standardStyleOpenElement.addAttribute("style:family", "paragraph");
     307           0 :     standardStyleOpenElement.addAttribute("style:class", "text");
     308           0 :     standardStyleOpenElement.write(pHandler);
     309             : 
     310           0 :     pHandler->endElement("style:style");
     311             : 
     312           0 :     TagOpenElement textBodyStyleOpenElement("style:style");
     313           0 :     textBodyStyleOpenElement.addAttribute("style:name", "Text_Body");
     314           0 :     textBodyStyleOpenElement.addAttribute("style:display-name", "Text Body");
     315           0 :     textBodyStyleOpenElement.addAttribute("style:family", "paragraph");
     316           0 :     textBodyStyleOpenElement.addAttribute("style:parent-style-name", "Standard");
     317           0 :     textBodyStyleOpenElement.addAttribute("style:class", "text");
     318           0 :     textBodyStyleOpenElement.write(pHandler);
     319             : 
     320           0 :     pHandler->endElement("style:style");
     321             : 
     322           0 :     TagOpenElement tableContentsStyleOpenElement("style:style");
     323           0 :     tableContentsStyleOpenElement.addAttribute("style:name", "Table_Contents");
     324           0 :     tableContentsStyleOpenElement.addAttribute("style:display-name", "Table Contents");
     325           0 :     tableContentsStyleOpenElement.addAttribute("style:family", "paragraph");
     326           0 :     tableContentsStyleOpenElement.addAttribute("style:parent-style-name", "Text_Body");
     327           0 :     tableContentsStyleOpenElement.addAttribute("style:class", "extra");
     328           0 :     tableContentsStyleOpenElement.write(pHandler);
     329             : 
     330           0 :     pHandler->endElement("style:style");
     331             : 
     332           0 :     TagOpenElement tableHeadingStyleOpenElement("style:style");
     333           0 :     tableHeadingStyleOpenElement.addAttribute("style:name", "Table_Heading");
     334           0 :     tableHeadingStyleOpenElement.addAttribute("style:display-name", "Table Heading");
     335           0 :     tableHeadingStyleOpenElement.addAttribute("style:family", "paragraph");
     336           0 :     tableHeadingStyleOpenElement.addAttribute("style:parent-style-name", "Table_Contents");
     337           0 :     tableHeadingStyleOpenElement.addAttribute("style:class", "extra");
     338           0 :     tableHeadingStyleOpenElement.write(pHandler);
     339             : 
     340           0 :     pHandler->endElement("style:style");
     341             : 
     342           0 :     for (std::vector<DocumentElement *>::const_iterator iter = mFrameStyles.begin();
     343           0 :             iter != mFrameStyles.end(); ++iter)
     344           0 :         (*iter)->write(pHandler);
     345             : 
     346           0 :     pHandler->endElement("office:styles");
     347           0 : }
     348             : 
     349           0 : void OdtGeneratorPrivate::_writeMasterPages(OdfDocumentHandler *pHandler)
     350             : {
     351           0 :     TagOpenElement("office:master-styles").write(mpHandler);
     352           0 :     int pageNumber = 1;
     353           0 :     for (unsigned int i=0; i<mPageSpans.size(); ++i)
     354             :     {
     355             :         bool bLastPage;
     356           0 :         (i == (mPageSpans.size() - 1)) ? bLastPage = true : bLastPage = false;
     357           0 :         mPageSpans[i]->writeMasterPages(pageNumber, i, bLastPage, pHandler);
     358           0 :         pageNumber += mPageSpans[i]->getSpan();
     359             :     }
     360           0 :     pHandler->endElement("office:master-styles");
     361           0 : }
     362             : 
     363           0 : void OdtGeneratorPrivate::_writePageLayouts(OdfDocumentHandler *pHandler)
     364             : {
     365           0 :     for (unsigned int i=0; i<mPageSpans.size(); ++i)
     366             :     {
     367           0 :         mPageSpans[i]->writePageLayout(i, pHandler);
     368             :     }
     369           0 : }
     370             : 
     371           0 : bool OdtGeneratorPrivate::_writeTargetDocument(OdfDocumentHandler *pHandler)
     372             : {
     373             :     WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Printing out the header stuff..\n"));
     374             : 
     375             :     WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Start Document\n"));
     376           0 :     mpHandler->startDocument();
     377             : 
     378             :     WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: preamble\n"));
     379           0 :     WPXPropertyList docContentPropList;
     380           0 :     docContentPropList.insert("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
     381           0 :     docContentPropList.insert("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
     382           0 :     docContentPropList.insert("xmlns:dc", "http://purl.org/dc/elements/1.1/");
     383           0 :     docContentPropList.insert("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
     384           0 :     docContentPropList.insert("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
     385           0 :     docContentPropList.insert("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0");
     386           0 :     docContentPropList.insert("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
     387           0 :     docContentPropList.insert("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
     388           0 :     docContentPropList.insert("xmlns:xlink", "http://www.w3.org/1999/xlink");
     389           0 :     docContentPropList.insert("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0");
     390           0 :     docContentPropList.insert("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
     391           0 :     docContentPropList.insert("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0");
     392           0 :     docContentPropList.insert("xmlns:dr3d", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0");
     393           0 :     docContentPropList.insert("xmlns:math", "http://www.w3.org/1998/Math/MathML");
     394           0 :     docContentPropList.insert("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0");
     395           0 :     docContentPropList.insert("xmlns:script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0");
     396           0 :     docContentPropList.insert("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0");
     397           0 :     docContentPropList.insert("office:version", "1.0");
     398           0 :     if (mxStreamType == ODF_FLAT_XML)
     399             :     {
     400           0 :         docContentPropList.insert("office:mimetype", "application/vnd.oasis.opendocument.text");
     401           0 :         mpHandler->startElement("office:document", docContentPropList);
     402             :     }
     403             :     else
     404           0 :         mpHandler->startElement("office:document-content", docContentPropList);
     405             : 
     406             :     // write out the metadata
     407           0 :     TagOpenElement("office:meta").write(mpHandler);
     408           0 :     for (std::vector<DocumentElement *>::const_iterator iterMetaData = mMetaData.begin(); iterMetaData != mMetaData.end(); ++iterMetaData)
     409             :     {
     410           0 :         (*iterMetaData)->write(mpHandler);
     411             :     }
     412           0 :     mpHandler->endElement("office:meta");
     413             : 
     414             :     // write out the font styles
     415           0 :     mFontManager.writeFontsDeclaration(mpHandler);
     416             : 
     417             :     WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the styles..\n"));
     418             : 
     419             :     // write default styles
     420           0 :     _writeDefaultStyles(mpHandler);
     421             : 
     422           0 :     TagOpenElement("office:automatic-styles").write(mpHandler);
     423             : 
     424           0 :     for (std::vector<DocumentElement *>::const_iterator iterFrameAutomaticStyles = mFrameAutomaticStyles.begin();
     425           0 :             iterFrameAutomaticStyles != mFrameAutomaticStyles.end(); ++iterFrameAutomaticStyles)
     426             :     {
     427           0 :         (*iterFrameAutomaticStyles)->write(pHandler);
     428             :     }
     429             : 
     430           0 :     mFontManager.write(pHandler); // do nothing
     431           0 :     mParagraphManager.write(pHandler);
     432           0 :     mSpanManager.write(pHandler);
     433             : 
     434             :     // writing out the sections styles
     435           0 :     for (std::vector<SectionStyle *>::const_iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); ++iterSectionStyles)
     436             :     {
     437           0 :         (*iterSectionStyles)->write(pHandler);
     438             :     }
     439             : 
     440             :     // writing out the lists styles
     441           0 :     for (std::vector<ListStyle *>::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles)
     442             :     {
     443           0 :         (*iterListStyles)->write(pHandler);
     444             :     }
     445             : 
     446             :     // writing out the table styles
     447           0 :     for (std::vector<TableStyle *>::const_iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); ++iterTableStyles)
     448             :     {
     449           0 :         (*iterTableStyles)->write(pHandler);
     450             :     }
     451             : 
     452             :     // writing out the page masters
     453           0 :     _writePageLayouts(pHandler);
     454             : 
     455             : 
     456           0 :     pHandler->endElement("office:automatic-styles");
     457             : 
     458           0 :     _writeMasterPages(pHandler);
     459             : 
     460             :     WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the document..\n"));
     461             :     // writing out the document
     462           0 :     TagOpenElement("office:body").write(mpHandler);
     463           0 :     TagOpenElement("office:text").write(mpHandler);
     464             : 
     465           0 :     for (std::vector<DocumentElement *>::const_iterator iterBodyElements = mBodyElements.begin(); iterBodyElements != mBodyElements.end(); ++iterBodyElements)
     466             :     {
     467           0 :         (*iterBodyElements)->write(pHandler);
     468             :     }
     469             :     WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Finished writing all doc els..\n"));
     470             : 
     471           0 :     pHandler->endElement("office:text");
     472           0 :     pHandler->endElement("office:body");
     473           0 :     if (mxStreamType == ODF_FLAT_XML)
     474           0 :         pHandler->endElement("office:document");
     475             :     else
     476           0 :         pHandler->endElement("office:document-content");
     477             : 
     478           0 :     pHandler->endDocument();
     479             : 
     480           0 :     return true;
     481             : }
     482             : 
     483             : 
     484           0 : void OdtGenerator::setDocumentMetaData(const WPXPropertyList &propList)
     485             : {
     486           0 :     WPXPropertyList::Iter i(propList);
     487           0 :     for (i.rewind(); i.next(); )
     488             :     {
     489             :         // filter out libwpd elements
     490           0 :         if (strncmp(i.key(), "libwpd", 6) != 0 && strncmp(i.key(), "dcterms", 7) != 0)
     491             :         {
     492           0 :             mpImpl->mMetaData.push_back(new TagOpenElement(i.key()));
     493           0 :             WPXString sStringValue(i()->getStr(), true);
     494           0 :             mpImpl->mMetaData.push_back(new CharDataElement(sStringValue.cstr()));
     495           0 :             mpImpl->mMetaData.push_back(new TagCloseElement(i.key()));
     496             :         }
     497           0 :     }
     498             : 
     499           0 : }
     500             : 
     501           0 : void OdtGenerator::openPageSpan(const WPXPropertyList &propList)
     502             : {
     503           0 :     PageSpan *pPageSpan = new PageSpan(propList);
     504           0 :     mpImpl->mPageSpans.push_back(pPageSpan);
     505           0 :     mpImpl->mpCurrentPageSpan = pPageSpan;
     506           0 :     mpImpl->miNumPageStyles++;
     507             : 
     508           0 :     mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan = true;
     509           0 : }
     510             : 
     511           0 : void OdtGenerator::openHeader(const WPXPropertyList &propList)
     512             : {
     513           0 :     std::vector<DocumentElement *> * pHeaderFooterContentElements = new std::vector<DocumentElement *>;
     514             : 
     515           0 :     if (propList["libwpd:occurence"]->getStr() == "even")
     516           0 :         mpImpl->mpCurrentPageSpan->setHeaderLeftContent(pHeaderFooterContentElements);
     517             :     else
     518           0 :         mpImpl->mpCurrentPageSpan->setHeaderContent(pHeaderFooterContentElements);
     519             : 
     520           0 :     mpImpl->mpCurrentContentElements = pHeaderFooterContentElements;
     521           0 : }
     522             : 
     523           0 : void OdtGenerator::closeHeader()
     524             : {
     525           0 :     mpImpl->mpCurrentContentElements = &(mpImpl->mBodyElements);
     526           0 : }
     527             : 
     528           0 : void OdtGenerator::openFooter(const WPXPropertyList &propList)
     529             : {
     530           0 :     std::vector<DocumentElement *> * pHeaderFooterContentElements = new std::vector<DocumentElement *>;
     531             : 
     532           0 :     if (propList["libwpd:occurence"]->getStr() == "even")
     533           0 :         mpImpl->mpCurrentPageSpan->setFooterLeftContent(pHeaderFooterContentElements);
     534             :     else
     535           0 :         mpImpl->mpCurrentPageSpan->setFooterContent(pHeaderFooterContentElements);
     536             : 
     537           0 :     mpImpl->mpCurrentContentElements = pHeaderFooterContentElements;
     538           0 : }
     539             : 
     540           0 : void OdtGenerator::closeFooter()
     541             : {
     542           0 :     mpImpl->mpCurrentContentElements = &(mpImpl->mBodyElements);
     543           0 : }
     544             : 
     545           0 : void OdtGenerator::openSection(const WPXPropertyList &propList, const WPXPropertyListVector &columns)
     546             : {
     547           0 :     int iNumColumns = columns.count();
     548           0 :     double fSectionMarginLeft = 0.0;
     549           0 :     double fSectionMarginRight = 0.0;
     550           0 :     if (propList["fo:margin-left"])
     551           0 :         fSectionMarginLeft = propList["fo:margin-left"]->getDouble();
     552           0 :     if (propList["fo:margin-right"])
     553           0 :         fSectionMarginRight = propList["fo:margin-right"]->getDouble();
     554             : 
     555           0 :     if (iNumColumns > 1 || fSectionMarginLeft != 0 || fSectionMarginRight != 0)
     556             :     {
     557           0 :         WPXString sSectionName;
     558           0 :         sSectionName.sprintf("Section%i", mpImpl->mSectionStyles.size());
     559             : 
     560           0 :         SectionStyle *pSectionStyle = new SectionStyle(propList, columns, sSectionName.cstr());
     561           0 :         mpImpl->mSectionStyles.push_back(pSectionStyle);
     562             : 
     563           0 :         TagOpenElement *pSectionOpenElement = new TagOpenElement("text:section");
     564           0 :         pSectionOpenElement->addAttribute("text:style-name", pSectionStyle->getName());
     565           0 :         pSectionOpenElement->addAttribute("text:name", pSectionStyle->getName());
     566           0 :         mpImpl->mpCurrentContentElements->push_back(pSectionOpenElement);
     567             :     }
     568             :     else
     569           0 :         mpImpl->mWriterDocumentStates.top().mbInFakeSection = true;
     570           0 : }
     571             : 
     572           0 : void OdtGenerator::closeSection()
     573             : {
     574           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInFakeSection)
     575           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:section"));
     576             :     else
     577           0 :         mpImpl->mWriterDocumentStates.top().mbInFakeSection = false;
     578           0 : }
     579             : 
     580           0 : void OdtGenerator::openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops)
     581             : {
     582             :     // FIXMENOW: What happens if we open a footnote inside a table? do we then inherit the footnote's style
     583             :     // from "Table Contents"
     584             : 
     585           0 :     WPXPropertyList finalPropList(propList);
     586           0 :     if (mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan && mpImpl->mpCurrentContentElements == &(mpImpl->mBodyElements))
     587             :     {
     588           0 :         WPXString sPageStyleName;
     589           0 :         sPageStyleName.sprintf("Page_Style_%i", mpImpl->miNumPageStyles);
     590           0 :         finalPropList.insert("style:master-page-name", sPageStyleName);
     591           0 :         mpImpl->mWriterDocumentStates.top().mbFirstElement = false;
     592           0 :         mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false;
     593             :     }
     594             : 
     595           0 :     if (mpImpl->mWriterDocumentStates.top().mbTableCellOpened)
     596             :     {
     597           0 :         if (mpImpl->mWriterDocumentStates.top().mbHeaderRow)
     598           0 :             finalPropList.insert("style:parent-style-name", "Table_Heading");
     599             :         else
     600           0 :             finalPropList.insert("style:parent-style-name", "Table_Contents");
     601             :     }
     602             :     else
     603           0 :         finalPropList.insert("style:parent-style-name", "Standard");
     604             : 
     605           0 :     WPXString sName = mpImpl->mParagraphManager.findOrAdd(finalPropList, tabStops);
     606             : 
     607             :     // create a document element corresponding to the paragraph, and append it to our list of document elements
     608           0 :     TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p");
     609           0 :     pParagraphOpenElement->addAttribute("text:style-name", sName);
     610           0 :     mpImpl->mpCurrentContentElements->push_back(pParagraphOpenElement);
     611           0 : }
     612             : 
     613           0 : void OdtGenerator::closeParagraph()
     614             : {
     615           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
     616           0 : }
     617             : 
     618           0 : void OdtGenerator::openSpan(const WPXPropertyList &propList)
     619             : {
     620           0 :     if (propList["style:font-name"])
     621           0 :         mpImpl->mFontManager.findOrAdd(propList["style:font-name"]->getStr().cstr());
     622             : 
     623             :     // Get the style
     624           0 :     WPXString sName = mpImpl->mSpanManager.findOrAdd(propList);
     625             : 
     626             :     // create a document element corresponding to the paragraph, and append it to our list of document elements
     627           0 :     TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span");
     628           0 :     pSpanOpenElement->addAttribute("text:style-name", sName.cstr());
     629           0 :     mpImpl->mpCurrentContentElements->push_back(pSpanOpenElement);
     630           0 : }
     631             : 
     632           0 : void OdtGenerator::closeSpan()
     633             : {
     634           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:span"));
     635           0 : }
     636             : 
     637           0 : void OdtGenerator::defineOrderedListLevel(const WPXPropertyList &propList)
     638             : {
     639           0 :     int id = 0;
     640           0 :     if (propList["libwpd:id"])
     641           0 :         id = propList["libwpd:id"]->getInt();
     642             : 
     643           0 :     OrderedListStyle *pOrderedListStyle = 0;
     644           0 :     if (mpImpl->mWriterListStates.top().mpCurrentListStyle && mpImpl->mWriterListStates.top().mpCurrentListStyle->getListID() == id)
     645           0 :         pOrderedListStyle = static_cast<OrderedListStyle *>(mpImpl->mWriterListStates.top().mpCurrentListStyle); // FIXME: using a dynamic cast here causes oo to crash?!
     646             : 
     647             :     // this rather appalling conditional makes sure we only start a new list (rather than continue an old
     648             :     // one) if: (1) we have no prior list OR (2) the prior list is actually definitively different
     649             :     // from the list that is just being defined (listIDs differ) OR (3) we can tell that the user actually
     650             :     // is starting a new list at level 1 (and only level 1)
     651           0 :     if (pOrderedListStyle == 0 || pOrderedListStyle->getListID() != id  ||
     652           0 :             (propList["libwpd:level"] && propList["libwpd:level"]->getInt()==1 &&
     653           0 :              (propList["text:start-value"] && propList["text:start-value"]->getInt() != int(mpImpl->mWriterListStates.top().miLastListNumber+1))))
     654             :     {
     655             :         WRITER_DEBUG_MSG(("Attempting to create a new ordered list style (listid: %i)\n", id));
     656           0 :         WPXString sName;
     657           0 :         sName.sprintf("OL%i", mpImpl->miNumListStyles);
     658           0 :         mpImpl->miNumListStyles++;
     659           0 :         pOrderedListStyle = new OrderedListStyle(sName.cstr(), id);
     660           0 :         mpImpl->mListStyles.push_back(pOrderedListStyle);
     661           0 :         mpImpl->mWriterListStates.top().mpCurrentListStyle = pOrderedListStyle;
     662           0 :         mpImpl->mWriterListStates.top().mbListContinueNumbering = false;
     663           0 :         mpImpl->mWriterListStates.top().miLastListNumber = 0;
     664             :     }
     665             :     else
     666           0 :         mpImpl->mWriterListStates.top().mbListContinueNumbering = true;
     667             : 
     668             :     // Iterate through ALL list styles with the same WordPerfect list id and define a level if it is not already defined
     669             :     // This solves certain problems with lists that start and finish without reaching certain levels and then begin again
     670             :     // and reach those levels. See gradguide0405_PC.wpd in the regression suite
     671           0 :     for (std::vector<ListStyle *>::iterator iterOrderedListStyles = mpImpl->mListStyles.begin(); iterOrderedListStyles != mpImpl->mListStyles.end(); ++iterOrderedListStyles)
     672             :     {
     673           0 :         if ((* iterOrderedListStyles) && (* iterOrderedListStyles)->getListID() == id && propList["libwpd:level"])
     674           0 :             (* iterOrderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList);
     675             :     }
     676           0 : }
     677             : 
     678           0 : void OdtGenerator::defineUnorderedListLevel(const WPXPropertyList &propList)
     679             : {
     680           0 :     int id = 0;
     681           0 :     if (propList["libwpd:id"])
     682           0 :         id = propList["libwpd:id"]->getInt();
     683             : 
     684           0 :     UnorderedListStyle *pUnorderedListStyle = 0;
     685           0 :     if (mpImpl->mWriterListStates.top().mpCurrentListStyle && mpImpl->mWriterListStates.top().mpCurrentListStyle->getListID() == id)
     686           0 :         pUnorderedListStyle = static_cast<UnorderedListStyle *>(mpImpl->mWriterListStates.top().mpCurrentListStyle); // FIXME: using a dynamic cast here causes oo to crash?!
     687             : 
     688           0 :     if (pUnorderedListStyle == 0)
     689             :     {
     690             :         WRITER_DEBUG_MSG(("Attempting to create a new unordered list style (listid: %i)\n", id));
     691           0 :         WPXString sName;
     692           0 :         sName.sprintf("UL%i", mpImpl->miNumListStyles);
     693           0 :         mpImpl->miNumListStyles++;
     694           0 :         pUnorderedListStyle = new UnorderedListStyle(sName.cstr(), id);
     695           0 :         mpImpl->mListStyles.push_back(pUnorderedListStyle);
     696           0 :         mpImpl->mWriterListStates.top().mpCurrentListStyle = pUnorderedListStyle;
     697             :     }
     698             : 
     699             :     // See comment in OdtGenerator::defineOrderedListLevel
     700           0 :     for (std::vector<ListStyle *>::iterator iterUnorderedListStyles = mpImpl->mListStyles.begin(); iterUnorderedListStyles != mpImpl->mListStyles.end(); ++iterUnorderedListStyles)
     701             :     {
     702           0 :         if ((* iterUnorderedListStyles) && (* iterUnorderedListStyles)->getListID() == id && propList["libwpd:level"])
     703           0 :             (* iterUnorderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList);
     704             :     }
     705           0 : }
     706             : 
     707           0 : void OdtGenerator::openOrderedListLevel(const WPXPropertyList &)
     708             : {
     709           0 :     if (mpImpl->mWriterListStates.top().mbListElementParagraphOpened)
     710             :     {
     711           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
     712           0 :         mpImpl->mWriterListStates.top().mbListElementParagraphOpened = false;
     713             :     }
     714           0 :     TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list");
     715           0 :     mpImpl->_openListLevel(pListLevelOpenElement);
     716             : 
     717           0 :     if (mpImpl->mWriterListStates.top().mbListContinueNumbering)
     718             :     {
     719           0 :         pListLevelOpenElement->addAttribute("text:continue-numbering", "true");
     720             :     }
     721             : 
     722           0 :     mpImpl->mpCurrentContentElements->push_back(pListLevelOpenElement);
     723           0 : }
     724             : 
     725           0 : void OdtGenerator::openUnorderedListLevel(const WPXPropertyList &)
     726             : {
     727           0 :     if (mpImpl->mWriterListStates.top().mbListElementParagraphOpened)
     728             :     {
     729           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
     730           0 :         mpImpl->mWriterListStates.top().mbListElementParagraphOpened = false;
     731             :     }
     732           0 :     TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list");
     733           0 :     mpImpl->_openListLevel(pListLevelOpenElement);
     734             : 
     735           0 :     mpImpl->mpCurrentContentElements->push_back(pListLevelOpenElement);
     736           0 : }
     737             : 
     738           0 : void OdtGeneratorPrivate::_openListLevel(TagOpenElement *pListLevelOpenElement)
     739             : {
     740           0 :     if (!mWriterListStates.top().mbListElementOpened.empty() &&
     741           0 :             !mWriterListStates.top().mbListElementOpened.top())
     742             :     {
     743           0 :         mpCurrentContentElements->push_back(new TagOpenElement("text:list-item"));
     744           0 :         mWriterListStates.top().mbListElementOpened.top() = true;
     745             :     }
     746             : 
     747           0 :     mWriterListStates.top().mbListElementOpened.push(false);
     748           0 :     if (mWriterListStates.top().mbListElementOpened.size() == 1)
     749             :     {
     750           0 :         pListLevelOpenElement->addAttribute("text:style-name", mWriterListStates.top().mpCurrentListStyle->getName());
     751             :     }
     752           0 : }
     753             : 
     754           0 : void OdtGenerator::closeOrderedListLevel()
     755             : {
     756           0 :     mpImpl->_closeListLevel();
     757           0 : }
     758             : 
     759           0 : void OdtGenerator::closeUnorderedListLevel()
     760             : {
     761           0 :     mpImpl->_closeListLevel();
     762           0 : }
     763             : 
     764           0 : void OdtGeneratorPrivate::_closeListLevel()
     765             : {
     766           0 :     if (mWriterListStates.top().mbListElementOpened.top())
     767             :     {
     768           0 :         mpCurrentContentElements->push_back(new TagCloseElement("text:list-item"));
     769           0 :         mWriterListStates.top().mbListElementOpened.top() = false;
     770             :     }
     771             : 
     772           0 :     mpCurrentContentElements->push_back(new TagCloseElement("text:list"));
     773             : 
     774           0 :     if (!mWriterListStates.top().mbListElementOpened.empty())
     775             :     {
     776           0 :         mWriterListStates.top().mbListElementOpened.pop();
     777             :     }
     778           0 : }
     779             : 
     780           0 : void OdtGenerator::openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops)
     781             : {
     782           0 :     mpImpl->mWriterListStates.top().miLastListLevel = mpImpl->mWriterListStates.top().miCurrentListLevel;
     783           0 :     if (mpImpl->mWriterListStates.top().miCurrentListLevel == 1)
     784           0 :         mpImpl->mWriterListStates.top().miLastListNumber++;
     785             : 
     786           0 :     if (mpImpl->mWriterListStates.top().mbListElementOpened.top())
     787             :     {
     788           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:list-item"));
     789           0 :         mpImpl->mWriterListStates.top().mbListElementOpened.top() = false;
     790             :     }
     791             : 
     792           0 :     WPXPropertyList finalPropList(propList);
     793             : #if 0
     794             :     // this property is ignored in TextRunStyle.c++
     795             :     finalPropList.insert("style:list-style-name", mpImpl->mWriterListStates.top().mpCurrentListStyle->getName());
     796             : #endif
     797           0 :     finalPropList.insert("style:parent-style-name", "Standard");
     798           0 :     WPXString paragName = mpImpl->mParagraphManager.findOrAdd(finalPropList, tabStops);
     799             : 
     800           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:list-item"));
     801             : 
     802           0 :     TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p");
     803           0 :     pOpenListElementParagraph->addAttribute("text:style-name", paragName);
     804           0 :     mpImpl->mpCurrentContentElements->push_back(pOpenListElementParagraph);
     805             : 
     806           0 :     if (mpImpl->mpCurrentContentElements == &(mpImpl->mBodyElements))
     807           0 :         mpImpl->mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false;
     808             : 
     809           0 :     mpImpl->mWriterListStates.top().mbListElementOpened.top() = true;
     810           0 :     mpImpl->mWriterListStates.top().mbListElementParagraphOpened = true;
     811           0 :     mpImpl->mWriterListStates.top().mbListContinueNumbering = false;
     812           0 : }
     813             : 
     814           0 : void OdtGenerator::closeListElement()
     815             : {
     816             :     // this code is kind of tricky, because we don't actually close the list element (because this list element
     817             :     // could contain another list level in OOo's implementation of lists). that is done in the closeListLevel
     818             :     // code (or when we open another list element)
     819             : 
     820           0 :     if (mpImpl->mWriterListStates.top().mbListElementParagraphOpened)
     821             :     {
     822           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
     823           0 :         mpImpl->mWriterListStates.top().mbListElementParagraphOpened = false;
     824             :     }
     825           0 : }
     826             : 
     827           0 : void OdtGenerator::openFootnote(const WPXPropertyList &propList)
     828             : {
     829           0 :     mpImpl->mWriterListStates.push(WriterListState());
     830           0 :     TagOpenElement *pOpenFootNote = new TagOpenElement("text:note");
     831           0 :     pOpenFootNote->addAttribute("text:note-class", "footnote");
     832           0 :     if (propList["libwpd:number"])
     833             :     {
     834           0 :         WPXString tmpString("ftn");
     835           0 :         tmpString.append(propList["libwpd:number"]->getStr());
     836           0 :         pOpenFootNote->addAttribute("text:id", tmpString);
     837             :     }
     838           0 :     mpImpl->mpCurrentContentElements->push_back(pOpenFootNote);
     839             : 
     840           0 :     TagOpenElement *pOpenFootCitation = new TagOpenElement("text:note-citation");
     841           0 :     if (propList["text:label"])
     842             :     {
     843           0 :         WPXString tmpString(propList["text:label"]->getStr(),true);
     844           0 :         pOpenFootCitation->addAttribute("text:label", tmpString);
     845             :     }
     846           0 :     mpImpl->mpCurrentContentElements->push_back(pOpenFootCitation);
     847             : 
     848           0 :     if (propList["text:label"])
     849           0 :         mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["text:label"]->getStr().cstr()));
     850           0 :     else if (propList["libwpd:number"])
     851           0 :         mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr()));
     852           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation"));
     853             : 
     854           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:note-body"));
     855             : 
     856           0 :     mpImpl->mWriterDocumentStates.top().mbInNote = true;
     857           0 : }
     858             : 
     859           0 : void OdtGenerator::closeFootnote()
     860             : {
     861           0 :     mpImpl->mWriterDocumentStates.top().mbInNote = false;
     862           0 :     if (mpImpl->mWriterListStates.size() > 1)
     863           0 :         mpImpl->mWriterListStates.pop();
     864             : 
     865           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-body"));
     866           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note"));
     867           0 : }
     868             : 
     869           0 : void OdtGenerator::openEndnote(const WPXPropertyList &propList)
     870             : {
     871           0 :     mpImpl->mWriterListStates.push(WriterListState());
     872           0 :     TagOpenElement *pOpenEndNote = new TagOpenElement("text:note");
     873           0 :     pOpenEndNote->addAttribute("text:note-class", "endnote");
     874           0 :     if (propList["libwpd:number"])
     875             :     {
     876           0 :         WPXString tmpString("edn");
     877           0 :         tmpString.append(propList["libwpd:number"]->getStr());
     878           0 :         pOpenEndNote->addAttribute("text:id", tmpString);
     879             :     }
     880           0 :     mpImpl->mpCurrentContentElements->push_back(pOpenEndNote);
     881             : 
     882           0 :     TagOpenElement *pOpenEndCitation = new TagOpenElement("text:note-citation");
     883           0 :     if (propList["text:label"])
     884             :     {
     885           0 :         WPXString tmpString(propList["text:label"]->getStr(),true);
     886           0 :         pOpenEndCitation->addAttribute("text:label", tmpString);
     887             :     }
     888           0 :     mpImpl->mpCurrentContentElements->push_back(pOpenEndCitation);
     889             : 
     890           0 :     if (propList["text:label"])
     891           0 :         mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["text:label"]->getStr().cstr()));
     892           0 :     else if (propList["libwpd:number"])
     893           0 :         mpImpl->mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr()));
     894           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation"));
     895             : 
     896           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:note-body"));
     897             : 
     898           0 :     mpImpl->mWriterDocumentStates.top().mbInNote = true;
     899           0 : }
     900             : 
     901           0 : void OdtGenerator::closeEndnote()
     902             : {
     903           0 :     mpImpl->mWriterDocumentStates.top().mbInNote = false;
     904           0 :     if (mpImpl->mWriterListStates.size() > 1)
     905           0 :         mpImpl->mWriterListStates.pop();
     906             : 
     907           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note-body"));
     908           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:note"));
     909           0 : }
     910             : 
     911           0 : void OdtGenerator::openComment(const WPXPropertyList &)
     912             : {
     913           0 :     mpImpl->mWriterListStates.push(WriterListState());
     914           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("office:annotation"));
     915             : 
     916           0 :     mpImpl->mWriterDocumentStates.top().mbInNote = true;
     917           0 : }
     918             : 
     919           0 : void OdtGenerator::closeComment()
     920             : {
     921           0 :     mpImpl->mWriterDocumentStates.top().mbInNote = false;
     922           0 :     if (mpImpl->mWriterListStates.size() > 1)
     923           0 :         mpImpl->mWriterListStates.pop();
     924             : 
     925           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("office:annotation"));
     926           0 : }
     927             : 
     928           0 : void OdtGenerator::openTable(const WPXPropertyList &propList, const WPXPropertyListVector &columns)
     929             : {
     930           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInNote)
     931             :     {
     932           0 :         WPXString sTableName;
     933           0 :         sTableName.sprintf("Table%i", mpImpl->mTableStyles.size());
     934             : 
     935             :         // FIXME: we base the table style off of the page's margin left, ignoring (potential) wordperfect margin
     936             :         // state which is transmitted inside the page. could this lead to unacceptable behaviour?
     937             :         // WLACH_REFACTORING: characterize this behaviour, probably should nip it at the bud within libwpd
     938           0 :         TableStyle *pTableStyle = new TableStyle(propList, columns, sTableName.cstr());
     939             : 
     940           0 :         if (mpImpl->mWriterDocumentStates.top().mbFirstElement && mpImpl->mpCurrentContentElements == &(mpImpl->mBodyElements))
     941             :         {
     942           0 :             WPXString sMasterPageName("Page_Style_1");
     943           0 :             pTableStyle->setMasterPageName(sMasterPageName);
     944           0 :             mpImpl->mWriterDocumentStates.top().mbFirstElement = false;
     945             :         }
     946             : 
     947           0 :         mpImpl->mTableStyles.push_back(pTableStyle);
     948             : 
     949           0 :         mpImpl->mpCurrentTableStyle = pTableStyle;
     950             : 
     951           0 :         TagOpenElement *pTableOpenElement = new TagOpenElement("table:table");
     952             : 
     953           0 :         pTableOpenElement->addAttribute("table:name", sTableName.cstr());
     954           0 :         pTableOpenElement->addAttribute("table:style-name", sTableName.cstr());
     955           0 :         mpImpl->mpCurrentContentElements->push_back(pTableOpenElement);
     956             : 
     957           0 :         for (int i=0; i<pTableStyle->getNumColumns(); ++i)
     958             :         {
     959           0 :             TagOpenElement *pTableColumnOpenElement = new TagOpenElement("table:table-column");
     960           0 :             WPXString sColumnStyleName;
     961           0 :             sColumnStyleName.sprintf("%s.Column%i", sTableName.cstr(), (i+1));
     962           0 :             pTableColumnOpenElement->addAttribute("table:style-name", sColumnStyleName.cstr());
     963           0 :             mpImpl->mpCurrentContentElements->push_back(pTableColumnOpenElement);
     964             : 
     965           0 :             TagCloseElement *pTableColumnCloseElement = new TagCloseElement("table:table-column");
     966           0 :             mpImpl->mpCurrentContentElements->push_back(pTableColumnCloseElement);
     967           0 :         }
     968             :     }
     969           0 : }
     970             : 
     971           0 : void OdtGenerator::openTableRow(const WPXPropertyList &propList)
     972             : {
     973           0 :     if (mpImpl->mWriterDocumentStates.top().mbInNote)
     974             :         return;
     975           0 :     if (!mpImpl->mpCurrentTableStyle)
     976             :     {
     977             :         WRITER_DEBUG_MSG(("OdtGenerator::openTableRow called with no table\n"));
     978             :         return;
     979             :     }
     980           0 :     if (propList["libwpd:is-header-row"] && (propList["libwpd:is-header-row"]->getInt()))
     981             :     {
     982           0 :         mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("table:table-header-rows"));
     983           0 :         mpImpl->mWriterDocumentStates.top().mbHeaderRow = true;
     984             :     }
     985             : 
     986           0 :     WPXString sTableRowStyleName;
     987           0 :     sTableRowStyleName.sprintf("%s.Row%i", mpImpl->mpCurrentTableStyle->getName().cstr(), mpImpl->mpCurrentTableStyle->getNumTableRowStyles());
     988           0 :     TableRowStyle *pTableRowStyle = new TableRowStyle(propList, sTableRowStyleName.cstr());
     989           0 :     mpImpl->mpCurrentTableStyle->addTableRowStyle(pTableRowStyle);
     990             : 
     991           0 :     TagOpenElement *pTableRowOpenElement = new TagOpenElement("table:table-row");
     992           0 :     pTableRowOpenElement->addAttribute("table:style-name", sTableRowStyleName);
     993           0 :     mpImpl->mpCurrentContentElements->push_back(pTableRowOpenElement);
     994             : }
     995             : 
     996           0 : void OdtGenerator::closeTableRow()
     997             : {
     998           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInNote && mpImpl->mpCurrentTableStyle)
     999             :     {
    1000           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table-row"));
    1001           0 :         if (mpImpl->mWriterDocumentStates.top().mbHeaderRow)
    1002             :         {
    1003           0 :             mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table-header-rows"));
    1004           0 :             mpImpl->mWriterDocumentStates.top().mbHeaderRow = false;
    1005             :         }
    1006             :     }
    1007           0 : }
    1008             : 
    1009           0 : void OdtGenerator::openTableCell(const WPXPropertyList &propList)
    1010             : {
    1011           0 :     if (mpImpl->mWriterDocumentStates.top().mbInNote)
    1012             :         return;
    1013           0 :     if (!mpImpl->mpCurrentTableStyle)
    1014             :     {
    1015             :         WRITER_DEBUG_MSG(("OdtGenerator::openTableCell called with no table\n"));
    1016             :         return;
    1017             :     }
    1018             : 
    1019           0 :     WPXString sTableCellStyleName;
    1020           0 :     sTableCellStyleName.sprintf( "%s.Cell%i", mpImpl->mpCurrentTableStyle->getName().cstr(), mpImpl->mpCurrentTableStyle->getNumTableCellStyles());
    1021           0 :     TableCellStyle *pTableCellStyle = new TableCellStyle(propList, sTableCellStyleName.cstr());
    1022           0 :     mpImpl->mpCurrentTableStyle->addTableCellStyle(pTableCellStyle);
    1023             : 
    1024           0 :     TagOpenElement *pTableCellOpenElement = new TagOpenElement("table:table-cell");
    1025           0 :     pTableCellOpenElement->addAttribute("table:style-name", sTableCellStyleName);
    1026           0 :     if (propList["table:number-columns-spanned"])
    1027             :         pTableCellOpenElement->addAttribute("table:number-columns-spanned",
    1028           0 :                                             propList["table:number-columns-spanned"]->getStr().cstr());
    1029           0 :     if (propList["table:number-rows-spanned"])
    1030             :         pTableCellOpenElement->addAttribute("table:number-rows-spanned",
    1031           0 :                                             propList["table:number-rows-spanned"]->getStr().cstr());
    1032             :     // pTableCellOpenElement->addAttribute("table:value-type", "string");
    1033           0 :     mpImpl->mpCurrentContentElements->push_back(pTableCellOpenElement);
    1034             : 
    1035           0 :     mpImpl->mWriterDocumentStates.top().mbTableCellOpened = true;
    1036             : }
    1037             : 
    1038           0 : void OdtGenerator::closeTableCell()
    1039             : {
    1040           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInNote && mpImpl->mpCurrentTableStyle)
    1041             :     {
    1042           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table-cell"));
    1043           0 :         mpImpl->mWriterDocumentStates.top().mbTableCellOpened = false;
    1044             :     }
    1045           0 : }
    1046             : 
    1047           0 : void OdtGenerator::insertCoveredTableCell(const WPXPropertyList &)
    1048             : {
    1049           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInNote && mpImpl->mpCurrentTableStyle)
    1050             :     {
    1051           0 :         mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("table:covered-table-cell"));
    1052           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:covered-table-cell"));
    1053             :     }
    1054           0 : }
    1055             : 
    1056           0 : void OdtGenerator::closeTable()
    1057             : {
    1058           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInNote)
    1059             :     {
    1060           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("table:table"));
    1061             :     }
    1062           0 : }
    1063             : 
    1064             : 
    1065           0 : void OdtGenerator::insertTab()
    1066             : {
    1067           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:tab"));
    1068           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:tab"));
    1069           0 : }
    1070             : 
    1071           0 : void OdtGenerator::insertSpace()
    1072             : {
    1073           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:s"));
    1074           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:s"));
    1075           0 : }
    1076             : 
    1077           0 : void OdtGenerator::insertLineBreak()
    1078             : {
    1079           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("text:line-break"));
    1080           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("text:line-break"));
    1081           0 : }
    1082             : 
    1083           0 : void OdtGenerator::insertField(const WPXString &type, const WPXPropertyList &propList)
    1084             : {
    1085           0 :     if (!type.len())
    1086           0 :         return;
    1087             : 
    1088           0 :     TagOpenElement *openElement = new TagOpenElement(type);
    1089           0 :     if (type == "text:page-number")
    1090           0 :         openElement->addAttribute("text:select-page", "current");
    1091             : 
    1092           0 :     if (propList["style:num-format"])
    1093           0 :         openElement->addAttribute("style:num-format", propList["style:num-format"]->getStr());
    1094             : 
    1095           0 :     mpImpl->mpCurrentContentElements->push_back(openElement);
    1096           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement(type));
    1097             : }
    1098             : 
    1099           0 : void OdtGenerator::insertText(const WPXString &text)
    1100             : {
    1101           0 :     DocumentElement *pText = new TextElement(text);
    1102           0 :     mpImpl->mpCurrentContentElements->push_back(pText);
    1103           0 : }
    1104             : 
    1105           0 : void OdtGenerator::openFrame(const WPXPropertyList &propList)
    1106             : {
    1107           0 :     mpImpl->mWriterListStates.push(WriterListState());
    1108             : 
    1109             :     // First, let's create a Frame Style for this box
    1110           0 :     TagOpenElement *frameStyleOpenElement = new TagOpenElement("style:style");
    1111           0 :     WPXString frameStyleName;
    1112           0 :     frameStyleName.sprintf("GraphicFrame_%i", mpImpl->miObjectNumber);
    1113           0 :     frameStyleOpenElement->addAttribute("style:name", frameStyleName);
    1114           0 :     frameStyleOpenElement->addAttribute("style:family", "graphic");
    1115             : 
    1116           0 :     mpImpl->mFrameStyles.push_back(frameStyleOpenElement);
    1117             : 
    1118           0 :     TagOpenElement *frameStylePropertiesOpenElement = new TagOpenElement("style:graphic-properties");
    1119             : 
    1120           0 :     if (propList["text:anchor-type"])
    1121           0 :         frameStylePropertiesOpenElement->addAttribute("text:anchor-type", propList["text:anchor-type"]->getStr());
    1122             :     else
    1123           0 :         frameStylePropertiesOpenElement->addAttribute("text:anchor-type","paragraph");
    1124             : 
    1125           0 :     if (propList["text:anchor-page-number"])
    1126           0 :         frameStylePropertiesOpenElement->addAttribute("text:anchor-page-number", propList["text:anchor-page-number"]->getStr());
    1127             : 
    1128           0 :     if (propList["svg:x"])
    1129           0 :         frameStylePropertiesOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr());
    1130             : 
    1131           0 :     if (propList["svg:y"])
    1132           0 :         frameStylePropertiesOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr());
    1133             : 
    1134           0 :     if (propList["svg:width"])
    1135           0 :         frameStylePropertiesOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr());
    1136             : 
    1137           0 :     if (propList["svg:height"])
    1138           0 :         frameStylePropertiesOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr());
    1139             : 
    1140           0 :     if (propList["style:rel-width"])
    1141           0 :         frameStylePropertiesOpenElement->addAttribute("style:rel-width", propList["style:rel-width"]->getStr());
    1142             : 
    1143           0 :     if (propList["style:rel-height"])
    1144           0 :         frameStylePropertiesOpenElement->addAttribute("style:rel-height", propList["style:rel-height"]->getStr());
    1145             : 
    1146           0 :     if (propList["fo:max-width"])
    1147           0 :         frameStylePropertiesOpenElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr());
    1148             : 
    1149           0 :     if (propList["fo:max-height"])
    1150           0 :         frameStylePropertiesOpenElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr());
    1151             : 
    1152           0 :     if (propList["style:wrap"])
    1153           0 :         frameStylePropertiesOpenElement->addAttribute("style:wrap", propList["style:wrap"]->getStr());
    1154             : 
    1155           0 :     mpImpl->mFrameStyles.push_back(frameStylePropertiesOpenElement);
    1156             : 
    1157           0 :     mpImpl->mFrameStyles.push_back(new TagCloseElement("style:graphic-properties"));
    1158             : 
    1159           0 :     mpImpl->mFrameStyles.push_back(new TagCloseElement("style:style"));
    1160             : 
    1161             :     // Now, let's create an automatic style for this frame
    1162           0 :     TagOpenElement *frameAutomaticStyleElement = new TagOpenElement("style:style");
    1163           0 :     WPXString frameAutomaticStyleName;
    1164           0 :     frameAutomaticStyleName.sprintf("fr%i", mpImpl->miObjectNumber);
    1165           0 :     frameAutomaticStyleElement->addAttribute("style:name", frameAutomaticStyleName);
    1166           0 :     frameAutomaticStyleElement->addAttribute("style:family", "graphic");
    1167           0 :     frameAutomaticStyleElement->addAttribute("style:parent-style-name", frameStyleName);
    1168             : 
    1169           0 :     mpImpl->mFrameAutomaticStyles.push_back(frameAutomaticStyleElement);
    1170             : 
    1171           0 :     TagOpenElement *frameAutomaticStylePropertiesElement = new TagOpenElement("style:graphic-properties");
    1172           0 :     if (propList["style:horizontal-pos"])
    1173           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-pos", propList["style:horizontal-pos"]->getStr());
    1174             :     else
    1175           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-pos", "left");
    1176             : 
    1177           0 :     if (propList["style:horizontal-rel"])
    1178           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-rel", propList["style:horizontal-rel"]->getStr());
    1179             :     else
    1180           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-rel", "paragraph");
    1181             : 
    1182           0 :     if (propList["style:vertical-pos"])
    1183           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:vertical-pos", propList["style:vertical-pos"]->getStr());
    1184             :     else
    1185           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:vertical-pos", "top");
    1186             : 
    1187           0 :     if (propList["style:vertical-rel"])
    1188           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:vertical-rel", propList["style:vertical-rel"]->getStr());
    1189             :     else
    1190           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:vertical-rel", "page-content");
    1191             : 
    1192           0 :     if (propList["fo:max-width"])
    1193           0 :         frameAutomaticStylePropertiesElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr());
    1194             : 
    1195           0 :     if (propList["fo:max-height"])
    1196           0 :         frameAutomaticStylePropertiesElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr());
    1197             : 
    1198             :     // check if the frame has border, background attributes
    1199           0 :     if (propList["fo:border"])
    1200           0 :         frameAutomaticStylePropertiesElement->addAttribute("fo:border", propList["fo:border"]->getStr());
    1201           0 :     if (propList["style:border-line-width"])
    1202           0 :         frameAutomaticStylePropertiesElement->addAttribute("style:border-line-width", propList["style:border-line-width"]->getStr());
    1203           0 :     if (propList["fo:background-color"])
    1204           0 :         frameAutomaticStylePropertiesElement->addAttribute("fo:background-color", propList["fo:background-color"]->getStr());
    1205             : 
    1206           0 :     frameAutomaticStylePropertiesElement->addAttribute("draw:ole-draw-aspect", "1");
    1207             : 
    1208           0 :     mpImpl->mFrameAutomaticStyles.push_back(frameAutomaticStylePropertiesElement);
    1209             : 
    1210           0 :     mpImpl->mFrameAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties"));
    1211             : 
    1212           0 :     mpImpl->mFrameAutomaticStyles.push_back(new TagCloseElement("style:style"));
    1213             : 
    1214             :     // And write the frame itself
    1215           0 :     TagOpenElement *drawFrameOpenElement = new TagOpenElement("draw:frame");
    1216             : 
    1217           0 :     drawFrameOpenElement->addAttribute("draw:style-name", frameAutomaticStyleName);
    1218           0 :     WPXString objectName;
    1219           0 :     objectName.sprintf("Object%i", mpImpl->miObjectNumber++);
    1220           0 :     drawFrameOpenElement->addAttribute("draw:name", objectName);
    1221           0 :     if (propList["text:anchor-type"])
    1222           0 :         drawFrameOpenElement->addAttribute("text:anchor-type", propList["text:anchor-type"]->getStr());
    1223             :     else
    1224           0 :         drawFrameOpenElement->addAttribute("text:anchor-type","paragraph");
    1225             : 
    1226           0 :     if (propList["text:anchor-page-number"])
    1227           0 :         drawFrameOpenElement->addAttribute("text:anchor-page-number", propList["text:anchor-page-number"]->getStr());
    1228             : 
    1229           0 :     if (propList["svg:x"])
    1230           0 :         drawFrameOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr());
    1231             : 
    1232           0 :     if (propList["svg:y"])
    1233           0 :         drawFrameOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr());
    1234             : 
    1235           0 :     if (propList["svg:width"])
    1236           0 :         drawFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr());
    1237             : 
    1238           0 :     if (propList["svg:height"])
    1239           0 :         drawFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr());
    1240             : 
    1241           0 :     if (propList["style:rel-width"])
    1242           0 :         drawFrameOpenElement->addAttribute("style:rel-width", propList["style:rel-width"]->getStr());
    1243             : 
    1244           0 :     if (propList["style:rel-height"])
    1245           0 :         drawFrameOpenElement->addAttribute("style:rel-height", propList["style:rel-height"]->getStr());
    1246             : 
    1247           0 :     mpImpl->mpCurrentContentElements->push_back(drawFrameOpenElement);
    1248             : 
    1249           0 :     mpImpl->mWriterDocumentStates.top().mbInFrame = true;
    1250           0 : }
    1251             : 
    1252           0 : void OdtGenerator::closeFrame()
    1253             : {
    1254           0 :     if (mpImpl->mWriterListStates.size() > 1)
    1255           0 :         mpImpl->mWriterListStates.pop();
    1256             : 
    1257           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:frame"));
    1258             : 
    1259           0 :     mpImpl->mWriterDocumentStates.top().mbInFrame = false;
    1260           0 : }
    1261             : 
    1262           0 : void OdtGenerator::insertBinaryObject(const WPXPropertyList &propList, const WPXBinaryData &data)
    1263             : {
    1264           0 :     if (!data.size())
    1265           0 :         return;
    1266           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInFrame) // Embedded objects without a frame simply don't make sense for us
    1267           0 :         return;
    1268           0 :     if (!propList["libwpd:mimetype"])
    1269           0 :         return;
    1270             : 
    1271           0 :     OdfEmbeddedObject tmpObjectHandler = mpImpl->_findEmbeddedObjectHandler(propList["libwpd:mimetype"]->getStr());
    1272           0 :     OdfEmbeddedImage tmpImageHandler = mpImpl->_findEmbeddedImageHandler(propList["libwpd:mimetype"]->getStr());
    1273             : 
    1274           0 :     if (tmpObjectHandler || tmpImageHandler)
    1275             :     {
    1276           0 :         if (tmpObjectHandler)
    1277             :         {
    1278           0 :             std::vector<DocumentElement *> tmpContentElements;
    1279           0 :             InternalHandler tmpHandler(&tmpContentElements);
    1280             : 
    1281           0 :             if (tmpObjectHandler(data, &tmpHandler, ODF_FLAT_XML) && !tmpContentElements.empty())
    1282             :             {
    1283           0 :                 mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:object"));
    1284           0 :                 for (std::vector<DocumentElement *>::const_iterator iter = tmpContentElements.begin(); iter != tmpContentElements.end(); ++iter)
    1285           0 :                     mpImpl->mpCurrentContentElements->push_back(*iter);
    1286           0 :                 mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:object"));
    1287           0 :             }
    1288             :         }
    1289           0 :         if (tmpImageHandler)
    1290             :         {
    1291           0 :             WPXBinaryData output;
    1292           0 :             if (tmpImageHandler(data, output))
    1293             :             {
    1294           0 :                 mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:image"));
    1295             : 
    1296           0 :                 mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("office:binary-data"));
    1297             : 
    1298           0 :                 WPXString binaryBase64Data = output.getBase64Data();
    1299             : 
    1300           0 :                 mpImpl->mpCurrentContentElements->push_back(new CharDataElement(binaryBase64Data.cstr()));
    1301             : 
    1302           0 :                 mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("office:binary-data"));
    1303             : 
    1304           0 :                 mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:image"));
    1305           0 :             }
    1306           0 :         }
    1307             :     }
    1308             :     else
    1309             :         // assuming we have a binary image or a object_ole that we can just insert as it is
    1310             :     {
    1311           0 :         if (propList["libwpd:mimetype"]->getStr() == "object/ole")
    1312           0 :             mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:object-ole"));
    1313             :         else
    1314           0 :             mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:image"));
    1315             : 
    1316           0 :         mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("office:binary-data"));
    1317             : 
    1318           0 :         WPXString binaryBase64Data = data.getBase64Data();
    1319             : 
    1320           0 :         mpImpl->mpCurrentContentElements->push_back(new CharDataElement(binaryBase64Data.cstr()));
    1321             : 
    1322           0 :         mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("office:binary-data"));
    1323             : 
    1324           0 :         if (propList["libwpd:mimetype"]->getStr() == "object/ole")
    1325           0 :             mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:object-ole"));
    1326             :         else
    1327           0 :             mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:image"));
    1328             :     }
    1329             : }
    1330             : 
    1331           0 : void OdtGenerator::openTextBox(const WPXPropertyList &)
    1332             : {
    1333           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInFrame) // Text box without a frame simply doesn't make sense for us
    1334           0 :         return;
    1335           0 :     mpImpl->mWriterListStates.push(WriterListState());
    1336           0 :     mpImpl->mWriterDocumentStates.push(WriterDocumentState());
    1337           0 :     mpImpl->mpCurrentContentElements->push_back(new TagOpenElement("draw:text-box"));
    1338           0 :     mpImpl->mWriterDocumentStates.top().mbInTextBox = true;
    1339           0 :     mpImpl->mWriterDocumentStates.top().mbFirstElement = false;
    1340             : }
    1341             : 
    1342           0 : void OdtGenerator::closeTextBox()
    1343             : {
    1344           0 :     if (!mpImpl->mWriterDocumentStates.top().mbInTextBox)
    1345           0 :         return;
    1346           0 :     if (mpImpl->mWriterListStates.size() > 1)
    1347           0 :         mpImpl->mWriterListStates.pop();
    1348           0 :     if (mpImpl->mWriterDocumentStates.size() > 1)
    1349           0 :         mpImpl->mWriterDocumentStates.pop();
    1350             : 
    1351           0 :     mpImpl->mpCurrentContentElements->push_back(new TagCloseElement("draw:text-box"));
    1352             : }
    1353             : 
    1354           0 : void OdtGenerator::defineSectionStyle(WPXPropertyList const &, WPXPropertyListVector const &)
    1355             : {
    1356           0 : }
    1357             : 
    1358           0 : void OdtGenerator::insertEquation(WPXPropertyList const &, WPXString const &)
    1359             : {
    1360           0 : }
    1361             : 
    1362           0 : void OdtGenerator::endDocument()
    1363             : {
    1364             :     // Write out the collected document
    1365           0 :     mpImpl->_writeTargetDocument(mpImpl->mpHandler);
    1366           0 : }
    1367             : 
    1368           0 : void OdtGenerator::startDocument()
    1369             : {
    1370           0 : }
    1371             : 
    1372           0 : void OdtGenerator::closePageSpan()
    1373             : {
    1374           0 : }
    1375             : 
    1376           0 : void OdtGenerator::definePageStyle(WPXPropertyList const &)
    1377             : {
    1378           0 : }
    1379             : 
    1380           0 : void OdtGenerator::defineParagraphStyle(WPXPropertyList const &, WPXPropertyListVector const &)
    1381             : {
    1382           0 : }
    1383             : 
    1384           0 : void OdtGenerator::defineCharacterStyle(WPXPropertyList const &)
    1385             : {
    1386           0 : }
    1387             : 
    1388           0 : void OdtGenerator::registerEmbeddedObjectHandler(const WPXString &mimeType, OdfEmbeddedObject objectHandler)
    1389             : {
    1390           0 :     mpImpl->mObjectHandlers[mimeType] = objectHandler;
    1391           0 : }
    1392             : 
    1393           0 : void OdtGenerator::registerEmbeddedImageHandler(const WPXString &mimeType, OdfEmbeddedImage imageHandler)
    1394             : {
    1395           0 :     mpImpl->mImageHandlers[mimeType] = imageHandler;
    1396           0 : }
    1397             : 
    1398             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10