diff options
Diffstat (limited to 'filters/kword/wordperfect/import/WordPerfectCollector.cxx')
-rw-r--r-- | filters/kword/wordperfect/import/WordPerfectCollector.cxx | 973 |
1 files changed, 0 insertions, 973 deletions
diff --git a/filters/kword/wordperfect/import/WordPerfectCollector.cxx b/filters/kword/wordperfect/import/WordPerfectCollector.cxx deleted file mode 100644 index eb59a70f0..000000000 --- a/filters/kword/wordperfect/import/WordPerfectCollector.cxx +++ /dev/null @@ -1,973 +0,0 @@ -/* WordPerfectCollector: Collects sections and runs of text from a - * wordperfect file (and styles to go along with them) and writes them - * to a Writer target document - * - * Copyright (C) 2002-2004 William Lachance (william.lachance@sympatico.ca) - * Copyright (C) 2003-2004 Net Integration Technologies (http://www.net-itech.com) - * Copyright (C) 2004 Fridrich Strba (fridrich.strba@bluewin.ch) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * For further information visit http://libwpd.sourceforge.net - * - */ - -/* "This product is not manufactured, approved, or supported by - * Corel Corporation or Corel Corporation Limited." - */ - -#include <config.h> - -#include <libwpd/libwpd.h> -#include <string.h> // for strcmp - -#include "WordPerfectCollector.hxx" -#include "DocumentElement.hxx" -#include "TextRunStyle.hxx" -#include "FontStyle.hxx" -#include "ListStyle.hxx" -#include "PageSpan.hxx" -#include "SectionStyle.hxx" -#include "TableStyle.hxx" -#include "FilterInternal.hxx" -#include "WriterProperties.hxx" - -_WriterDocumentState::_WriterDocumentState() : - mbFirstElement(true), - mbInFakeSection(false), - mbListElementOpenedAtCurrentLevel(false), - mbTableCellOpened(false), - mbHeaderRow(false), - mbInNote(false) -{ -} - -WordPerfectCollector::WordPerfectCollector(_SH_InputStream *pInput, DocumentHandler *pHandler) : - mpInput(pInput), - mpHandler(pHandler), - mbUsed(false), - mfSectionSpaceAfter(0.0f), - miNumListStyles(0), - mpCurrentContentElements(&mBodyElements), - mpCurrentPageSpan(NULL), - miNumPageStyles(0), - mpCurrentListStyle(NULL), - miCurrentListLevel(0), - miLastListLevel(0), - miLastListNumber(0), - mbListContinueNumbering(false), - mbListElementOpened(false), - mbListElementParagraphOpened(false) -{ -} - -WordPerfectCollector::~WordPerfectCollector() -{ -} - -bool WordPerfectCollector::filter() -{ - // The contract for WordPerfectCollector is that it will only be used once after it is - // instantiated - if (mbUsed) - return false; - - mbUsed = true; - - // parse & write - // WLACH_REFACTORING: Remove these args.. - if (!_parseSourceDocument(*mpInput)) - return false; - if (!_writeTargetDocument(*mpHandler)) - return false; - - // clean up the mess we made - WRITER_DEBUG_MSG(("WriterWordPerfect: Cleaning up our mess..\n")); - - WRITER_DEBUG_MSG(("Destroying the body elements\n")); - for (std::vector<DocumentElement *>::iterator iterBody = mBodyElements.begin(); iterBody != mBodyElements.end(); iterBody++) { - delete((*iterBody)); - (*iterBody) = NULL; - } - - WRITER_DEBUG_MSG(("Destroying the styles elements\n")); - for (std::vector<DocumentElement *>::iterator iterStyles = mStylesElements.begin(); iterStyles != mStylesElements.end(); iterStyles++) { - delete (*iterStyles); - (*iterStyles) = NULL; // we may pass over the same element again (in the case of headers/footers spanning multiple pages) - // so make sure we don't do a double del - } - - WRITER_DEBUG_MSG(("Destroying the rest of the styles elements\n")); - for (std::map<_SH_String, ParagraphStyle *, ltstr>::iterator iterTextStyle = mTextStyleHash.begin(); iterTextStyle != mTextStyleHash.end(); iterTextStyle++) { - delete(iterTextStyle->second); - } - for (std::map<_SH_String, FontStyle *, ltstr>::iterator iterFont = mFontHash.begin(); iterFont != mFontHash.end(); iterFont++) { - delete(iterFont->second); - } - - for (std::vector<ListStyle *>::iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); iterListStyles++) { - delete((*iterListStyles)); - } - for (std::vector<SectionStyle *>::iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); iterSectionStyles++) { - delete((*iterSectionStyles)); - } - for (std::vector<TableStyle *>::iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); iterTableStyles++) { - delete((*iterTableStyles)); - } - - for (std::vector<PageSpan *>::iterator iterPageSpans = mPageSpans.begin(); iterPageSpans != mPageSpans.end(); iterPageSpans++) { - delete((*iterPageSpans)); - } - - return true; -} - -bool WordPerfectCollector::_parseSourceDocument(_SH_InputStream &input) -{ -#if defined(HAVE_LIBWPD_0100) - libwpd::WPDResult result = libwpd::WPDocument::parse(&input, static_cast<_SH_DocumentInterface*>(this), NULL); -#elif defined(HAVE_LIBWPD_090) - WPDResult result = WPDocument::parse(&input, static_cast<_SH_DocumentInterface*>(this), NULL); -#else - WPDResult result = WPDocument::parse(&input, static_cast<_SH_DocumentInterface*>(this)); -#endif -#if defined(HAVE_LIBWPD_0100) - if (result != libwpd::WPD_OK) -#else - if (result != WPD_OK) -#endif - return false; - - return true; -} - -void WordPerfectCollector::_writeDefaultStyles(DocumentHandler &xHandler) -{ - TagOpenElement stylesOpenElement("office:styles"); - stylesOpenElement.write(xHandler); - - TagOpenElement defaultParagraphStyleOpenElement("style:default-style"); - defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph"); - defaultParagraphStyleOpenElement.write(xHandler); - - TagOpenElement defaultParagraphStylePropertiesOpenElement("style:properties"); - defaultParagraphStylePropertiesOpenElement.addAttribute("style:family", "paragraph"); - defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5inch"); - defaultParagraphStylePropertiesOpenElement.write(xHandler); - TagCloseElement defaultParagraphStylePropertiesCloseElement("style:properties"); - defaultParagraphStylePropertiesCloseElement.write(xHandler); - - TagCloseElement defaultParagraphStyleCloseElement("style:default-style"); - defaultParagraphStyleCloseElement.write(xHandler); - - TagOpenElement standardStyleOpenElement("style:style"); - standardStyleOpenElement.addAttribute("style:name", "Standard"); - standardStyleOpenElement.addAttribute("style:family", "paragraph"); - standardStyleOpenElement.addAttribute("style:class", "text"); - standardStyleOpenElement.write(xHandler); - TagCloseElement standardStyleCloseElement("style:style"); - standardStyleCloseElement.write(xHandler); - - TagOpenElement textBodyStyleOpenElement("style:style"); - textBodyStyleOpenElement.addAttribute("style:name", "Text Body"); - textBodyStyleOpenElement.addAttribute("style:family", "paragraph"); - textBodyStyleOpenElement.addAttribute("style:parent-style-name", "Standard"); - textBodyStyleOpenElement.addAttribute("style:class", "text"); - textBodyStyleOpenElement.write(xHandler); - TagCloseElement textBodyStyleCloseElement("style:style"); - textBodyStyleCloseElement.write(xHandler); - - TagOpenElement tableContentsStyleOpenElement("style:style"); - tableContentsStyleOpenElement.addAttribute("style:name", "Table Contents"); - tableContentsStyleOpenElement.addAttribute("style:family", "paragraph"); - tableContentsStyleOpenElement.addAttribute("style:parent-style-name", "Text Body"); - tableContentsStyleOpenElement.addAttribute("style:class", "extra"); - tableContentsStyleOpenElement.write(xHandler); - TagCloseElement tableContentsStyleCloseElement("style:style"); - tableContentsStyleCloseElement.write(xHandler); - - TagOpenElement tableHeadingStyleOpenElement("style:style"); - tableHeadingStyleOpenElement.addAttribute("style:name", "Table Heading"); - tableHeadingStyleOpenElement.addAttribute("style:family", "paragraph"); - tableHeadingStyleOpenElement.addAttribute("style:parent-style-name", "Table Contents"); - tableHeadingStyleOpenElement.addAttribute("style:class", "extra"); - tableHeadingStyleOpenElement.write(xHandler); - TagCloseElement tableHeadingStyleCloseElement("style:style"); - tableHeadingStyleCloseElement.write(xHandler); - - TagCloseElement stylesCloseElement("office:styles"); - stylesCloseElement.write(xHandler); - -} - -// writes everything up to the automatic styles declarations.. -void WordPerfectCollector::_writeBegin() -{ -} - -void WordPerfectCollector::_writeMasterPages(DocumentHandler &xHandler) -{ - _SH_PropertyList xBlankAttrList; - - xHandler.startElement("office:master-styles", xBlankAttrList); - int pageNumber = 1; - for (int i=0; i<mPageSpans.size(); i++) - { - bool bLastPage; - (i == (mPageSpans.size() - 1)) ? bLastPage = true : bLastPage = false; - mPageSpans[i]->writeMasterPages(pageNumber, i, bLastPage, xHandler); - pageNumber += mPageSpans[i]->getSpan(); - } - xHandler.endElement("office:master-styles"); -} - -void WordPerfectCollector::_writePageMasters(DocumentHandler &xHandler) -{ - int pageNumber = 1; - for (int i=0; i<mPageSpans.size(); i++) - { - mPageSpans[i]->writePageMaster(i, xHandler); - } -} - -bool WordPerfectCollector::_writeTargetDocument(DocumentHandler &xHandler) -{ - WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Printing out the header stuff..\n")); - _SH_PropertyList xBlankAttrList; - - WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Start Document\n")); - mpHandler->startDocument(); - - WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: preamble\n")); - _SH_PropertyList docContentPropList; - docContentPropList.insert("xmlns:office", "http://openoffice.org/2000/office"); - docContentPropList.insert("xmlns:style", "http://openoffice.org/2000/style"); - docContentPropList.insert("xmlns:text", "http://openoffice.org/2000/text"); - docContentPropList.insert("xmlns:table", "http://openoffice.org/2000/table"); - docContentPropList.insert("xmlns:draw", "http://openoffice.org/2000/draw"); - docContentPropList.insert("xmlns:fo", "http://www.w3.org/1999/XSL/Format"); - docContentPropList.insert("xmlns:xlink", "http://www.w3.org/1999/xlink"); - docContentPropList.insert("xmlns:number", "http://openoffice.org/2000/datastyle"); - docContentPropList.insert("xmlns:svg", "http://www.w3.org/2000/svg"); - docContentPropList.insert("xmlns:chart", "http://openoffice.org/2000/chart"); - docContentPropList.insert("xmlns:dr3d", "http://openoffice.org/2000/dr3d"); - docContentPropList.insert("xmlns:math", "http://www.w3.org/1998/Math/MathML"); - docContentPropList.insert("xmlns:form", "http://openoffice.org/2000/form"); - docContentPropList.insert("xmlns:script", "http://openoffice.org/2000/script"); - docContentPropList.insert("office:class", "text"); - docContentPropList.insert("office:version", "1.0"); - mpHandler->startElement("office:document-content", docContentPropList); - - // write out the font styles - mpHandler->startElement("office:font-decls", xBlankAttrList); - for (std::map<_SH_String, FontStyle *, ltstr>::iterator iterFont = mFontHash.begin(); iterFont != mFontHash.end(); iterFont++) { - iterFont->second->write(*mpHandler); - } - TagOpenElement symbolFontOpen("style:font-decl"); - symbolFontOpen.addAttribute("style:name", "StarSymbol"); - symbolFontOpen.addAttribute("fo:font-family", "StarSymbol"); - symbolFontOpen.addAttribute("style:font-charset", "x-symbol"); - symbolFontOpen.write(*mpHandler); - mpHandler->endElement("style:font-decl"); - - mpHandler->endElement("office:font-decls"); - - - WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the styles..\n")); - - // write default styles - _writeDefaultStyles(*mpHandler); - - mpHandler->startElement("office:automatic-styles", xBlankAttrList); - - for (std::map<_SH_String, ParagraphStyle *, ltstr>::iterator iterTextStyle = mTextStyleHash.begin(); - iterTextStyle != mTextStyleHash.end(); iterTextStyle++) - { - // writing out the paragraph styles - if (strcmp((iterTextStyle->second)->getName().cstr(), "Standard")) - { - // don't write standard paragraph "no styles" style - (iterTextStyle->second)->write(xHandler); - } - } - - // span styles.. - for (std::map<_SH_String, SpanStyle *, ltstr>::iterator iterSpanStyle = mSpanStyleHash.begin(); - iterSpanStyle != mSpanStyleHash.end(); iterSpanStyle++) - { - (iterSpanStyle->second)->write(xHandler); - } - - // writing out the sections styles - for (std::vector<SectionStyle *>::iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); iterSectionStyles++) { - (*iterSectionStyles)->write(xHandler); - } - - // writing out the lists styles - for (std::vector<ListStyle *>::iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); iterListStyles++) { - (*iterListStyles)->write(xHandler); - } - - // writing out the table styles - for (std::vector<TableStyle *>::iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); iterTableStyles++) { - (*iterTableStyles)->write(xHandler); - } - - // writing out the page masters - _writePageMasters(xHandler); - - - xHandler.endElement("office:automatic-styles"); - - _writeMasterPages(xHandler); - - WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the document..\n")); - // writing out the document - xHandler.startElement("office:body", xBlankAttrList); - - for (std::vector<DocumentElement *>::iterator iterBodyElements = mBodyElements.begin(); iterBodyElements != mBodyElements.end(); iterBodyElements++) { - (*iterBodyElements)->write(xHandler); - } - WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Finished writing all doc els..\n")); - - xHandler.endElement("office:body"); - xHandler.endElement("office:document-content"); - - xHandler.endDocument(); - - return true; -} - - -_SH_String propListToStyleKey(const _SH_PropertyList & xPropList) -{ - _SH_String sKey; - _SH_PropertyList::Iter i(xPropList); - for (i.rewind(); i.next(); ) - { - _SH_String sProp; - sProp.sprintf("[%s:%s]", i.key(), i()->getStr().cstr()); - sKey.append(sProp); - } - - return sKey; -} - -_SH_String getParagraphStyleKey(const _SH_PropertyList & xPropList, const _SH_PropertyListVector & xTabStops) -{ - _SH_String sKey = propListToStyleKey(xPropList); - - _SH_String sTabStops; - sTabStops.sprintf("[num-tab-stops:%i]", xTabStops.count()); - _SH_PropertyListVector::Iter i(xTabStops); - for (i.rewind(); i.next();) - { - sTabStops.append(propListToStyleKey(i())); - } - sKey.append(sTabStops); - - return sKey; -} - -// _allocateFontName: add a (potentially mapped) font style to the hash if it's not already there, do nothing otherwise -void WordPerfectCollector::_allocateFontName(const _SH_String & sFontName) -{ - if (mFontHash.find(sFontName) == mFontHash.end()) - { - FontStyle *pFontStyle = new FontStyle(sFontName.cstr(), sFontName.cstr()); - mFontHash[sFontName] = pFontStyle; - } -} - -void WordPerfectCollector::openPageSpan(const _SH_PropertyList &propList) -{ - PageSpan *pPageSpan = new PageSpan(propList); - mPageSpans.push_back(pPageSpan); - mpCurrentPageSpan = pPageSpan; -} - -void WordPerfectCollector::openHeader(const _SH_PropertyList &propList) -{ - std::vector<DocumentElement *> * pHeaderFooterContentElements = new std::vector<DocumentElement *>; - - if (propList["libwpd:occurence"]->getStr() == "even") - mpCurrentPageSpan->setHeaderLeftContent(pHeaderFooterContentElements); - else - mpCurrentPageSpan->setHeaderContent(pHeaderFooterContentElements); - - mpCurrentContentElements = pHeaderFooterContentElements; -} - -void WordPerfectCollector::closeHeader() -{ - mpCurrentContentElements = &mBodyElements; -} - -void WordPerfectCollector::openFooter(const _SH_PropertyList &propList) -{ - std::vector<DocumentElement *> * pHeaderFooterContentElements = new std::vector<DocumentElement *>; - - if (propList["libwpd:occurence"]->getStr() == "even") - mpCurrentPageSpan->setFooterLeftContent(pHeaderFooterContentElements); - else - mpCurrentPageSpan->setFooterContent(pHeaderFooterContentElements); - - mpCurrentContentElements = pHeaderFooterContentElements; -} - -void WordPerfectCollector::closeFooter() -{ - mpCurrentContentElements = &mBodyElements; -} - -void WordPerfectCollector::openSection(const _SH_PropertyList &propList, const _SH_PropertyListVector &columns) -{ - int iNumColumns = columns.count(); - - if (iNumColumns > 1) - { -#if defined(HAVE_LIBWPD_090) || defined(HAVE_LIBWPD_0100) - mfSectionSpaceAfter = propList["fo:margin-bottom"]->getDouble(); -#else - mfSectionSpaceAfter = propList["fo:margin-bottom"]->getFloat(); -#endif - _SH_String sSectionName; - sSectionName.sprintf("Section%i", mSectionStyles.size()); - - SectionStyle *pSectionStyle = new SectionStyle(propList, columns, sSectionName.cstr()); - mSectionStyles.push_back(pSectionStyle); - - TagOpenElement *pSectionOpenElement = new TagOpenElement("text:section"); - pSectionOpenElement->addAttribute("text:style-name", pSectionStyle->getName()); - pSectionOpenElement->addAttribute("text:name", pSectionStyle->getName()); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pSectionOpenElement)); - } - else - mWriterDocumentState.mbInFakeSection = true; -} - -void WordPerfectCollector::closeSection() -{ - if (!mWriterDocumentState.mbInFakeSection) - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:section"))); - else - mWriterDocumentState.mbInFakeSection = false; - - // open as many paragraphs as needed to simulate section space after - // WLACH_REFACTORING: disable this for now.. - #if 0 - for (float f=0.0f; f<mfSectionSpaceAfter; f+=1.0f) { - vector<WPXTabStop> dummyTabStops; - openParagraph(WPX_PARAGRAPH_JUSTIFICATION_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, dummyTabStops, false, false); - closeParagraph(); - } - #endif - mfSectionSpaceAfter = 0.0f; -} - -void WordPerfectCollector::openParagraph(const _SH_PropertyList &propList, const _SH_PropertyListVector &tabStops) -{ - // FIXMENOW: What happens if we open a footnote inside a table? do we then inherit the footnote's style - // from "Table Contents" - - _SH_PropertyList *pPersistPropList = new _SH_PropertyList(propList); - ParagraphStyle *pStyle = NULL; - - if (mWriterDocumentState.mbFirstElement && mpCurrentContentElements == &mBodyElements) - { - // we don't have to go through the fuss of determining if the paragraph style is - // unique in this case, because if we are the first document element, then we - // are singular. Neither do we have to determine what our parent style is-- we can't - // be inside a table in this case (the table would be the first document element - //in that case) - pPersistPropList->insert("style:parent-style-name", "Standard"); - _SH_String sName; - sName.sprintf("FS"); - - _SH_String sParagraphHashKey("P|FS"); - pPersistPropList->insert("style:master-page-name", "Page Style 1"); - pStyle = new ParagraphStyle(pPersistPropList, tabStops, sName); - mTextStyleHash[sParagraphHashKey] = pStyle; - mWriterDocumentState.mbFirstElement = false; - } - else - { - if (mWriterDocumentState.mbTableCellOpened) - { - if (mWriterDocumentState.mbHeaderRow) - pPersistPropList->insert("style:parent-style-name", "Table Heading"); - else - pPersistPropList->insert("style:parent-style-name", "Table Contents"); - } - else - pPersistPropList->insert("style:parent-style-name", "Standard"); - - _SH_String sKey = getParagraphStyleKey(*pPersistPropList, tabStops); - - if (mTextStyleHash.find(sKey) == mTextStyleHash.end()) { - _SH_String sName; - sName.sprintf("S%i", mTextStyleHash.size()); - - pStyle = new ParagraphStyle(pPersistPropList, tabStops, sName); - - mTextStyleHash[sKey] = pStyle; - } - else - { - pStyle = mTextStyleHash[sKey]; - delete pPersistPropList; - } - } - // create a document element corresponding to the paragraph, and append it to our list of document elements - TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p"); - pParagraphOpenElement->addAttribute("text:style-name", pStyle->getName()); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pParagraphOpenElement)); -} - -void WordPerfectCollector::closeParagraph() -{ - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p"))); -} - -void WordPerfectCollector::openSpan(const _SH_PropertyList &propList) -{ - if (propList["style:font-name"]) - _allocateFontName(propList["style:font-name"]->getStr()); - _SH_String sSpanHashKey = propListToStyleKey(propList); - WRITER_DEBUG_MSG(("WriterWordPerfect: Span Hash Key: %s\n", sSpanHashKey.cstr())); - - // Get the style - _SH_String sName; - if (mSpanStyleHash.find(sSpanHashKey) == mSpanStyleHash.end()) - { - // allocate a new paragraph style - sName.sprintf("Span%i", mSpanStyleHash.size()); - SpanStyle *pStyle = new SpanStyle(sName.cstr(), propList); - - mSpanStyleHash[sSpanHashKey] = pStyle; - } - else - { - sName.sprintf("%s", mSpanStyleHash.find(sSpanHashKey)->second->getName().cstr()); - } - - // create a document element corresponding to the paragraph, and append it to our list of document elements - TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span"); - pSpanOpenElement->addAttribute("text:style-name", sName.cstr()); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pSpanOpenElement)); -} - -void WordPerfectCollector::closeSpan() -{ - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:span"))); -} - -void WordPerfectCollector::defineOrderedListLevel(const _SH_PropertyList &propList) -{ - int id = 0; - if (propList["libwpd:id"]) - id = propList["libwpd:id"]->getInt(); - - OrderedListStyle *pOrderedListStyle = NULL; - if (mpCurrentListStyle && mpCurrentListStyle->getListID() == id) - pOrderedListStyle = static_cast<OrderedListStyle *>(mpCurrentListStyle); // FIXME: using a dynamic cast here causes oo to crash?! - - // this rather appalling conditional makes sure we only start a new list (rather than continue an old - // one) if: (1) we have no prior list OR (2) the prior list is actually definitively different - // from the list that is just being defined (listIDs differ) OR (3) we can tell that the user actually - // is starting a new list at level 1 (and only level 1) - if (pOrderedListStyle == NULL || pOrderedListStyle->getListID() != id || - (propList["libwpd:level"] && propList["libwpd:level"]->getInt()==1 && - (propList["text:start-value"] && propList["text:start-value"]->getInt() != (miLastListNumber+1)))) - { - WRITER_DEBUG_MSG(("Attempting to create a new ordered list style (listid: %i)\n", id)); - _SH_String sName; - sName.sprintf("OL%i", miNumListStyles); - miNumListStyles++; - pOrderedListStyle = new OrderedListStyle(sName.cstr(), propList["libwpd:id"]->getInt()); - mListStyles.push_back(static_cast<ListStyle *>(pOrderedListStyle)); - mpCurrentListStyle = static_cast<ListStyle *>(pOrderedListStyle); - mbListContinueNumbering = false; - miLastListNumber = 0; - } - else - mbListContinueNumbering = true; - - // Iterate through ALL list styles with the same WordPerfect list id and define a level if it is not already defined - // This solves certain problems with lists that start and finish without reaching certain levels and then begin again - // and reach those levels. See gradguide0405_PC.wpd in the regression suite - for (std::vector<ListStyle *>::iterator iterOrderedListStyles = mListStyles.begin(); iterOrderedListStyles != mListStyles.end(); iterOrderedListStyles++) - { - if ((* iterOrderedListStyles)->getListID() == propList["libwpd:id"]->getInt()) - (* iterOrderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList); - } -} - -void WordPerfectCollector::defineUnorderedListLevel(const _SH_PropertyList &propList) -{ - int id = 0; - if (propList["libwpd:id"]) - id = propList["libwpd:id"]->getInt(); - - UnorderedListStyle *pUnorderedListStyle = NULL; - if (mpCurrentListStyle && mpCurrentListStyle->getListID() == id) - pUnorderedListStyle = static_cast<UnorderedListStyle *>(mpCurrentListStyle); // FIXME: using a dynamic cast here causes oo to crash?! - - if (pUnorderedListStyle == NULL) { - WRITER_DEBUG_MSG(("Attempting to create a new unordered list style (listid: %i)\n", id)); - _SH_String sName; - sName.sprintf("UL%i", miNumListStyles); - pUnorderedListStyle = new UnorderedListStyle(sName.cstr(), id); - mListStyles.push_back(static_cast<ListStyle *>(pUnorderedListStyle)); - mpCurrentListStyle = static_cast<ListStyle *>(pUnorderedListStyle); - } - - // See comment in WordPerfectCollector::defineOrderedListLevel - for (std::vector<ListStyle *>::iterator iterUnorderedListStyles = mListStyles.begin(); iterUnorderedListStyles != mListStyles.end(); iterUnorderedListStyles++) - { - if ((* iterUnorderedListStyles)->getListID() == propList["libwpd:id"]->getInt()) - (* iterUnorderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList); - } -} - -void WordPerfectCollector::openOrderedListLevel(const _SH_PropertyList &propList) -{ - miCurrentListLevel++; - TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:ordered-list"); - _openListLevel(pListLevelOpenElement); - - if (mbListContinueNumbering) { - pListLevelOpenElement->addAttribute("text:continue-numbering", "true"); - } - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pListLevelOpenElement)); -} - -void WordPerfectCollector::openUnorderedListLevel(const _SH_PropertyList &propList) -{ - miCurrentListLevel++; - TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:unordered-list"); - _openListLevel(pListLevelOpenElement); - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pListLevelOpenElement)); -} - -void WordPerfectCollector::_openListLevel(TagOpenElement *pListLevelOpenElement) -{ - if (!mbListElementOpened && miCurrentListLevel > 1) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:list-item"))); - } - else if (mbListElementParagraphOpened) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p"))); - mbListElementParagraphOpened = false; - } - - if (miCurrentListLevel==1) { - pListLevelOpenElement->addAttribute("text:style-name", mpCurrentListStyle->getName()); - } - - mbListElementOpened = false; -} - -void WordPerfectCollector::closeOrderedListLevel() -{ - _closeListLevel("ordered-list"); -} - -void WordPerfectCollector::closeUnorderedListLevel() -{ - _closeListLevel("unordered-list"); -} - -void WordPerfectCollector::_closeListLevel(const char *szListType) -{ - if (mbListElementOpened) - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item"))); - - miCurrentListLevel--; - - _SH_String sCloseElement; - sCloseElement.sprintf("text:%s", szListType); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement(sCloseElement.cstr()))); - - if (miCurrentListLevel > 0) - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item"))); - mbListElementOpened = false; -} - -void WordPerfectCollector::openListElement(const _SH_PropertyList &propList, const _SH_PropertyListVector &tabStops) -{ - miLastListLevel = miCurrentListLevel; - if (miCurrentListLevel == 1) - miLastListNumber++; - - if (mbListElementOpened) - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item"))); - - ParagraphStyle *pStyle = NULL; - - _SH_PropertyList *pPersistPropList = new _SH_PropertyList(propList); - pPersistPropList->insert("style:list-style-name", mpCurrentListStyle->getName()); - pPersistPropList->insert("style:parent-style-name", "Standard"); - - _SH_String sKey = getParagraphStyleKey(*pPersistPropList, tabStops); - - if (mTextStyleHash.find(sKey) == mTextStyleHash.end()) - { - _SH_String sName; - sName.sprintf("S%i", mTextStyleHash.size()); - - pStyle = new ParagraphStyle(pPersistPropList, tabStops, sName); - - mTextStyleHash[sKey] = pStyle; - } - else - { - pStyle = mTextStyleHash[sKey]; - delete pPersistPropList; - } - - TagOpenElement *pOpenListElement = new TagOpenElement("text:list-item"); - TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p"); - - pOpenListElementParagraph->addAttribute("text:style-name", pStyle->getName()); - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenListElement)); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenListElementParagraph)); - - mbListElementOpened = true; - mbListElementParagraphOpened = true; - mbListContinueNumbering = false; -} - -void WordPerfectCollector::closeListElement() -{ - // this code is kind of tricky, because we don't actually close the list element (because this list element - // could contain another list level in OOo's implementation of lists). that is done in the closeListLevel - // code (or when we open another list element) - - if (mbListElementParagraphOpened) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p"))); - mbListElementParagraphOpened = false; - } -} - -void WordPerfectCollector::openFootnote(const _SH_PropertyList &propList) -{ - TagOpenElement *pOpenFootNote = new TagOpenElement("text:footnote"); - if (propList["libwpd:number"]) - { - _SH_String tmpString("ftn"); - tmpString.append(propList["libwpd:number"]->getStr()); - pOpenFootNote->addAttribute("text:id", tmpString); - } - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenFootNote)); - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:footnote-citation"))); - if (propList["libwpd:number"]) - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new CharDataElement(propList["libwpd:number"]->getStr().cstr()))); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote-citation"))); - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:footnote-body"))); - - mWriterDocumentState.mbInNote = true; -} - -void WordPerfectCollector::closeFootnote() -{ - mWriterDocumentState.mbInNote = false; - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote-body"))); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote"))); -} - -void WordPerfectCollector::openEndnote(const _SH_PropertyList &propList) -{ - TagOpenElement *pOpenEndNote = new TagOpenElement("text:endnote"); - if (propList["libwpd:number"]) - { - _SH_String tmpString("edn"); - tmpString.append(propList["libwpd:number"]->getStr()); - pOpenEndNote->addAttribute("text:id", tmpString); - } - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenEndNote)); - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:endnote-citation"))); - if (propList["libwpd:number"]) - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new CharDataElement(propList["libwpd:number"]->getStr().cstr()))); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote-citation"))); - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:endnote-body"))); - - mWriterDocumentState.mbInNote = true; -} - -void WordPerfectCollector::closeEndnote() -{ - mWriterDocumentState.mbInNote = false; - - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote-body"))); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote"))); -} - -void WordPerfectCollector::openTable(const _SH_PropertyList &propList, const _SH_PropertyListVector &columns) -{ - if (!mWriterDocumentState.mbInNote) - { - _SH_String sTableName; - sTableName.sprintf("Table%i", mTableStyles.size()); - - // FIXME: we base the table style off of the page's margin left, ignoring (potential) wordperfect margin - // state which is transmitted inside the page. could this lead to unacceptable behaviour? - // WLACH_REFACTORING: characterize this behaviour, probably should nip it at the bud within libwpd - TableStyle *pTableStyle = new TableStyle(propList, columns, sTableName.cstr()); - - if (mWriterDocumentState.mbFirstElement && mpCurrentContentElements == &mBodyElements) - { - _SH_String sMasterPageName("Page Style 1"); - pTableStyle->setMasterPageName(sMasterPageName); - mWriterDocumentState.mbFirstElement = false; - } - - mTableStyles.push_back(pTableStyle); - - mpCurrentTableStyle = pTableStyle; - - TagOpenElement *pTableOpenElement = new TagOpenElement("table:table"); - - pTableOpenElement->addAttribute("table:name", sTableName.cstr()); - pTableOpenElement->addAttribute("table:style-name", sTableName.cstr()); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableOpenElement)); - - for (int i=0; i<pTableStyle->getNumColumns(); i++) - { - TagOpenElement *pTableColumnOpenElement = new TagOpenElement("table:table-column"); - _SH_String sColumnStyleName; - sColumnStyleName.sprintf("%s.Column%i", sTableName.cstr(), (i+1)); - pTableColumnOpenElement->addAttribute("table:style-name", sColumnStyleName.cstr()); - mpCurrentContentElements->push_back(pTableColumnOpenElement); - - TagCloseElement *pTableColumnCloseElement = new TagCloseElement("table:table-column"); - mpCurrentContentElements->push_back(pTableColumnCloseElement); - } - } -} - -void WordPerfectCollector::openTableRow(const _SH_PropertyList &propList) -{ - if (!mWriterDocumentState.mbInNote) - { - if (propList["libwpd:is-header-row"] && (propList["libwpd:is-header-row"]->getInt())) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("table:table-header-rows"))); - mWriterDocumentState.mbHeaderRow = true; - } - - _SH_String sTableRowStyleName; - sTableRowStyleName.sprintf("%s.Row%i", mpCurrentTableStyle->getName().cstr(), mpCurrentTableStyle->getNumTableRowStyles()); - TableRowStyle *pTableRowStyle = new TableRowStyle(propList, sTableRowStyleName.cstr()); - mpCurrentTableStyle->addTableRowStyle(pTableRowStyle); - - TagOpenElement *pTableRowOpenElement = new TagOpenElement("table:table-row"); - pTableRowOpenElement->addAttribute("table:style-name", sTableRowStyleName); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableRowOpenElement)); - } -} - -void WordPerfectCollector::closeTableRow() -{ - if (!mWriterDocumentState.mbInNote) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-row"))); - if (mWriterDocumentState.mbHeaderRow) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-header-rows"))); - mWriterDocumentState.mbHeaderRow = false; - } - } -} - -void WordPerfectCollector::openTableCell(const _SH_PropertyList &propList) -{ - if (!mWriterDocumentState.mbInNote) - { - _SH_String sTableCellStyleName; - sTableCellStyleName.sprintf( "%s.Cell%i", mpCurrentTableStyle->getName().cstr(), mpCurrentTableStyle->getNumTableCellStyles()); - TableCellStyle *pTableCellStyle = new TableCellStyle(propList, sTableCellStyleName.cstr()); - mpCurrentTableStyle->addTableCellStyle(pTableCellStyle); - - TagOpenElement *pTableCellOpenElement = new TagOpenElement("table:table-cell"); - pTableCellOpenElement->addAttribute("table:style-name", sTableCellStyleName); - if (propList["table:number-columns-spanned"]) - pTableCellOpenElement->addAttribute("table:number-columns-spanned", - propList["table:number-columns-spanned"]->getStr().cstr()); - if (propList["table:number-rows-spanned"]) - pTableCellOpenElement->addAttribute("table:number-rows-spanned", - propList["table:number-rows-spanned"]->getStr().cstr()); - pTableCellOpenElement->addAttribute("table:value-type", "string"); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableCellOpenElement)); - - mWriterDocumentState.mbTableCellOpened = true; - } -} - -void WordPerfectCollector::closeTableCell() -{ - if (!mWriterDocumentState.mbInNote) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-cell"))); - mWriterDocumentState.mbTableCellOpened = false; - } -} - -void WordPerfectCollector::insertCoveredTableCell(const _SH_PropertyList &propList) -{ - if (!mWriterDocumentState.mbInNote) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("table:covered-table-cell"))); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:covered-table-cell"))); - } -} - -void WordPerfectCollector::closeTable() -{ - if (!mWriterDocumentState.mbInNote) - { - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table"))); - } -} - - -void WordPerfectCollector::insertTab() -{ - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:tab-stop"))); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:tab-stop"))); -} - -void WordPerfectCollector::insertLineBreak() -{ - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:line-break"))); - mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:line-break"))); -} - -void WordPerfectCollector::insertText(const _SH_String &text) -{ - DocumentElement *pText = new TextElement(text); - mpCurrentContentElements->push_back(pText); -} |