diff options
Diffstat (limited to 'writerperfect/source/filter')
22 files changed, 2818 insertions, 0 deletions
diff --git a/writerperfect/source/filter/DocumentCollector.cxx b/writerperfect/source/filter/DocumentCollector.cxx new file mode 100644 index 000000000000..e258d2212518 --- /dev/null +++ b/writerperfect/source/filter/DocumentCollector.cxx @@ -0,0 +1,931 @@ +/* DocumentCollector: Collects sections and runs of text from a + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif +#include <string.h> // for strcmp + +#include "DocumentCollector.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) +{ +} + +DocumentCollector::DocumentCollector(WPXInputStream *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) +{ +} + +DocumentCollector::~DocumentCollector() +{ +} + +bool DocumentCollector::filter() +{ + // The contract for DocumentCollector 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<WPXString, ParagraphStyle *, ltstr>::iterator iterTextStyle = mTextStyleHash.begin(); iterTextStyle != mTextStyleHash.end(); iterTextStyle++) { + delete iterTextStyle->second; + } + for (std::map<WPXString, SpanStyle *, ltstr>::iterator iterSpanStyle = mSpanStyleHash.begin(); iterSpanStyle != mSpanStyleHash.end(); iterSpanStyle++) { + delete iterSpanStyle->second; + } + + for (std::map<WPXString, 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; +} + +void DocumentCollector::_writeDefaultStyles(DocumentHandler *pHandler) +{ + TagOpenElement stylesOpenElement("office:styles"); + stylesOpenElement.write(pHandler); + + TagOpenElement defaultParagraphStyleOpenElement("style:default-style"); + defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph"); + defaultParagraphStyleOpenElement.write(pHandler); + + TagOpenElement defaultParagraphStylePropertiesOpenElement("style:properties"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:family", "paragraph"); + defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5inch"); + defaultParagraphStylePropertiesOpenElement.write(pHandler); + TagCloseElement defaultParagraphStylePropertiesCloseElement("style:properties"); + defaultParagraphStylePropertiesCloseElement.write(pHandler); + + TagCloseElement defaultParagraphStyleCloseElement("style:default-style"); + defaultParagraphStyleCloseElement.write(pHandler); + + TagOpenElement standardStyleOpenElement("style:style"); + standardStyleOpenElement.addAttribute("style:name", "Standard"); + standardStyleOpenElement.addAttribute("style:family", "paragraph"); + standardStyleOpenElement.addAttribute("style:class", "text"); + standardStyleOpenElement.write(pHandler); + TagCloseElement standardStyleCloseElement("style:style"); + standardStyleCloseElement.write(pHandler); + + 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(pHandler); + TagCloseElement textBodyStyleCloseElement("style:style"); + textBodyStyleCloseElement.write(pHandler); + + 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(pHandler); + TagCloseElement tableContentsStyleCloseElement("style:style"); + tableContentsStyleCloseElement.write(pHandler); + + 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(pHandler); + TagCloseElement tableHeadingStyleCloseElement("style:style"); + tableHeadingStyleCloseElement.write(pHandler); + + TagCloseElement stylesCloseElement("office:styles"); + stylesCloseElement.write(pHandler); + +} + +void DocumentCollector::_writeMasterPages(DocumentHandler *pHandler) +{ + WPXPropertyList xBlankAttrList; + + pHandler->startElement("office:master-styles", xBlankAttrList); + int pageNumber = 1; + for (unsigned int i=0; i<mPageSpans.size(); i++) + { + bool bLastPage; + (i == (mPageSpans.size() - 1)) ? bLastPage = true : bLastPage = false; + mPageSpans[i]->writeMasterPages(pageNumber, i, bLastPage, pHandler); + pageNumber += mPageSpans[i]->getSpan(); + } + pHandler->endElement("office:master-styles"); +} + +void DocumentCollector::_writePageMasters(DocumentHandler *pHandler) +{ + for (unsigned int i=0; i<mPageSpans.size(); i++) + { + mPageSpans[i]->writePageMaster(i, pHandler); + } +} + +bool DocumentCollector::_writeTargetDocument(DocumentHandler *pHandler) +{ + WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Printing out the header stuff..\n")); + WPXPropertyList xBlankAttrList; + + WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Start Document\n")); + mpHandler->startDocument(); + + WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: preamble\n")); + WPXPropertyList 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<WPXString, 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<WPXString, 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(pHandler); + } + } + + // span styles.. + for (std::map<WPXString, SpanStyle *, ltstr>::iterator iterSpanStyle = mSpanStyleHash.begin(); + iterSpanStyle != mSpanStyleHash.end(); iterSpanStyle++) + { + (iterSpanStyle->second)->write(pHandler); + } + + // writing out the sections styles + for (std::vector<SectionStyle *>::iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); iterSectionStyles++) { + (*iterSectionStyles)->write(pHandler); + } + + // writing out the lists styles + for (std::vector<ListStyle *>::iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); iterListStyles++) { + (*iterListStyles)->write(pHandler); + } + + // writing out the table styles + for (std::vector<TableStyle *>::iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); iterTableStyles++) { + (*iterTableStyles)->write(pHandler); + } + + // writing out the page masters + _writePageMasters(pHandler); + + + pHandler->endElement("office:automatic-styles"); + + _writeMasterPages(pHandler); + + WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the document..\n")); + // writing out the document + pHandler->startElement("office:body", xBlankAttrList); + + for (std::vector<DocumentElement *>::iterator iterBodyElements = mBodyElements.begin(); iterBodyElements != mBodyElements.end(); iterBodyElements++) { + (*iterBodyElements)->write(pHandler); + } + WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Finished writing all doc els..\n")); + + pHandler->endElement("office:body"); + pHandler->endElement("office:document-content"); + + pHandler->endDocument(); + + return true; +} + + +WPXString propListToStyleKey(const WPXPropertyList & xPropList) +{ + WPXString sKey; + WPXPropertyList::Iter i(xPropList); + for (i.rewind(); i.next(); ) + { + WPXString sProp; + sProp.sprintf("[%s:%s]", i.key(), i()->getStr().cstr()); + sKey.append(sProp); + } + + return sKey; +} + +WPXString getParagraphStyleKey(const WPXPropertyList & xPropList, const WPXPropertyListVector & xTabStops) +{ + WPXString sKey = propListToStyleKey(xPropList); + + WPXString sTabStops; + sTabStops.sprintf("[num-tab-stops:%i]", xTabStops.count()); + WPXPropertyListVector::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 DocumentCollector::_allocateFontName(const WPXString & sFontName) +{ + if (mFontHash.find(sFontName) == mFontHash.end()) + { + FontStyle *pFontStyle = new FontStyle(sFontName.cstr(), sFontName.cstr()); + mFontHash[sFontName] = pFontStyle; + } +} + +void DocumentCollector::openPageSpan(const WPXPropertyList &propList) +{ + PageSpan *pPageSpan = new PageSpan(propList); + mPageSpans.push_back(pPageSpan); + mpCurrentPageSpan = pPageSpan; +} + +void DocumentCollector::openHeader(const WPXPropertyList &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 DocumentCollector::closeHeader() +{ + mpCurrentContentElements = &mBodyElements; +} + +void DocumentCollector::openFooter(const WPXPropertyList &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 DocumentCollector::closeFooter() +{ + mpCurrentContentElements = &mBodyElements; +} + +void DocumentCollector::openSection(const WPXPropertyList &propList, const WPXPropertyListVector &columns) +{ + int iNumColumns = columns.count(); + float fSectionMarginLeft = 0.0f; + float fSectionMarginRight = 0.0f; + if (propList["fo:margin-left"]) + fSectionMarginLeft = propList["fo:margin-left"]->getFloat(); + if (propList["fo:margin-right"]) + fSectionMarginRight = propList["fo:margin-right"]->getFloat(); + + if (iNumColumns > 1 || fSectionMarginLeft != 0 || fSectionMarginRight != 0) + { + mfSectionSpaceAfter = propList["fo:margin-bottom"]->getFloat(); + WPXString 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 DocumentCollector::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 DocumentCollector::openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops) +{ + // FIXMENOW: What happens if we open a footnote inside a table? do we then inherit the footnote's style + // from "Table Contents" + + WPXPropertyList *pPersistPropList = new WPXPropertyList(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"); + WPXString sName; + sName.sprintf("FS"); + + WPXString 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"); + + WPXString sKey = getParagraphStyleKey(*pPersistPropList, tabStops); + + if (mTextStyleHash.find(sKey) == mTextStyleHash.end()) { + WPXString 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 DocumentCollector::closeParagraph() +{ + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p"))); +} + +void DocumentCollector::openSpan(const WPXPropertyList &propList) +{ + if (propList["style:font-name"]) + _allocateFontName(propList["style:font-name"]->getStr()); + WPXString sSpanHashKey = propListToStyleKey(propList); + WRITER_DEBUG_MSG(("WriterWordPerfect: Span Hash Key: %s\n", sSpanHashKey.cstr())); + + // Get the style + WPXString 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 DocumentCollector::closeSpan() +{ + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:span"))); +} + +void DocumentCollector::defineOrderedListLevel(const WPXPropertyList &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"] && (unsigned int)(propList["text:start-value"]->getInt()) != (miLastListNumber+1)))) + { + WRITER_DEBUG_MSG(("Attempting to create a new ordered list style (listid: %i)\n", id)); + WPXString 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 DocumentCollector::defineUnorderedListLevel(const WPXPropertyList &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)); + WPXString 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 DocumentCollector::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 DocumentCollector::openOrderedListLevel(const WPXPropertyList & /* 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 DocumentCollector::openUnorderedListLevel(const WPXPropertyList & /* propList */) +{ + miCurrentListLevel++; + TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:unordered-list"); + _openListLevel(pListLevelOpenElement); + + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pListLevelOpenElement)); +} + +void DocumentCollector::_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 DocumentCollector::closeOrderedListLevel() +{ + _closeListLevel("ordered-list"); +} + +void DocumentCollector::closeUnorderedListLevel() +{ + _closeListLevel("unordered-list"); +} + +void DocumentCollector::_closeListLevel(const char *szListType) +{ + if (mbListElementOpened) + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item"))); + + miCurrentListLevel--; + + WPXString 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 DocumentCollector::openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops) +{ + miLastListLevel = miCurrentListLevel; + if (miCurrentListLevel == 1) + miLastListNumber++; + + if (mbListElementOpened) + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item"))); + + ParagraphStyle *pStyle = NULL; + + WPXPropertyList *pPersistPropList = new WPXPropertyList(propList); + pPersistPropList->insert("style:list-style-name", mpCurrentListStyle->getName()); + pPersistPropList->insert("style:parent-style-name", "Standard"); + + WPXString sKey = getParagraphStyleKey(*pPersistPropList, tabStops); + + if (mTextStyleHash.find(sKey) == mTextStyleHash.end()) + { + WPXString 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 DocumentCollector::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 DocumentCollector::openFootnote(const WPXPropertyList &propList) +{ + TagOpenElement *pOpenFootNote = new TagOpenElement("text:footnote"); + if (propList["libwpd:number"]) + { + WPXString 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 DocumentCollector::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 DocumentCollector::openEndnote(const WPXPropertyList &propList) +{ + TagOpenElement *pOpenEndNote = new TagOpenElement("text:endnote"); + if (propList["libwpd:number"]) + { + WPXString 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"))); + +} +void DocumentCollector::closeEndnote() +{ + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote-body"))); + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote"))); +} + +void DocumentCollector::openTable(const WPXPropertyList &propList, const WPXPropertyListVector &columns) +{ + WPXString 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) + { + WPXString 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"); + WPXString 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 DocumentCollector::openTableRow(const WPXPropertyList &propList) +{ + 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; + } + + WPXString 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 DocumentCollector::closeTableRow() +{ + 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 DocumentCollector::openTableCell(const WPXPropertyList &propList) +{ + WPXString 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 DocumentCollector::closeTableCell() +{ + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-cell"))); + mWriterDocumentState.mbTableCellOpened = false; +} + +void DocumentCollector::insertCoveredTableCell(const WPXPropertyList & /* propList */) +{ + 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 DocumentCollector::closeTable() +{ + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table"))); +} + +void DocumentCollector::insertTab() +{ + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:tab-stop"))); + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:tab-stop"))); +} + +void DocumentCollector::insertLineBreak() +{ + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:line-break"))); + mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:line-break"))); +} + +void DocumentCollector::insertText(const WPXString &text) +{ + DocumentElement *pText = new TextElement(text); + mpCurrentContentElements->push_back(pText); +} diff --git a/writerperfect/source/filter/DocumentCollector.hxx b/writerperfect/source/filter/DocumentCollector.hxx new file mode 100644 index 000000000000..18ebcdb43418 --- /dev/null +++ b/writerperfect/source/filter/DocumentCollector.hxx @@ -0,0 +1,201 @@ +/* DocumentCollector: Collects sections and runs of text from a + * file (and styles to go along with them) and writes them + * to a target file + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#ifndef _DOCUMENTCOLLECTOR_HXX +#define _DOCUMENTCOLLECTOR_HXX +#include "SectionStyle.hxx" + +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif +#include <vector> +#include <map> +#include <stack> +#include <string.h> + +class DocumentElement; +class DocumentHandler; +class TagOpenElement; +class FontStyle; +class ListStyle; + +class ParagraphStyle; +class SpanStyle; +class TableStyle; +class PageSpan; + +// the state we use for writing the final document +typedef struct _WriterDocumentState WriterDocumentState; +struct _WriterDocumentState +{ + _WriterDocumentState(); + + bool mbFirstElement; + bool mbInFakeSection; + bool mbListElementOpenedAtCurrentLevel; + bool mbTableCellOpened; + bool mbHeaderRow; + bool mbInNote; +}; + +enum WriterListType { unordered, ordered }; + +struct ltstr +{ + bool operator()(const WPXString & s1, const WPXString & s2) const + { + return strcmp(s1.cstr(), s2.cstr()) < 0; + } +}; + +class DocumentCollector : public WPXHLListenerImpl +{ +public: + DocumentCollector(WPXInputStream *pInput, DocumentHandler *pHandler); + virtual ~DocumentCollector(); + bool filter(); + + virtual void setDocumentMetaData(const WPXPropertyList & /* propList */) {} + virtual void startDocument() {} + virtual void endDocument() {} + + virtual void openPageSpan(const WPXPropertyList &propList); + virtual void closePageSpan() {} + + virtual void openSection(const WPXPropertyList &propList, const WPXPropertyListVector &columns); + virtual void closeSection(); + + virtual void openHeader(const WPXPropertyList &propList); + virtual void closeHeader(); + virtual void openFooter(const WPXPropertyList &propList); + virtual void closeFooter(); + + virtual void openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops); + virtual void closeParagraph(); + + virtual void openSpan(const WPXPropertyList &propList); + virtual void closeSpan(); + + + virtual void insertTab(); + virtual void insertText(const WPXString &text); + virtual void insertLineBreak(); + + virtual void defineOrderedListLevel(const WPXPropertyList &propList); + virtual void defineUnorderedListLevel(const WPXPropertyList &propList); + virtual void openOrderedListLevel(const WPXPropertyList &propList); + virtual void openUnorderedListLevel(const WPXPropertyList &propList); + virtual void closeOrderedListLevel(); + virtual void closeUnorderedListLevel(); + virtual void openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops); + virtual void closeListElement(); + + virtual void openFootnote(const WPXPropertyList &propList); + virtual void closeFootnote(); + virtual void openEndnote(const WPXPropertyList &propList); + virtual void closeEndnote(); + + virtual void openTable(const WPXPropertyList &propList, const WPXPropertyListVector &columns); + virtual void openTableRow(const WPXPropertyList &propList); + virtual void closeTableRow(); + virtual void openTableCell(const WPXPropertyList &propList); + virtual void closeTableCell(); + virtual void insertCoveredTableCell(const WPXPropertyList &propList); + virtual void closeTable(); + virtual bool parseSourceDocument(WPXInputStream &input) = 0; + +protected: + void _resetDocumentState(); + bool _writeTargetDocument(DocumentHandler *pHandler); + void _writeDefaultStyles(DocumentHandler *pHandler); + void _writeMasterPages(DocumentHandler *pHandler); + void _writePageMasters(DocumentHandler *pHandler); + void _allocateFontName(const WPXString &); + +private: + void _openListLevel(TagOpenElement *pListLevelOpenElement); + void _closeListLevel(const char *szListType); + + WPXInputStream *mpInput; + DocumentHandler *mpHandler; + bool mbUsed; // whether or not it has been before (you can only use me once!) + + WriterDocumentState mWriterDocumentState; + + // paragraph styles + std::map<WPXString, ParagraphStyle *, ltstr> mTextStyleHash; + + // span styles + std::map<WPXString, SpanStyle *, ltstr> mSpanStyleHash; + + // font styles + std::map<WPXString, FontStyle *, ltstr> mFontHash; + + // section styles + std::vector<SectionStyle *> mSectionStyles; + float mfSectionSpaceAfter; + + // table styles + std::vector<TableStyle *> mTableStyles; + + // list styles + unsigned int miNumListStyles; + + // style elements + std::vector<DocumentElement *> mStylesElements; + // content elements + std::vector<DocumentElement *> mBodyElements; + // the current set of elements that we're writing to + std::vector<DocumentElement *> * mpCurrentContentElements; + + // page state + std::vector<PageSpan *> mPageSpans; + PageSpan *mpCurrentPageSpan; + int miNumPageStyles; + + // list styles / state + ListStyle *mpCurrentListStyle; + unsigned int miCurrentListLevel; + unsigned int miLastListLevel; + unsigned int miLastListNumber; + std::vector<ListStyle *> mListStyles; + bool mbListContinueNumbering; + bool mbListElementOpened; + bool mbListElementParagraphOpened; + + // table state + TableStyle *mpCurrentTableStyle; +}; + +#endif diff --git a/writerperfect/source/filter/DocumentElement.cxx b/writerperfect/source/filter/DocumentElement.cxx new file mode 100644 index 000000000000..38caf5780e15 --- /dev/null +++ b/writerperfect/source/filter/DocumentElement.cxx @@ -0,0 +1,102 @@ +/* DocumentElement: The items we are collecting to be put into the Writer + * document: paragraph and spans of text, as well as section breaks. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "DocumentElement.hxx" +#include "FilterInternal.hxx" +#include <string.h> + +#define ASCII_SPACE 0x0020 + +void TagElement::print() const +{ + WRITER_DEBUG_MSG(("%s\n", msTagName.cstr())); +} + +void TagOpenElement::write(DocumentHandler *pHandler) const +{ + pHandler->startElement(getTagName().cstr(), maAttrList); +} + +void TagOpenElement::print() const +{ + TagElement::print(); +} + +void TagOpenElement::addAttribute(const char *szAttributeName, const WPXString &sAttributeValue) +{ + maAttrList.insert(szAttributeName, sAttributeValue); +} + +void TagCloseElement::write(DocumentHandler *pHandler) const +{ + WRITER_DEBUG_MSG(("TagCloseElement: write (%s)\n", getTagName().cstr())); + + pHandler->endElement(getTagName().cstr()); +} + +void CharDataElement::write(DocumentHandler *pHandler) const +{ + WRITER_DEBUG_MSG(("TextElement: write\n")); + pHandler->characters(msData); +} + +TextElement::TextElement(const WPXString & sTextBuf) : + msTextBuf(sTextBuf, false) +{ +} + +// write: writes a text run, appropriately converting spaces to <text:s> +// elements +void TextElement::write(DocumentHandler *pHandler) const +{ + WPXPropertyList xBlankAttrList; + + WPXString sTemp; + + int iNumConsecutiveSpaces = 0; + WPXString::Iter i(msTextBuf); + for (i.rewind(); i.next();) + { + if (*(i()) == ASCII_SPACE) + iNumConsecutiveSpaces++; + else + iNumConsecutiveSpaces = 0; + + if (iNumConsecutiveSpaces > 1) { + if (sTemp.len() > 0) { + pHandler->characters(sTemp); + sTemp.clear(); + } + pHandler->startElement("text:s", xBlankAttrList); + pHandler->endElement("text:s"); + } + else { + sTemp.append(i()); + } + } + pHandler->characters(sTemp); +} diff --git a/writerperfect/source/filter/DocumentElement.hxx b/writerperfect/source/filter/DocumentElement.hxx new file mode 100644 index 000000000000..bcfabd8015d8 --- /dev/null +++ b/writerperfect/source/filter/DocumentElement.hxx @@ -0,0 +1,99 @@ +/* DocumentElement: The items we are collecting to be put into the Writer + * document: paragraph and spans of text, as well as section breaks. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#ifndef _DOCUMENTELEMENT_H +#define _DOCUMENTELEMENT_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#include <libwpd/WPXProperty.h> +#include <libwpd/WPXString.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif +#include <vector> + +#include "DocumentHandler.hxx" + +class DocumentElement +{ +public: + virtual ~DocumentElement() {} + virtual void write(DocumentHandler *pHandler) const = 0; + virtual void print() const {} +}; + +class TagElement : public DocumentElement +{ +public: + TagElement(const char *szTagName) : msTagName(szTagName) {} + const WPXString & getTagName() const { return msTagName; } + virtual void print() const; +private: + WPXString msTagName; +}; + +class TagOpenElement : public TagElement +{ +public: + TagOpenElement(const char *szTagName) : TagElement(szTagName) {} + ~TagOpenElement() {} + void addAttribute(const char *szAttributeName, const WPXString &sAttributeValue); + virtual void write(DocumentHandler *pHandler) const; + virtual void print () const; +private: + WPXPropertyList maAttrList; +}; + +class TagCloseElement : public TagElement +{ +public: + TagCloseElement(const char *szTagName) : TagElement(szTagName) {} + virtual void write(DocumentHandler *pHandler) const; +}; + +class CharDataElement : public DocumentElement +{ +public: + CharDataElement(const char *sData) : DocumentElement(), msData(sData) {} + virtual void write(DocumentHandler *pHandler) const; +private: + WPXString msData; +}; + +class TextElement : public DocumentElement +{ +public: + TextElement(const WPXString & sTextBuf); + virtual void write(DocumentHandler *pHandler) const; + +private: + WPXString msTextBuf; +}; + +#endif diff --git a/writerperfect/source/filter/DocumentHandler.cxx b/writerperfect/source/filter/DocumentHandler.cxx new file mode 100644 index 000000000000..5877b8acd5df --- /dev/null +++ b/writerperfect/source/filter/DocumentHandler.cxx @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2004 William Lachance (william.lachance@sympatico.ca) + * Copyright (C) 2004 Net Integration Technologies (http://www.net-itech.com) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ +#include "DocumentHandler.hxx" +#include "FilterInternal.hxx" + +#include <string.h> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/xml/sax/XAttributeList.hpp> + +#ifndef _ATTRLIST_HPP_ +#include <xmloff/attrlist.hxx> +#endif + +using namespace ::rtl; +using rtl::OUString; + +using com::sun::star::xml::sax::XAttributeList; + +DocumentHandler::DocumentHandler(Reference < XDocumentHandler > &xHandler) : + mxHandler(xHandler) +{ +} + +void DocumentHandler::startDocument() +{ + WRITER_DEBUG_MSG(("DocumentHandler::startDocument")); + mxHandler->startDocument(); +} + +void DocumentHandler::endDocument() +{ + WRITER_DEBUG_MSG(("DocumentHandler::endDocument")); + mxHandler->endDocument(); +} + +void DocumentHandler::startElement(const char *psName, const WPXPropertyList &xPropList) +{ + WRITER_DEBUG_MSG(("DocumentHandler::startElement")); + SvXMLAttributeList *pAttrList = new SvXMLAttributeList(); + Reference < XAttributeList > xAttrList(pAttrList); + WPXPropertyList::Iter i(xPropList); + for (i.rewind(); i.next(); ) + { + // filter out libwpd elements + if (strlen(i.key()) > 6 && strncmp(i.key(), "libwpd", 6) != 0) + pAttrList->AddAttribute(OUString::createFromAscii(i.key()), + OUString::createFromAscii(i()->getStr().cstr())); + } + + mxHandler->startElement(OUString::createFromAscii(psName), xAttrList); +} + +void DocumentHandler::endElement(const char *psName) +{ + WRITER_DEBUG_MSG(("DocumentHandler::endElement")); + mxHandler->endElement(OUString::createFromAscii(psName)); +} + +void DocumentHandler::characters(const WPXString &sCharacters) +{ + WRITER_DEBUG_MSG(("DocumentHandler::characters")); + OUString sCharU16(sCharacters.cstr(), strlen(sCharacters.cstr()), RTL_TEXTENCODING_UTF8); + mxHandler->characters(sCharU16); +} diff --git a/writerperfect/source/filter/DocumentHandler.hxx b/writerperfect/source/filter/DocumentHandler.hxx new file mode 100644 index 000000000000..350157d17aa8 --- /dev/null +++ b/writerperfect/source/filter/DocumentHandler.hxx @@ -0,0 +1,31 @@ +#ifndef _OODOCUMENTHANDLER_HXX_ +#define _OODOCUMENTHANDLER_HXX_ + +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> + +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif + +using com::sun::star::uno::Reference; +using com::sun::star::xml::sax::XDocumentHandler; + +class DocumentHandler +{ +public: + DocumentHandler(Reference < XDocumentHandler > &xHandler); + void startDocument(); + void endDocument(); + void startElement(const char *psName, const WPXPropertyList &xPropList); + void endElement(const char *psName); + void characters(const WPXString &sCharacters); + +private: + Reference < XDocumentHandler > mxHandler; +}; + +#endif // _OODOCUMENTHANDLER_HXX_ diff --git a/writerperfect/source/filter/FilterInternal.hxx b/writerperfect/source/filter/FilterInternal.hxx new file mode 100644 index 000000000000..adc993c6d9d3 --- /dev/null +++ b/writerperfect/source/filter/FilterInternal.hxx @@ -0,0 +1,31 @@ +/* FilterInternal: Debugging information + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ +#include <stdio.h> +#ifdef DEBUG +#define WRITER_DEBUG_MSG(M) printf M +#else +#define WRITER_DEBUG_MSG(M) +#endif + +const float fDefaultSideMargin = 1.0f; // inches +const float fDefaultPageWidth = 8.5f; // inches (OOo required default: we will handle this later) +const float fDefaultPageHeight = 11.0f; // inches diff --git a/writerperfect/source/filter/FontStyle.cxx b/writerperfect/source/filter/FontStyle.cxx new file mode 100644 index 000000000000..de7cc47002dc --- /dev/null +++ b/writerperfect/source/filter/FontStyle.cxx @@ -0,0 +1,50 @@ +/* FontStyle: Stores (and writes) font-based information that is needed at + * the head of an OO document. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "FontStyle.hxx" +#include "WriterProperties.hxx" +#include "DocumentElement.hxx" + +FontStyle::FontStyle(const char *psName, const char *psFontFamily) : Style(psName), + msFontFamily(psFontFamily), + msFontPitch(IMP_DEFAULT_FONT_PITCH) +{ +} + +FontStyle::~FontStyle() +{ +} + +void FontStyle::write(DocumentHandler *pHandler) const +{ + TagOpenElement styleOpen("style:font-decl"); + styleOpen.addAttribute("style:name", getName()); + styleOpen.addAttribute("fo:font-family", msFontFamily); + styleOpen.addAttribute("style:font-pitch", msFontPitch); + styleOpen.write(pHandler); + TagCloseElement styleClose("style:font-decl"); + styleClose.write(pHandler); +} diff --git a/writerperfect/source/filter/FontStyle.hxx b/writerperfect/source/filter/FontStyle.hxx new file mode 100644 index 000000000000..be44cf140471 --- /dev/null +++ b/writerperfect/source/filter/FontStyle.hxx @@ -0,0 +1,52 @@ +/* FontStyle: Stores (and writes) font-based information that is needed at + * the head of an OO document. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ +#ifndef _FONTSTYLE_H +#define _FONTSTYLE_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif + +#include "Style.hxx" +#include "WriterProperties.hxx" + +class FontStyle : public Style +{ +public: + FontStyle(const char *psName, const char *psFontFamily); + ~FontStyle(); + virtual void write(DocumentHandler *pHandler) const; + const WPXString &getFontFamily() const { return msFontFamily; } + +private: + WPXString msFontFamily; + WPXString msFontPitch; +}; +#endif diff --git a/writerperfect/source/filter/ListStyle.cxx b/writerperfect/source/filter/ListStyle.cxx new file mode 100644 index 000000000000..b320022caf56 --- /dev/null +++ b/writerperfect/source/filter/ListStyle.cxx @@ -0,0 +1,161 @@ +/* ListStyle: Stores (and writes) list-based information that is + * needed at the head of an OO document. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "FilterInternal.hxx" +#include "ListStyle.hxx" +#include "DocumentElement.hxx" + +OrderedListLevelStyle::OrderedListLevelStyle(const WPXPropertyList &xPropList) : + mPropList(xPropList) +{ +} + +void OrderedListStyle::updateListLevel(const int iLevel, const WPXPropertyList &xPropList) +{ + if (iLevel < 0) + return; + if (!isListLevelDefined(iLevel)) + setListLevel(iLevel, new OrderedListLevelStyle(xPropList)); +} + +void OrderedListLevelStyle::write(DocumentHandler *pHandler, int iLevel) const +{ + WPXString sLevel; + sLevel.sprintf("%i", (iLevel+1)); + + TagOpenElement listLevelStyleOpen("text:list-level-style-number"); + listLevelStyleOpen.addAttribute("text:level", sLevel); + listLevelStyleOpen.addAttribute("text:style-name", "Numbering Symbols"); + if (mPropList["style:num-prefix"]) + listLevelStyleOpen.addAttribute("style:num-prefix", mPropList["style:num-prefix"]->getStr()); + if (mPropList["style:num-suffix"]) + listLevelStyleOpen.addAttribute("style:num-suffix", mPropList["style:num-suffix"]->getStr()); + if (mPropList["style:num-format"]) + listLevelStyleOpen.addAttribute("style:num-format", mPropList["style:num-format"]->getStr()); + if (mPropList["text:start-value"]) + listLevelStyleOpen.addAttribute("text:start-value", mPropList["text:start-value"]->getStr()); + listLevelStyleOpen.write(pHandler); + + TagOpenElement stylePropertiesOpen("style:properties"); + if (mPropList["text:space-before"]) + stylePropertiesOpen.addAttribute("text:space-before", mPropList["text:space-before"]->getStr()); + if (mPropList["text:min-label-width"]) + stylePropertiesOpen.addAttribute("text:min-label-width", mPropList["text:min-label-width"]->getStr()); + if (mPropList["text:min-label-distance"]) + stylePropertiesOpen.addAttribute("text:min-label-distance", mPropList["text:min-label-distance"]->getStr()); + stylePropertiesOpen.write(pHandler); + + pHandler->endElement("style:properties"); + pHandler->endElement("text:list-level-style-number"); +} + +UnorderedListLevelStyle::UnorderedListLevelStyle(const WPXPropertyList &xPropList) + : mPropList(xPropList) +{ +} + +void UnorderedListStyle::updateListLevel(const int iLevel, const WPXPropertyList &xPropList) +{ + if (iLevel < 0) + return; + if (!isListLevelDefined(iLevel)) + setListLevel(iLevel, new UnorderedListLevelStyle(xPropList)); +} + +void UnorderedListLevelStyle::write(DocumentHandler *pHandler, int iLevel) const +{ + WPXString sLevel; + sLevel.sprintf("%i", (iLevel+1)); + TagOpenElement listLevelStyleOpen("text:list-level-style-bullet"); + listLevelStyleOpen.addAttribute("text:level", sLevel); + listLevelStyleOpen.addAttribute("text:style-name", "Bullet Symbols"); + listLevelStyleOpen.addAttribute("style:num-suffice", "."); + if (mPropList["text:bullet-char"]) + listLevelStyleOpen.addAttribute("text:bullet-char", mPropList["text:bullet-char"]->getStr()); + listLevelStyleOpen.write(pHandler); + + TagOpenElement stylePropertiesOpen("style:properties"); + if (mPropList["text:space-before"]) + stylePropertiesOpen.addAttribute("text:space-before", mPropList["text:space-before"]->getStr()); + if (mPropList["text:min-label-width"]) + stylePropertiesOpen.addAttribute("text:min-label-width", mPropList["text:min-label-width"]->getStr()); + if (mPropList["text:min-label-distance"]) + stylePropertiesOpen.addAttribute("text:min-label-distance", mPropList["text:min-label-distance"]->getStr()); + stylePropertiesOpen.addAttribute("style:font-name", "OpenSymbol"); + stylePropertiesOpen.write(pHandler); + + pHandler->endElement("style:properties"); + pHandler->endElement("text:list-level-style-bullet"); +} + +ListStyle::ListStyle(const char *psName, const int iListID) : + Style(psName), + miListID(iListID) +{ + for (int i=0; i<WP6_NUM_LIST_LEVELS; i++) + mppListLevels[i] = NULL; + +} + +ListStyle::~ListStyle() +{ + for (int i=0; i<WP6_NUM_LIST_LEVELS; i++) { + if (mppListLevels[i]) + delete(mppListLevels[i]); + } + +} + +bool ListStyle::isListLevelDefined(int iLevel) const +{ + if (mppListLevels[iLevel] == NULL) + return false; + + return true; +} + +void ListStyle::setListLevel(int iLevel, ListLevelStyle *iListLevelStyle) +{ + // can't uncomment this next line without adding some extra logic. + // figure out which is best: use the initial message, or constantly + // update? + if (mppListLevels[iLevel] == NULL) + mppListLevels[iLevel] = iListLevelStyle; +} + +void ListStyle::write(DocumentHandler *pHandler) const +{ + TagOpenElement listStyleOpenElement("text:list-style"); + listStyleOpenElement.addAttribute("style:name", getName()); + listStyleOpenElement.write(pHandler); + + for (int i=0; i<WP6_NUM_LIST_LEVELS; i++) { + if (mppListLevels[i] != NULL) + mppListLevels[i]->write(pHandler, i); + } + + pHandler->endElement("text:list-style"); +} diff --git a/writerperfect/source/filter/ListStyle.hxx b/writerperfect/source/filter/ListStyle.hxx new file mode 100644 index 000000000000..b2ebb07ef799 --- /dev/null +++ b/writerperfect/source/filter/ListStyle.hxx @@ -0,0 +1,101 @@ +/* ListStyle: Stores (and writes) list-based information that is + * needed at the head of an OO document. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ +#ifndef _LISTSTYLE_H +#define _LISTSTYLE_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif + +#define WP6_NUM_LIST_LEVELS 8 // see WP6FileStructure.h (we shouldn't need to reference this) + +#include "Style.hxx" +#include "WriterProperties.hxx" + +class DocumentElement; + +class ListLevelStyle +{ +public: + virtual ~ListLevelStyle() {}; + virtual void write(DocumentHandler *pHandler, int iLevel) const = 0; +}; + +class OrderedListLevelStyle : public ListLevelStyle +{ +public: + OrderedListLevelStyle(const WPXPropertyList &xPropList); + void write(DocumentHandler *pHandler, int iLevel) const; +private: + WPXPropertyList mPropList; +}; + +class UnorderedListLevelStyle : public ListLevelStyle +{ +public: + UnorderedListLevelStyle(const WPXPropertyList &xPropList); + void write(DocumentHandler *pHandler, int iLevel) const; +private: + WPXPropertyList mPropList; +}; + +class ListStyle : public Style +{ +public: + ListStyle(const char *psName, const int iListID); + virtual ~ListStyle(); + virtual void updateListLevel(const int iLevel, const WPXPropertyList &xPropList) = 0; + virtual void write(DocumentHandler *pHandler) const; + int getListID() const { return miListID; } + bool isListLevelDefined(int iLevel) const; + +protected: + void setListLevel(int iLevel, ListLevelStyle *iListLevelStyle); + +private: + ListLevelStyle *mppListLevels[WP6_NUM_LIST_LEVELS]; + int miNumListLevels; + const int miListID; +}; + +class OrderedListStyle : public ListStyle +{ +public: + OrderedListStyle(const char *psName, const int iListID) : ListStyle(psName, iListID) {} + void updateListLevel(const int iLevel, const WPXPropertyList &xPropList); +}; + +class UnorderedListStyle : public ListStyle +{ +public: + UnorderedListStyle(const char *psName, const int iListID) : ListStyle(psName, iListID) {} + void updateListLevel(const int iLevel, const WPXPropertyList &xPropList); +}; +#endif diff --git a/writerperfect/source/filter/PageSpan.cxx b/writerperfect/source/filter/PageSpan.cxx new file mode 100644 index 000000000000..4ac5797e6d01 --- /dev/null +++ b/writerperfect/source/filter/PageSpan.cxx @@ -0,0 +1,173 @@ +/* SectionStyle: Stores (and writes) section-based information (e.g.: a column + * break needs a new section) that is needed at the head of an OO document and + * is referenced throughout the entire document + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "FilterInternal.hxx" +#include "PageSpan.hxx" +#include "DocumentElement.hxx" + +PageSpan::PageSpan(const WPXPropertyList &xPropList) : + mxPropList(xPropList), + mpHeaderContent(NULL), + mpFooterContent(NULL), + mpHeaderLeftContent(NULL), + mpFooterLeftContent(NULL) +{ +} + +PageSpan::~PageSpan() +{ + typedef std::vector<DocumentElement *>::iterator DEVIter; + + if (mpHeaderContent) + { + for (DEVIter iterHeaderContent = mpHeaderContent->begin(); + iterHeaderContent != mpHeaderContent->end(); + iterHeaderContent++) + delete(*iterHeaderContent); + delete mpHeaderContent; + } + + if (mpHeaderLeftContent) + { + for (DEVIter iterHeaderLeftContent = mpHeaderLeftContent->begin(); + iterHeaderLeftContent != mpHeaderLeftContent->end(); + iterHeaderLeftContent++) + delete(*iterHeaderLeftContent); + delete mpHeaderLeftContent; + } + + if (mpFooterContent) + { + for (DEVIter iterFooterContent = mpFooterContent->begin(); + iterFooterContent != mpFooterContent->end(); + iterFooterContent++) + delete(*iterFooterContent); + delete mpFooterContent; + } + + if (mpFooterLeftContent) + { + for (DEVIter iterFooterLeftContent = mpFooterLeftContent->begin(); + iterFooterLeftContent != mpFooterLeftContent->end(); + iterFooterLeftContent++) + delete(*iterFooterLeftContent); + delete mpFooterLeftContent; + } +} + +int PageSpan::getSpan() const +{ + if (mxPropList["libwpd:num-pages"]) + return mxPropList["libwpd:num-pages"]->getInt(); + + return 0; // should never happen +} + +void PageSpan::writePageMaster(const int iNum, DocumentHandler *pHandler) const +{ + WPXPropertyList propList; + + WPXString sPageMasterName; + sPageMasterName.sprintf("PM%i", iNum /* +2 */); + propList.insert("style:name", sPageMasterName); + + pHandler->startElement("style:page-master", propList); + + WPXPropertyList tempPropList = mxPropList; + if (!tempPropList["style:writing-mode"]) + tempPropList.insert("style:writing-mode", WPXString("lr-tb")); + if (!tempPropList["style:footnote-max-height"]) + tempPropList.insert("style:footnote-max-height", WPXString("0inch")); + pHandler->startElement("style:properties", tempPropList); + + WPXPropertyList footnoteSepPropList; + footnoteSepPropList.insert("style:width", WPXString("0.0071inch")); + footnoteSepPropList.insert("style:distance-before-sep", WPXString("0.0398inch")); + footnoteSepPropList.insert("style:distance-after-sep", WPXString("0.0398inch")); + footnoteSepPropList.insert("style:adjustment", WPXString("left")); + footnoteSepPropList.insert("style:rel-width", WPXString("25%")); + footnoteSepPropList.insert("style:color", WPXString("#000000")); + pHandler->startElement("style:footnote-sep", footnoteSepPropList); + + pHandler->endElement("style:footnote-sep"); + pHandler->endElement("style:properties"); + pHandler->endElement("style:page-master"); +} + +void PageSpan::writeMasterPages(const int iStartingNum, const int iPageMasterNum, const bool bLastPageSpan, + DocumentHandler *pHandler) const +{ + int iSpan = 0; + (bLastPageSpan) ? iSpan = 1 : iSpan = getSpan(); + + for (int i=iStartingNum; i<(iStartingNum+iSpan); i++) + { + TagOpenElement masterPageOpen("style:master-page"); + WPXString sMasterPageName; + sMasterPageName.sprintf("Page Style %i", i); + WPXString sPageMasterName; + sPageMasterName.sprintf("PM%i", iPageMasterNum /* +2 */); + WPXPropertyList propList; + propList.insert("style:name", sMasterPageName); + propList.insert("style:page-master-name", sPageMasterName); + if (!bLastPageSpan) + { + WPXString sNextMasterPageName; + sNextMasterPageName.sprintf("Page Style %i", (i+1)); + propList.insert("style:next-style-name", sNextMasterPageName); + } + pHandler->startElement("style:master-page", propList); + + if (mpHeaderContent) + _writeHeaderFooter("style:header", *mpHeaderContent, pHandler); + if (mpHeaderLeftContent) + _writeHeaderFooter("style:header-left", *mpHeaderLeftContent, pHandler); + if (mpFooterContent) + _writeHeaderFooter("style:footer", *mpFooterContent, pHandler); + if (mpFooterLeftContent) + _writeHeaderFooter("style:footer-left", *mpFooterLeftContent, pHandler); + + pHandler->endElement("style:master-page"); + } + +} + +void PageSpan::_writeHeaderFooter(const char *headerFooterTagName, + const std::vector<DocumentElement *> & headerFooterContent, + DocumentHandler *pHandler) const +{ + TagOpenElement headerFooterOpen(headerFooterTagName); + headerFooterOpen.write(pHandler); + for (std::vector<DocumentElement *>::const_iterator iter = headerFooterContent.begin(); + iter != headerFooterContent.end(); + iter++) { + (*iter)->write(pHandler); + } + TagCloseElement headerFooterClose(headerFooterTagName); + headerFooterClose.write(pHandler); +} + diff --git a/writerperfect/source/filter/PageSpan.hxx b/writerperfect/source/filter/PageSpan.hxx new file mode 100644 index 000000000000..7edbfaee8002 --- /dev/null +++ b/writerperfect/source/filter/PageSpan.hxx @@ -0,0 +1,65 @@ +/* PageSpan: Stores (and writes) page-based information (e.g.: margins, + * headers/footers) + * + * Copyright (C) 2002-2004 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ +#ifndef _PAGESPAN_H +#define _PAGESPAN_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif +#include <vector> + +class DocumentElement; +class DocumentHandler; + +class PageSpan +{ +public: + PageSpan(const WPXPropertyList &xPropList); + virtual ~PageSpan(); + void writePageMaster(const int iNum, DocumentHandler *pHandler) const; + void writeMasterPages(const int iStartingNum, const int iPageMasterNum, const bool bLastPageSpan, DocumentHandler *pHandler) const; + int getSpan() const; + + const std::vector<DocumentElement *> * getHeaderContent() const { return mpHeaderContent; } + void setHeaderContent(std::vector<DocumentElement *> * pHeaderContent) { mpHeaderContent = pHeaderContent; } + void setFooterContent(std::vector<DocumentElement *> * pFooterContent) { mpFooterContent = pFooterContent; } + void setHeaderLeftContent(std::vector<DocumentElement *> * pHeaderContent) { mpHeaderLeftContent = pHeaderContent; } + void setFooterLeftContent(std::vector<DocumentElement *> * pFooterContent) { mpFooterLeftContent = pFooterContent; } +protected: + void _writeHeaderFooter(const char *headerFooterTagName, const std::vector<DocumentElement *> & headerFooterContent, + DocumentHandler *pHandler) const; +private: + WPXPropertyList mxPropList; + std::vector<DocumentElement *> * mpHeaderContent; + std::vector<DocumentElement *> * mpFooterContent; + std::vector<DocumentElement *> * mpHeaderLeftContent; + std::vector<DocumentElement *> * mpFooterLeftContent; +}; +#endif diff --git a/writerperfect/source/filter/SectionStyle.cxx b/writerperfect/source/filter/SectionStyle.cxx new file mode 100644 index 000000000000..51dd9fc398f1 --- /dev/null +++ b/writerperfect/source/filter/SectionStyle.cxx @@ -0,0 +1,86 @@ +/* SectionStyle: Stores (and writes) section-based information (e.g.: a column + * break needs a new section) that is needed at the head of an OO document and + * is referenced throughout the entire document + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "FilterInternal.hxx" +#include "SectionStyle.hxx" +#include "DocumentElement.hxx" +#include <math.h> + +#ifdef _MSC_VER +double rint(double x); +#endif /* _WIN32 */ + +SectionStyle::SectionStyle(const WPXPropertyList &xPropList, + const WPXPropertyListVector &xColumns, + const char *psName) : + Style(psName), + mPropList(xPropList), + mColumns(xColumns) +{ +} + +void SectionStyle::write(DocumentHandler *pHandler) const +{ + TagOpenElement styleOpen("style:style"); + styleOpen.addAttribute("style:name", getName()); + styleOpen.addAttribute("style:family", "section"); + styleOpen.write(pHandler); + + // if the number of columns is <= 1, we will never come here. This is only an additional check + // style properties + pHandler->startElement("style:properties", mPropList); + + // column properties + WPXPropertyList columnProps; + + if (mColumns.count() > 1) + { + columnProps.insert("fo:column-count", (int)mColumns.count()); + pHandler->startElement("style:columns", columnProps); + + WPXPropertyListVector::Iter i(mColumns); + for (i.rewind(); i.next();) + { + pHandler->startElement("style:column", i()); + pHandler->endElement("style:column"); + } + } + else + { + columnProps.insert("fo:column-count", 0); + columnProps.insert("fo:column-gap", 0.0f); + pHandler->startElement("style:columns", columnProps); + } + + pHandler->endElement("style:columns"); + + + pHandler->endElement("style:properties"); + + pHandler->endElement("style:style"); +} diff --git a/writerperfect/source/filter/SectionStyle.hxx b/writerperfect/source/filter/SectionStyle.hxx new file mode 100644 index 000000000000..2e914824b550 --- /dev/null +++ b/writerperfect/source/filter/SectionStyle.hxx @@ -0,0 +1,52 @@ +/* SectionStyle: Stores (and writes) section-based information (e.g.: a column + * change needs a new section) that is needed at the head of an OO document. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ +#ifndef _SECTIONSTYLE_H +#define _SECTIONSTYLE_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#include <libwpd/WPXPropertyListVector.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif + +#include "Style.hxx" +#include "WriterProperties.hxx" + + +class SectionStyle : public Style +{ +public: + SectionStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &xColumns, const char *psName); + virtual void write(DocumentHandler *pHandler) const; + +private: + WPXPropertyList mPropList; + WPXPropertyListVector mColumns; +}; +#endif diff --git a/writerperfect/source/filter/Style.hxx b/writerperfect/source/filter/Style.hxx new file mode 100644 index 000000000000..f7e2233e0b80 --- /dev/null +++ b/writerperfect/source/filter/Style.hxx @@ -0,0 +1,63 @@ +/* Style: A base class from which all other styles are inherited, includes + * a name. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#ifndef _STYLE_H +#define _STYLE_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif +#include "DocumentElement.hxx" + +class TopLevelElementStyle +{ +public: + TopLevelElementStyle() : mpsMasterPageName(NULL) { } + virtual ~TopLevelElementStyle() { if (mpsMasterPageName) delete mpsMasterPageName; } + void setMasterPageName(WPXString &sMasterPageName) { mpsMasterPageName = new WPXString(sMasterPageName); } + const WPXString * getMasterPageName() const { return mpsMasterPageName; } + +private: + WPXString *mpsMasterPageName; +}; + +class Style +{ + public: + Style(const WPXString &psName) : msName(psName) {} + virtual ~Style() {} + + virtual void write(DocumentHandler * /* pHandler */) const {}; + const WPXString &getName() const { return msName; } + + private: + WPXString msName; +}; +#endif diff --git a/writerperfect/source/filter/TableStyle.cxx b/writerperfect/source/filter/TableStyle.cxx new file mode 100644 index 000000000000..8d12427ba87b --- /dev/null +++ b/writerperfect/source/filter/TableStyle.cxx @@ -0,0 +1,163 @@ +/* TableStyle: Stores (and writes) table-based information that is + * needed at the head of an OO document. + * + * Copyright (C) 2002-2004 William Lachance (william.lachance@sympatico.ca) + * Copyright (C) 2004 Net Integration Technologies, Inc. (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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <math.h> +#include <string.h> +#include "FilterInternal.hxx" +#include "TableStyle.hxx" +#include "DocumentElement.hxx" + +#ifdef _MSC_VER +#include <minmax.h> +#endif + +TableCellStyle::TableCellStyle(const WPXPropertyList &xPropList, const char *psName) : + Style(psName), + mPropList(xPropList) +{ +} + +void TableCellStyle::write(DocumentHandler *pHandler) const +{ + TagOpenElement styleOpen("style:style"); + styleOpen.addAttribute("style:name", getName()); + styleOpen.addAttribute("style:family", "table-cell"); + styleOpen.write(pHandler); + + // WLACH_REFACTORING: Only temporary.. a much better solution is to + // generalize this sort of thing into the "Style" superclass + WPXPropertyList stylePropList; + WPXPropertyList::Iter i(mPropList); + for (i.rewind(); i.next();) + { + if (strlen(i.key()) > 2 && strncmp(i.key(), "fo", 2) == 0) + stylePropList.insert(i.key(), i()->clone()); + } + stylePropList.insert("fo:padding", "0.0382inch"); + pHandler->startElement("style:properties", stylePropList); + pHandler->endElement("style:properties"); + + pHandler->endElement("style:style"); +} + +TableRowStyle::TableRowStyle(const WPXPropertyList &propList, const char *psName) : + Style(psName), + mPropList(propList) +{ +} + +void TableRowStyle::write(DocumentHandler *pHandler) const +{ + TagOpenElement styleOpen("style:style"); + styleOpen.addAttribute("style:name", getName()); + styleOpen.addAttribute("style:family", "table-row"); + styleOpen.write(pHandler); + + TagOpenElement stylePropertiesOpen("style:properties"); + if (mPropList["style:min-row-height"]) + stylePropertiesOpen.addAttribute("style:min-row-height", mPropList["style:min-row-height"]->getStr()); + else if (mPropList["style:row-height"]) + stylePropertiesOpen.addAttribute("style:row-height", mPropList["style:row-height"]->getStr()); + stylePropertiesOpen.write(pHandler); + pHandler->endElement("style:properties"); + + pHandler->endElement("style:style"); +} + + +TableStyle::TableStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &columns, const char *psName) : + Style(psName), + mPropList(xPropList), + mColumns(columns) +{ +} + +TableStyle::~TableStyle() +{ + typedef std::vector<TableCellStyle *>::iterator TCSVIter; + typedef std::vector<TableRowStyle *>::iterator TRSVIter; + for (TCSVIter iterTableCellStyles = mTableCellStyles.begin() ; iterTableCellStyles != mTableCellStyles.end(); iterTableCellStyles++) + delete(*iterTableCellStyles); + for (TRSVIter iterTableRowStyles = mTableRowStyles.begin() ; iterTableRowStyles != mTableRowStyles.end(); iterTableRowStyles++) + delete(*iterTableRowStyles); + +} + +void TableStyle::write(DocumentHandler *pHandler) const +{ + TagOpenElement styleOpen("style:style"); + styleOpen.addAttribute("style:name", getName()); + styleOpen.addAttribute("style:family", "table"); + if (getMasterPageName()) + styleOpen.addAttribute("style:master-page-name", getMasterPageName()->cstr()); + styleOpen.write(pHandler); + + TagOpenElement stylePropertiesOpen("style:properties"); + if (mPropList["table:align"]) + stylePropertiesOpen.addAttribute("table:align", mPropList["table:align"]->getStr()); + if (mPropList["fo:margin-left"]) + stylePropertiesOpen.addAttribute("fo:margin-left", mPropList["fo:margin-left"]->getStr()); + if (mPropList["fo:margin-right"]) + stylePropertiesOpen.addAttribute("fo:margin-right", mPropList["fo:margin-right"]->getStr()); + if (mPropList["style:width"]) + stylePropertiesOpen.addAttribute("style:width", mPropList["style:width"]->getStr()); + if (mPropList["fo:break-before"]) + stylePropertiesOpen.addAttribute("fo:break-before", mPropList["fo:break-before"]->getStr()); + stylePropertiesOpen.write(pHandler); + + pHandler->endElement("style:properties"); + + pHandler->endElement("style:style"); + + int i=1; + WPXPropertyListVector::Iter j(mColumns); + for (j.rewind(); j.next();) + { + TagOpenElement styleNestedOpen("style:style"); + WPXString sColumnName; + sColumnName.sprintf("%s.Column%i", getName().cstr(), i); + styleNestedOpen.addAttribute("style:name", sColumnName); + styleNestedOpen.addAttribute("style:family", "table-column"); + styleNestedOpen.write(pHandler); + + pHandler->startElement("style:properties", j()); + pHandler->endElement("style:properties"); + + pHandler->endElement("style:style"); + + i++; + } + + typedef std::vector<TableRowStyle *>::const_iterator TRSVIter; + for (TRSVIter iterTableRow = mTableRowStyles.begin() ; iterTableRow != mTableRowStyles.end(); iterTableRow++) + (*iterTableRow)->write(pHandler); + + typedef std::vector<TableCellStyle *>::const_iterator TCSVIter; + for (TCSVIter iterTableCell = mTableCellStyles.begin() ; iterTableCell != mTableCellStyles.end(); iterTableCell++) + (*iterTableCell)->write(pHandler); +} diff --git a/writerperfect/source/filter/TableStyle.hxx b/writerperfect/source/filter/TableStyle.hxx new file mode 100644 index 000000000000..a4c7116edb6d --- /dev/null +++ b/writerperfect/source/filter/TableStyle.hxx @@ -0,0 +1,80 @@ +/* TableStyle: Stores (and writes) table-based information that is + * needed at the head of an OO document. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ +#ifndef _TABLESTYLE_H +#define _TABLESTYLE_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif +#include <vector> + +#include "Style.hxx" +#include "WriterProperties.hxx" + +class DocumentElement; +class DocumentHandler; + +class TableCellStyle : public Style +{ +public: + TableCellStyle(const WPXPropertyList &xPropList, const char *psName); + virtual void write(DocumentHandler *pHandler) const; +private: + WPXPropertyList mPropList; +}; + +class TableRowStyle : public Style +{ +public: + TableRowStyle(const WPXPropertyList &propList, const char *psName); + virtual void write(DocumentHandler *pHandler) const; +private: + WPXPropertyList mPropList; +}; + +class TableStyle : public Style, public TopLevelElementStyle +{ +public: + TableStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &columns, const char *psName); + ~TableStyle(); + virtual void write(DocumentHandler *pHandler) const; + int getNumColumns() const { return mColumns.count(); } + void addTableCellStyle(TableCellStyle *pTableCellStyle) { mTableCellStyles.push_back(pTableCellStyle); } + int getNumTableCellStyles() { return mTableCellStyles.size(); } + void addTableRowStyle(TableRowStyle *pTableRowStyle) { mTableRowStyles.push_back(pTableRowStyle); } + int getNumTableRowStyles() { return mTableRowStyles.size(); } +private: + WPXPropertyList mPropList; + WPXPropertyListVector mColumns; + std::vector<TableCellStyle *> mTableCellStyles; + std::vector<TableRowStyle *> mTableRowStyles; +}; +#endif diff --git a/writerperfect/source/filter/TextRunStyle.cxx b/writerperfect/source/filter/TextRunStyle.cxx new file mode 100644 index 000000000000..f3e8b0499956 --- /dev/null +++ b/writerperfect/source/filter/TextRunStyle.cxx @@ -0,0 +1,162 @@ +/* TextRunStyle: Stores (and writes) paragraph/span-style-based information + * (e.g.: a paragraph might be bold) that is needed at the head of an OO + * document. + * + * Copyright (C) 2002-2004 William Lachance (william.lachance@sympatico.ca) + * Copyright (C) 2004 Net Integration Technologies, Inc. (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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "FilterInternal.hxx" +#include "TextRunStyle.hxx" +#include "WriterProperties.hxx" +#include "DocumentElement.hxx" + +#ifdef _MSC_VER +#include <minmax.h> +#endif + +#include <string.h> + +ParagraphStyle::ParagraphStyle(WPXPropertyList *pPropList, const WPXPropertyListVector &xTabStops, const WPXString &sName) : + mpPropList(pPropList), + mxTabStops(xTabStops), + msName(sName) +{ +} + +ParagraphStyle::~ParagraphStyle() +{ + delete mpPropList; +} + +void ParagraphStyle::write(DocumentHandler *pHandler) const +{ + WRITER_DEBUG_MSG(("Writing a paragraph style..\n")); + + WPXPropertyList propList; + propList.insert("style:name", msName.cstr()); + propList.insert("style:family", "paragraph"); + propList.insert("style:parent-style-name", (*mpPropList)["style:parent-style-name"]->getStr()); + if ((*mpPropList)["style:master-page-name"]) + propList.insert("style:master-page-name", (*mpPropList)["style:master-page-name"]->getStr()); + pHandler->startElement("style:style", propList); + + propList.clear(); + WPXPropertyList::Iter k((*mpPropList)); + for (k.rewind(); k.next(); ) + { + if (strcmp(k.key(), "style:list-style-name") == 0) + propList.insert("style:list-style-name", k()->getStr()); + if (strcmp(k.key(), "fo:margin-left") == 0) + propList.insert("fo:margin-left", k()->getStr()); + if (strcmp(k.key(), "fo:margin-right") == 0) + propList.insert("fo:margin-right", k()->getStr()); + if (strcmp(k.key(), "fo:text-indent") == 0) + propList.insert("fo:text-indent", k()->getStr()); + if (strcmp(k.key(), "fo:margin-top") == 0) + propList.insert("fo:margin-top", k()->getStr()); + if (strcmp(k.key(), "fo:margin-bottom") == 0) + propList.insert("fo:margin-bottom", k()->getStr()); + if (strcmp(k.key(), "fo:line-height") == 0) + propList.insert("fo:line-height", k()->getStr()); + if (strcmp(k.key(), "fo:break-before") == 0) + propList.insert("fo:break-before", k()->getStr()); + if (strcmp(k.key(), "fo:text-align") == 0) + propList.insert("fo:text-align", k()->getStr()); + if (strcmp(k.key(), "fo:text-align-last") == 0) + propList.insert("fo:text-align-last", k()->getStr()); + } + + propList.insert("style:justify-single-word", "false"); + pHandler->startElement("style:properties", propList); + + if (mxTabStops.count() > 0) + { + TagOpenElement tabListOpen("style:tab-stops"); + tabListOpen.write(pHandler); + WPXPropertyListVector::Iter i(mxTabStops); + for (i.rewind(); i.next();) + { + TagOpenElement tabStopOpen("style:tab-stop"); + + WPXPropertyList::Iter j(i()); + for (j.rewind(); j.next(); ) + { + tabStopOpen.addAttribute(j.key(), j()->getStr().cstr()); + } + tabStopOpen.write(pHandler); + pHandler->endElement("style:tab-stop"); + } + pHandler->endElement("style:tab-stops"); + } + + pHandler->endElement("style:properties"); + pHandler->endElement("style:style"); +} + +SpanStyle::SpanStyle(const char *psName, const WPXPropertyList &xPropList) : + Style(psName), + mPropList(xPropList) +{ +} + +void SpanStyle::write(DocumentHandler *pHandler) const +{ + WRITER_DEBUG_MSG(("Writing a span style..\n")); + WPXPropertyList styleOpenList; + styleOpenList.insert("style:name", getName()); + styleOpenList.insert("style:family", "text"); + pHandler->startElement("style:style", styleOpenList); + + WPXPropertyList propList(mPropList); + + if (mPropList["style:font-name"]) + { + propList.insert("style:font-name-asian", mPropList["style:font-name"]->getStr()); + propList.insert("style:font-name-complex", mPropList["style:font-name"]->getStr()); + } + + if (mPropList["fo:font-size"]) + { + propList.insert("style:font-size-asian", mPropList["fo:font-size"]->getStr()); + propList.insert("style:font-size-complex", mPropList["fo:font-size"]->getStr()); + } + + if (mPropList["fo:font-weight"]) + { + propList.insert("style:font-weight-asian", mPropList["fo:font-weight"]->getStr()); + propList.insert("style:font-weight-complex", mPropList["fo:font-weight"]->getStr()); + } + + if (mPropList["fo:font-style"]) + { + propList.insert("style:font-style-asian", mPropList["fo:font-style"]->getStr()); + propList.insert("style:font-style-complex", mPropList["fo:font-style"]->getStr()); + } + + pHandler->startElement("style:properties", propList); + + pHandler->endElement("style:properties"); + pHandler->endElement("style:style"); +} diff --git a/writerperfect/source/filter/TextRunStyle.hxx b/writerperfect/source/filter/TextRunStyle.hxx new file mode 100644 index 000000000000..7d5905e9d412 --- /dev/null +++ b/writerperfect/source/filter/TextRunStyle.hxx @@ -0,0 +1,69 @@ +/* TextRunStyle: Stores (and writes) paragraph/span-style-based information + * (e.g.: a paragraph might be bold) that is needed at the head of an OO + * document. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#ifndef _TEXTRUNSTYLE_H +#define _TEXTRUNSTYLE_H +#if defined _MSC_VER +#pragma warning( push, 1 ) +#endif +#include <libwpd/libwpd.h> +#if defined _MSC_VER +#pragma warning( pop ) +#endif + +#include "Style.hxx" + +class TagOpenElement; +class DocumentElement; +class DocumentHandler; + +class ParagraphStyle +{ +public: + ParagraphStyle(WPXPropertyList *propList, const WPXPropertyListVector &tabStops, const WPXString &sName); + virtual ~ParagraphStyle(); + virtual void write(DocumentHandler *pHandler) const; + WPXString getName() const { return msName; } +private: + WPXPropertyList *mpPropList; + WPXPropertyListVector mxTabStops; + WPXString msName; +}; + + +class SpanStyle : public Style +{ +public: + SpanStyle(const char *psName, const WPXPropertyList &xPropList); + virtual void write(DocumentHandler *pHandler) const; + +private: + WPXPropertyList mPropList; +}; +#endif diff --git a/writerperfect/source/filter/WriterProperties.hxx b/writerperfect/source/filter/WriterProperties.hxx new file mode 100644 index 000000000000..8b6466ac406c --- /dev/null +++ b/writerperfect/source/filter/WriterProperties.hxx @@ -0,0 +1,36 @@ +/* WriterProperties: A grab bag of writer-specific properties which we use + * define here for later use. + * + * Copyright (C) 2002-2003 William Lachance (william.lachance@sympatico.ca) + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information visit http://libwpd.sourceforge.net + * + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ +#ifndef _WRITER_PROPERTIES_H +#define _WRITER_PROPERTIES_H + +#define IMP_DEFAULT_SUPER_SUB_SCRIPT "58%" +#define IMP_NUM_CENTIMETERES_PER_INCH 2.54f +#define IMP_DEFAULT_FONT_NAME "Times New Roman" +#define IMP_DEFAULT_FONT_SIZE 12.0f +#define IMP_DEFAULT_FONT_PITCH "variable" +#define IMP_DEFAULT_FONT_COLOR (new RGBSColor(0x00,0x00,0x00,0x64)) +#endif diff --git a/writerperfect/source/filter/makefile.mk b/writerperfect/source/filter/makefile.mk new file mode 100644 index 000000000000..e535d2aebbe0 --- /dev/null +++ b/writerperfect/source/filter/makefile.mk @@ -0,0 +1,27 @@ +PRJ=..$/.. + +PRJNAME=writerperfect +TARGET=filter +ENABLE_EXCEPTIONS=true + +.INCLUDE : settings.mk + +.IF "$(SYSTEM_LIBWPD)" == "YES" +INCPRE+=$(LIBWPD_CFLAGS) -I.. +.ELSE +# broken but ... necessary, internal include shafted ... +INCPRE+=-I.. +.ENDIF + +SLOFILES= \ + $(SLO)$/DocumentElement.obj \ + $(SLO)$/FontStyle.obj \ + $(SLO)$/ListStyle.obj \ + $(SLO)$/DocumentHandler.obj \ + $(SLO)$/PageSpan.obj \ + $(SLO)$/SectionStyle.obj \ + $(SLO)$/TableStyle.obj \ + $(SLO)$/TextRunStyle.obj \ + $(SLO)$/DocumentCollector.obj + +.INCLUDE : target.mk |