summaryrefslogtreecommitdiff
path: root/writerperfect/source
diff options
context:
space:
mode:
Diffstat (limited to 'writerperfect/source')
-rw-r--r--writerperfect/source/filter/DocumentCollector.cxx1312
-rw-r--r--writerperfect/source/filter/DocumentCollector.hxx251
-rw-r--r--writerperfect/source/filter/DocumentElement.cxx108
-rw-r--r--writerperfect/source/filter/DocumentElement.hxx100
-rw-r--r--writerperfect/source/filter/DocumentHandler.cxx99
-rw-r--r--writerperfect/source/filter/DocumentHandler.hxx36
-rw-r--r--writerperfect/source/filter/DocumentHandlerInterface.hxx45
-rw-r--r--writerperfect/source/filter/FilterInternal.hxx40
-rw-r--r--writerperfect/source/filter/FontStyle.cxx53
-rw-r--r--writerperfect/source/filter/FontStyle.hxx50
-rw-r--r--writerperfect/source/filter/GraphicsStyle.cxx40
-rw-r--r--writerperfect/source/filter/GraphicsStyle.hxx40
-rw-r--r--writerperfect/source/filter/InternalHandler.cxx54
-rw-r--r--writerperfect/source/filter/InternalHandler.hxx46
-rw-r--r--writerperfect/source/filter/ListStyle.cxx185
-rw-r--r--writerperfect/source/filter/ListStyle.hxx99
-rw-r--r--writerperfect/source/filter/OdgExporter.cxx648
-rw-r--r--writerperfect/source/filter/OdgExporter.hxx90
-rw-r--r--writerperfect/source/filter/PageSpan.cxx276
-rw-r--r--writerperfect/source/filter/PageSpan.hxx63
-rw-r--r--writerperfect/source/filter/SectionStyle.cxx89
-rw-r--r--writerperfect/source/filter/SectionStyle.hxx49
-rw-r--r--writerperfect/source/filter/Style.hxx60
-rw-r--r--writerperfect/source/filter/TableStyle.cxx167
-rw-r--r--writerperfect/source/filter/TableStyle.hxx85
-rw-r--r--writerperfect/source/filter/TextRunStyle.cxx179
-rw-r--r--writerperfect/source/filter/TextRunStyle.hxx65
-rw-r--r--writerperfect/source/filter/WriterProperties.hxx38
-rw-r--r--writerperfect/source/filter/makefile.mk38
-rw-r--r--writerperfect/source/stream/WPXSvStream.cxx172
-rw-r--r--writerperfect/source/stream/WPXSvStream.h49
-rw-r--r--writerperfect/source/stream/makefile.mk24
-rw-r--r--writerperfect/source/wpdimp/WordPerfectCollector.cxx62
-rw-r--r--writerperfect/source/wpdimp/WordPerfectCollector.hxx48
-rw-r--r--writerperfect/source/wpdimp/WordPerfectImportFilter.cxx434
-rw-r--r--writerperfect/source/wpdimp/WordPerfectImportFilter.hxx178
-rw-r--r--writerperfect/source/wpdimp/makefile.mk29
-rw-r--r--writerperfect/source/wpdimp/wpft_genericfilter.cxx124
-rw-r--r--writerperfect/source/wpgimp/WPGImportFilter.cxx285
-rw-r--r--writerperfect/source/wpgimp/WPGImportFilter.hxx117
-rw-r--r--writerperfect/source/wpgimp/makefile.mk24
-rw-r--r--writerperfect/source/wpgimp/wpgimport_genericfilter.cxx102
-rw-r--r--writerperfect/source/wpsimp/MSWorksCollector.cxx51
-rw-r--r--writerperfect/source/wpsimp/MSWorksCollector.hxx45
-rw-r--r--writerperfect/source/wpsimp/MSWorksImportFilter.cxx280
-rw-r--r--writerperfect/source/wpsimp/MSWorksImportFilter.hxx120
-rw-r--r--writerperfect/source/wpsimp/makefile.mk29
-rw-r--r--writerperfect/source/wpsimp/msworks_genericfilter.cxx102
48 files changed, 6680 insertions, 0 deletions
diff --git a/writerperfect/source/filter/DocumentCollector.cxx b/writerperfect/source/filter/DocumentCollector.cxx
new file mode 100644
index 000000000000..22605664cc65
--- /dev/null
+++ b/writerperfect/source/filter/DocumentCollector.cxx
@@ -0,0 +1,1312 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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 "DocumentHandler.hxx"
+#include "InternalHandler.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"
+#include "OdgExporter.hxx"
+
+_WriterDocumentState::_WriterDocumentState() :
+ mbFirstElement(true),
+ mbFirstParagraphInPageSpan(true),
+ mbInFakeSection(false),
+ mbListElementOpenedAtCurrentLevel(false),
+ mbTableCellOpened(false),
+ mbHeaderRow(false),
+ mbInNote(false),
+ mbInTextBox(false),
+ mbInFrame(false)
+{
+}
+
+_WriterListState::_WriterListState() :
+ mpCurrentListStyle(NULL),
+ miCurrentListLevel(0),
+ miLastListLevel(0),
+ miLastListNumber(0),
+ mbListContinueNumbering(false),
+ mbListElementParagraphOpened(false),
+ mbListElementOpened()
+{
+}
+
+DocumentCollector::DocumentCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler) :
+ mpInput(pInput),
+ mpHandler(pHandler),
+ mbUsed(false),
+ mWriterDocumentStates(),
+ mWriterListStates(),
+ mfSectionSpaceAfter(0.0f),
+ miNumListStyles(0),
+ mpCurrentContentElements(&mBodyElements),
+ mpCurrentPageSpan(NULL),
+ miNumPageStyles(0),
+ miObjectNumber(0),
+ mbIsFlatXML(true),
+ mpPassword(NULL)
+{
+ mWriterDocumentStates.push(WriterDocumentState());
+ mWriterListStates.push(WriterListState());
+}
+
+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);
+ }
+ for (std::vector<DocumentElement *>::iterator iterFrameStyles = mFrameStyles.begin(); iterFrameStyles != mFrameStyles.end(); ++iterFrameStyles) {
+ delete(*iterFrameStyles);
+ }
+ for (std::vector<DocumentElement *>::iterator iterFrameAutomaticStyles = mFrameAutomaticStyles.begin();
+ iterFrameAutomaticStyles != mFrameAutomaticStyles.end(); ++iterFrameAutomaticStyles) {
+ delete(*iterFrameAutomaticStyles);
+ }
+ for (std::vector<DocumentElement *>::iterator iterMetaData = mMetaData.begin(); iterMetaData != mMetaData.end(); ++iterMetaData) {
+ delete(*iterMetaData);
+ }
+
+ return true;
+}
+
+void DocumentCollector::_writeDefaultStyles(DocumentHandlerInterface *pHandler)
+{
+ TagOpenElement("office:styles").write(pHandler);
+
+ TagOpenElement defaultParagraphStyleOpenElement("style:default-style");
+ defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph");
+ defaultParagraphStyleOpenElement.write(pHandler);
+
+ TagOpenElement defaultParagraphStylePropertiesOpenElement("style:paragraph-properties");
+ defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5in");
+ defaultParagraphStylePropertiesOpenElement.write(pHandler);
+ TagCloseElement defaultParagraphStylePropertiesCloseElement("style:paragraph-properties");
+ defaultParagraphStylePropertiesCloseElement.write(pHandler);
+
+ pHandler->endElement("style:default-style");
+
+ TagOpenElement defaultTableRowStyleOpenElement("style:default-style");
+ defaultTableRowStyleOpenElement.addAttribute("style:family", "table-row");
+ defaultTableRowStyleOpenElement.write(pHandler);
+
+ TagOpenElement defaultTableRowPropertiesOpenElement("style:table-row-properties");
+ defaultTableRowPropertiesOpenElement.addAttribute("fo:keep-together", "auto");
+ defaultTableRowPropertiesOpenElement.write(pHandler);
+
+ pHandler->endElement("style:table-row-properties");
+ pHandler->endElement("style:default-style");
+
+ TagOpenElement standardStyleOpenElement("style:style");
+ standardStyleOpenElement.addAttribute("style:name", "Standard");
+ standardStyleOpenElement.addAttribute("style:family", "paragraph");
+ standardStyleOpenElement.addAttribute("style:class", "text");
+ standardStyleOpenElement.write(pHandler);
+
+ pHandler->endElement("style:style");
+
+ TagOpenElement textBodyStyleOpenElement("style:style");
+ textBodyStyleOpenElement.addAttribute("style:name", "Text_Body");
+ textBodyStyleOpenElement.addAttribute("style:display-name", "Text Body");
+ textBodyStyleOpenElement.addAttribute("style:family", "paragraph");
+ textBodyStyleOpenElement.addAttribute("style:parent-style-name", "Standard");
+ textBodyStyleOpenElement.addAttribute("style:class", "text");
+ textBodyStyleOpenElement.write(pHandler);
+
+ pHandler->endElement("style:style");
+
+ TagOpenElement tableContentsStyleOpenElement("style:style");
+ tableContentsStyleOpenElement.addAttribute("style:name", "Table_Contents");
+ tableContentsStyleOpenElement.addAttribute("style:display-name", "Table Contents");
+ tableContentsStyleOpenElement.addAttribute("style:family", "paragraph");
+ tableContentsStyleOpenElement.addAttribute("style:parent-style-name", "Text_Body");
+ tableContentsStyleOpenElement.addAttribute("style:class", "extra");
+ tableContentsStyleOpenElement.write(pHandler);
+
+ pHandler->endElement("style:style");
+
+ TagOpenElement tableHeadingStyleOpenElement("style:style");
+ tableHeadingStyleOpenElement.addAttribute("style:name", "Table_Heading");
+ tableHeadingStyleOpenElement.addAttribute("style:display-name", "Table Heading");
+ tableHeadingStyleOpenElement.addAttribute("style:family", "paragraph");
+ tableHeadingStyleOpenElement.addAttribute("style:parent-style-name", "Table_Contents");
+ tableHeadingStyleOpenElement.addAttribute("style:class", "extra");
+ tableHeadingStyleOpenElement.write(pHandler);
+
+ pHandler->endElement("style:style");
+
+ for (std::vector<DocumentElement *>::const_iterator iter = mFrameStyles.begin();
+ iter != mFrameStyles.end(); ++iter)
+ (*iter)->write(pHandler);
+
+ pHandler->endElement("office:styles");
+}
+
+void DocumentCollector::_writeMasterPages(DocumentHandlerInterface *pHandler)
+{
+ TagOpenElement("office:master-styles").write(mpHandler);
+ 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::_writePageLayouts(DocumentHandlerInterface *pHandler)
+{
+ for (unsigned int i=0; i<mPageSpans.size(); i++)
+ {
+ mPageSpans[i]->writePageLayout(i, pHandler);
+ }
+}
+
+bool DocumentCollector::_writeTargetDocument(DocumentHandlerInterface *pHandler)
+{
+ WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Printing out the header stuff..\n"));
+
+ 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", "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
+ docContentPropList.insert("xmlns:meta", "urn:oasis:names:tc:opendocument:xmlns:meta:1.0");
+ docContentPropList.insert("xmlns:dc", "http://purl.org/dc/elements/1.1/");
+ docContentPropList.insert("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
+ docContentPropList.insert("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
+ docContentPropList.insert("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0");
+ docContentPropList.insert("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
+ docContentPropList.insert("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
+ docContentPropList.insert("xmlns:xlink", "http://www.w3.org/1999/xlink");
+ docContentPropList.insert("xmlns:number", "http://openoffice.org/2000/datastyle");
+ docContentPropList.insert("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
+ docContentPropList.insert("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0");
+ docContentPropList.insert("xmlns:dr3d", "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0");
+ docContentPropList.insert("xmlns:math", "http://www.w3.org/1998/Math/MathML");
+ docContentPropList.insert("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0");
+ docContentPropList.insert("xmlns:script", "urn:oasis:names:tc:opendocument:xmlns:script:1.0");
+ docContentPropList.insert("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0");
+ docContentPropList.insert("office:version", "1.0");
+ docContentPropList.insert("office:mimetype", "application/vnd.oasis.opendocument.text");
+ mpHandler->startElement("office:document", docContentPropList);
+
+ // write out the metadata
+ TagOpenElement("office:meta").write(mpHandler);
+ for (std::vector<DocumentElement *>::const_iterator iterMetaData = mMetaData.begin(); iterMetaData != mMetaData.end(); ++iterMetaData) {
+ (*iterMetaData)->write(mpHandler);
+ }
+ mpHandler->endElement("office:meta");
+
+ // write out the font styles
+ TagOpenElement("office:font-face-decls").write(mpHandler);
+ for (std::map<WPXString, FontStyle *, ltstr>::iterator iterFont = mFontHash.begin(); iterFont != mFontHash.end(); ++iterFont) {
+ iterFont->second->write(mpHandler);
+ }
+ TagOpenElement symbolFontOpen("style:font-face");
+ symbolFontOpen.addAttribute("style:name", "StarSymbol");
+ symbolFontOpen.addAttribute("svg:font-family", "StarSymbol");
+ symbolFontOpen.addAttribute("style:font-charset", "x-symbol");
+ symbolFontOpen.write(mpHandler);
+ mpHandler->endElement("style:font-face");
+
+ mpHandler->endElement("office:font-face-decls");
+
+ WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the styles..\n"));
+
+ // write default styles
+ _writeDefaultStyles(mpHandler);
+
+ TagOpenElement("office:automatic-styles").write(mpHandler);
+
+ for (std::vector<DocumentElement *>::const_iterator iterFrameAutomaticStyles = mFrameAutomaticStyles.begin();
+ iterFrameAutomaticStyles != mFrameAutomaticStyles.end(); ++iterFrameAutomaticStyles)
+ {
+ (*iterFrameAutomaticStyles)->write(pHandler);
+ }
+
+ for (std::map<WPXString, ParagraphStyle *, ltstr>::const_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>::const_iterator iterSpanStyle = mSpanStyleHash.begin();
+ iterSpanStyle != mSpanStyleHash.end(); ++iterSpanStyle)
+ {
+ (iterSpanStyle->second)->write(pHandler);
+ }
+
+ // writing out the sections styles
+ for (std::vector<SectionStyle *>::const_iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); ++iterSectionStyles) {
+ (*iterSectionStyles)->write(pHandler);
+ }
+
+ // writing out the lists styles
+ for (std::vector<ListStyle *>::const_iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); ++iterListStyles) {
+ (*iterListStyles)->write(pHandler);
+ }
+
+ // writing out the table styles
+ for (std::vector<TableStyle *>::const_iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); ++iterTableStyles) {
+ (*iterTableStyles)->write(pHandler);
+ }
+
+ // writing out the page masters
+ _writePageLayouts(pHandler);
+
+
+ pHandler->endElement("office:automatic-styles");
+
+ _writeMasterPages(pHandler);
+
+ WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the document..\n"));
+ // writing out the document
+ TagOpenElement("office:body").write(mpHandler);
+ TagOpenElement("office:text").write(mpHandler);
+
+ for (std::vector<DocumentElement *>::const_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:text");
+ pHandler->endElement("office:body");
+ pHandler->endElement("office:document");
+
+ 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::setDocumentMetaData(const WPXPropertyList &propList)
+{
+ WPXPropertyList::Iter i(propList);
+ for (i.rewind(); i.next(); )
+ {
+ // filter out libwpd elements
+ if (strncmp(i.key(), "libwpd", 6) != 0 && strncmp(i.key(), "dcterms", 7) != 0)
+ {
+ mMetaData.push_back(new TagOpenElement(i.key()));
+ WPXString sStringValue(i()->getStr(), true);
+ mMetaData.push_back(new CharDataElement(sStringValue.cstr()));
+ mMetaData.push_back(new TagCloseElement(i.key()));
+ }
+ }
+
+}
+
+void DocumentCollector::openPageSpan(const WPXPropertyList &propList)
+{
+ PageSpan *pPageSpan = new PageSpan(propList);
+ mPageSpans.push_back(pPageSpan);
+ mpCurrentPageSpan = pPageSpan;
+ miNumPageStyles++;
+
+ mWriterDocumentStates.top().mbFirstParagraphInPageSpan = true;
+}
+
+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();
+ double fSectionMarginLeft = 0.0;
+ double fSectionMarginRight = 0.0;
+ if (propList["fo:margin-left"])
+ fSectionMarginLeft = propList["fo:margin-left"]->getDouble();
+ if (propList["fo:margin-right"])
+ fSectionMarginRight = propList["fo:margin-right"]->getDouble();
+
+ if (iNumColumns > 1 || fSectionMarginLeft != 0 || fSectionMarginRight != 0)
+ {
+ if (propList["fo:margin-bottom"])
+ mfSectionSpaceAfter = propList["fo:margin-bottom"]->getDouble();
+ else if (propList["libwpd:margin-bottom"])
+ mfSectionSpaceAfter = propList["libwpd:margin-bottom"]->getDouble();
+
+ 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(pSectionOpenElement);
+ }
+ else
+ mWriterDocumentStates.top().mbInFakeSection = true;
+}
+
+void DocumentCollector::closeSection()
+{
+ if (!mWriterDocumentStates.top().mbInFakeSection)
+ mpCurrentContentElements->push_back(new TagCloseElement("text:section"));
+ else
+ mWriterDocumentStates.top().mbInFakeSection = false;
+
+ mfSectionSpaceAfter = 0.0;
+}
+
+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 (mWriterDocumentStates.top().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;
+ mWriterDocumentStates.top().mbFirstElement = false;
+ mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false;
+ }
+ else
+ {
+ if (mWriterDocumentStates.top().mbFirstParagraphInPageSpan && mpCurrentContentElements == &mBodyElements)
+ {
+ WPXString sPageStyleName;
+ sPageStyleName.sprintf("Page_Style_%i", miNumPageStyles);
+ pPersistPropList->insert("style:master-page-name", sPageStyleName);
+ mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false;
+ }
+
+ if (mWriterDocumentStates.top().mbTableCellOpened)
+ {
+ if (mWriterDocumentStates.top().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(pParagraphOpenElement);
+}
+
+void DocumentCollector::closeParagraph()
+{
+ mpCurrentContentElements->push_back(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(pSpanOpenElement);
+}
+
+void DocumentCollector::closeSpan()
+{
+ mpCurrentContentElements->push_back(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 (mWriterListStates.top().mpCurrentListStyle && mWriterListStates.top().mpCurrentListStyle->getListID() == id)
+ pOrderedListStyle = static_cast<OrderedListStyle *>(mWriterListStates.top().mpCurrentListStyle); // FIXME: using a dynamic cast here causes oo to crash?!
+
+ // this rather appalling conditional makes sure we only start a new list (rather than continue an old
+ // one) if: (1) we have no prior list OR (2) the prior list is actually definitively different
+ // from the list that is just being defined (listIDs differ) OR (3) we can tell that the user actually
+ // is starting a new list at level 1 (and only level 1)
+ if (pOrderedListStyle == NULL || pOrderedListStyle->getListID() != id ||
+ (propList["libwpd:level"] && propList["libwpd:level"]->getInt()==1 &&
+ (propList["text:start-value"] && propList["text:start-value"]->getInt() != (mWriterListStates.top().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(), id);
+ mListStyles.push_back(pOrderedListStyle);
+ mWriterListStates.top().mpCurrentListStyle = pOrderedListStyle;
+ mWriterListStates.top().mbListContinueNumbering = false;
+ mWriterListStates.top().miLastListNumber = 0;
+ }
+ else
+ mWriterListStates.top().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() == id)
+ (* 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 (mWriterListStates.top().mpCurrentListStyle && mWriterListStates.top().mpCurrentListStyle->getListID() == id)
+ pUnorderedListStyle = static_cast<UnorderedListStyle *>(mWriterListStates.top().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);
+ miNumListStyles++;
+ pUnorderedListStyle = new UnorderedListStyle(sName.cstr(), id);
+ mListStyles.push_back(pUnorderedListStyle);
+ mWriterListStates.top().mpCurrentListStyle = pUnorderedListStyle;
+ }
+
+ // See comment in DocumentCollector::defineOrderedListLevel
+ for (std::vector<ListStyle *>::iterator iterUnorderedListStyles = mListStyles.begin(); iterUnorderedListStyles != mListStyles.end(); ++iterUnorderedListStyles)
+ {
+ if ((* iterUnorderedListStyles)->getListID() == id)
+ (* iterUnorderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList);
+ }
+}
+
+void DocumentCollector::openOrderedListLevel(const WPXPropertyList & /* propList */)
+{
+ if (mWriterListStates.top().mbListElementParagraphOpened)
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
+ mWriterListStates.top().mbListElementParagraphOpened = false;
+ }
+ TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list");
+ _openListLevel(pListLevelOpenElement);
+
+ if (mWriterListStates.top().mbListContinueNumbering) {
+ pListLevelOpenElement->addAttribute("text:continue-numbering", "true");
+ }
+
+ mpCurrentContentElements->push_back(pListLevelOpenElement);
+}
+
+void DocumentCollector::openUnorderedListLevel(const WPXPropertyList & /* propList */)
+{
+ if (mWriterListStates.top().mbListElementParagraphOpened)
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
+ mWriterListStates.top().mbListElementParagraphOpened = false;
+ }
+ TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list");
+ _openListLevel(pListLevelOpenElement);
+
+ mpCurrentContentElements->push_back(pListLevelOpenElement);
+}
+
+void DocumentCollector::_openListLevel(TagOpenElement *pListLevelOpenElement)
+{
+ if (!mWriterListStates.top().mbListElementOpened.empty() &&
+ !mWriterListStates.top().mbListElementOpened.top())
+ {
+ mpCurrentContentElements->push_back(new TagOpenElement("text:list-item"));
+ mWriterListStates.top().mbListElementOpened.top() = true;
+ }
+
+ mWriterListStates.top().mbListElementOpened.push(false);
+ if (mWriterListStates.top().mbListElementOpened.size() == 1) {
+ pListLevelOpenElement->addAttribute("text:style-name", mWriterListStates.top().mpCurrentListStyle->getName());
+ }
+}
+
+void DocumentCollector::closeOrderedListLevel()
+{
+ _closeListLevel();
+}
+
+void DocumentCollector::closeUnorderedListLevel()
+{
+ _closeListLevel();
+}
+
+void DocumentCollector::_closeListLevel()
+{
+ if (mWriterListStates.top().mbListElementOpened.top())
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("text:list-item"));
+ mWriterListStates.top().mbListElementOpened.top() = false;
+ }
+
+ mpCurrentContentElements->push_back(new TagCloseElement("text:list"));
+
+ if (!mWriterListStates.top().mbListElementOpened.empty())
+ {
+ mWriterListStates.top().mbListElementOpened.pop();
+ }
+}
+
+void DocumentCollector::openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops)
+{
+ mWriterListStates.top().miLastListLevel = mWriterListStates.top().miCurrentListLevel;
+ if (mWriterListStates.top().miCurrentListLevel == 1)
+ mWriterListStates.top().miLastListNumber++;
+
+ if (mWriterListStates.top().mbListElementOpened.top())
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("text:list-item"));
+ mWriterListStates.top().mbListElementOpened.top() = false;
+ }
+
+ ParagraphStyle *pStyle = NULL;
+
+ WPXPropertyList *pPersistPropList = new WPXPropertyList(propList);
+ pPersistPropList->insert("style:list-style-name", mWriterListStates.top().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;
+ }
+
+ mpCurrentContentElements->push_back(new TagOpenElement("text:list-item"));
+
+ TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p");
+ pOpenListElementParagraph->addAttribute("text:style-name", pStyle->getName());
+ mpCurrentContentElements->push_back(pOpenListElementParagraph);
+
+ if (mpCurrentContentElements == &mBodyElements)
+ mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false;
+
+ mWriterListStates.top().mbListElementOpened.top() = true;
+ mWriterListStates.top().mbListElementParagraphOpened = true;
+ mWriterListStates.top().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 (mWriterListStates.top().mbListElementParagraphOpened)
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
+ mWriterListStates.top().mbListElementParagraphOpened = false;
+ }
+}
+
+void DocumentCollector::openFootnote(const WPXPropertyList &propList)
+{
+ mWriterListStates.push(WriterListState());
+ TagOpenElement *pOpenFootNote = new TagOpenElement("text:note");
+ pOpenFootNote->addAttribute("text:note-class", "footnote");
+ if (propList["libwpd:number"])
+ {
+ WPXString tmpString("ftn");
+ tmpString.append(propList["libwpd:number"]->getStr());
+ pOpenFootNote->addAttribute("text:id", tmpString);
+ }
+ mpCurrentContentElements->push_back(pOpenFootNote);
+
+ mpCurrentContentElements->push_back(new TagOpenElement("text:note-citation"));
+ if (propList["libwpd:number"])
+ mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr()));
+ mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation"));
+
+ mpCurrentContentElements->push_back(new TagOpenElement("text:note-body"));
+
+ mWriterDocumentStates.top().mbInNote = true;
+}
+
+void DocumentCollector::closeFootnote()
+{
+ mWriterDocumentStates.top().mbInNote = false;
+ if (mWriterListStates.size() > 1)
+ mWriterListStates.pop();
+
+ mpCurrentContentElements->push_back(new TagCloseElement("text:note-body"));
+ mpCurrentContentElements->push_back(new TagCloseElement("text:note"));
+}
+
+void DocumentCollector::openEndnote(const WPXPropertyList &propList)
+{
+ mWriterListStates.push(WriterListState());
+ TagOpenElement *pOpenEndNote = new TagOpenElement("text:note");
+ pOpenEndNote->addAttribute("text:note-class", "endnote");
+ if (propList["libwpd:number"])
+ {
+ WPXString tmpString("edn");
+ tmpString.append(propList["libwpd:number"]->getStr());
+ pOpenEndNote->addAttribute("text:id", tmpString);
+ }
+ mpCurrentContentElements->push_back(pOpenEndNote);
+
+ mpCurrentContentElements->push_back(new TagOpenElement("text:note-citation"));
+ if (propList["libwpd:number"])
+ mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr()));
+ mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation"));
+
+ mpCurrentContentElements->push_back(new TagOpenElement("text:note-body"));
+
+ mWriterDocumentStates.top().mbInNote = true;
+}
+
+void DocumentCollector::closeEndnote()
+{
+ mWriterDocumentStates.top().mbInNote = false;
+ if (mWriterListStates.size() > 1)
+ mWriterListStates.pop();
+
+ mpCurrentContentElements->push_back(new TagCloseElement("text:note-body"));
+ mpCurrentContentElements->push_back(new TagCloseElement("text:note"));
+}
+
+void DocumentCollector::openComment(const WPXPropertyList & /*propList*/)
+{
+ mWriterListStates.push(WriterListState());
+ mpCurrentContentElements->push_back(new TagOpenElement("office:annotation"));
+
+ mWriterDocumentStates.top().mbInNote = true;
+}
+
+void DocumentCollector::closeComment()
+{
+ mWriterDocumentStates.top().mbInNote = false;
+ if (mWriterListStates.size() > 1)
+ mWriterListStates.pop();
+
+ mpCurrentContentElements->push_back(new TagCloseElement("office:annotation"));
+}
+
+void DocumentCollector::openTable(const WPXPropertyList &propList, const WPXPropertyListVector &columns)
+{
+ if (!mWriterDocumentStates.top().mbInNote)
+ {
+ 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 (mWriterDocumentStates.top().mbFirstElement && mpCurrentContentElements == &mBodyElements)
+ {
+ WPXString sMasterPageName("Page_Style_1");
+ pTableStyle->setMasterPageName(sMasterPageName);
+ mWriterDocumentStates.top().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(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 (!mWriterDocumentStates.top().mbInNote)
+ {
+ if (propList["libwpd:is-header-row"] && (propList["libwpd:is-header-row"]->getInt()))
+ {
+ mpCurrentContentElements->push_back(new TagOpenElement("table:table-header-rows"));
+ mWriterDocumentStates.top().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(pTableRowOpenElement);
+ }
+}
+
+void DocumentCollector::closeTableRow()
+{
+ if (!mWriterDocumentStates.top().mbInNote)
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("table:table-row"));
+ if (mWriterDocumentStates.top().mbHeaderRow)
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("table:table-header-rows"));
+ mWriterDocumentStates.top().mbHeaderRow = false;
+ }
+ }
+}
+
+void DocumentCollector::openTableCell(const WPXPropertyList &propList)
+{
+ if (!mWriterDocumentStates.top().mbInNote)
+ {
+ 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(pTableCellOpenElement);
+
+ mWriterDocumentStates.top().mbTableCellOpened = true;
+ }
+}
+
+void DocumentCollector::closeTableCell()
+{
+ if (!mWriterDocumentStates.top().mbInNote)
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("table:table-cell"));
+ mWriterDocumentStates.top().mbTableCellOpened = false;
+ }
+}
+
+void DocumentCollector::insertCoveredTableCell(const WPXPropertyList & /* propList */)
+{
+ if (!mWriterDocumentStates.top().mbInNote)
+ {
+ mpCurrentContentElements->push_back(new TagOpenElement("table:covered-table-cell"));
+ mpCurrentContentElements->push_back(new TagCloseElement("table:covered-table-cell"));
+ }
+}
+
+void DocumentCollector::closeTable()
+{
+ if (!mWriterDocumentStates.top().mbInNote)
+ {
+ mpCurrentContentElements->push_back(new TagCloseElement("table:table"));
+ }
+}
+
+
+void DocumentCollector::insertTab()
+{
+ mpCurrentContentElements->push_back(new TagOpenElement("text:tab"));
+ mpCurrentContentElements->push_back(new TagCloseElement("text:tab"));
+}
+
+void DocumentCollector::insertSpace()
+{
+ mpCurrentContentElements->push_back(new TagOpenElement("text:s"));
+ mpCurrentContentElements->push_back(new TagCloseElement("text:s"));
+}
+
+void DocumentCollector::insertLineBreak()
+{
+ mpCurrentContentElements->push_back(new TagOpenElement("text:line-break"));
+ mpCurrentContentElements->push_back(new TagCloseElement("text:line-break"));
+}
+
+void DocumentCollector::insertField(const WPXString &type, const WPXPropertyList &propList)
+{
+ if (!type.len())
+ return;
+
+ TagOpenElement *openElement = new TagOpenElement(type.cstr());
+ if (type == "text:page-number")
+ openElement->addAttribute("text:select-page", "current");
+
+ if (propList["style:num-format"])
+ openElement->addAttribute("style:num-format", propList["style:num-format"]->getStr());
+
+ mpCurrentContentElements->push_back(openElement);
+ mpCurrentContentElements->push_back(new TagCloseElement(type.cstr()));
+}
+
+void DocumentCollector::insertText(const WPXString &text)
+{
+ DocumentElement *pText = new TextElement(text);
+ mpCurrentContentElements->push_back(pText);
+}
+
+void DocumentCollector::openFrame(const WPXPropertyList &propList)
+{
+ mWriterListStates.push(WriterListState());
+
+ // First, let's create a Frame Style for this box
+ TagOpenElement *frameStyleOpenElement = new TagOpenElement("style:style");
+ WPXString frameStyleName;
+ frameStyleName.sprintf("GraphicFrame_%i", miObjectNumber);
+ frameStyleOpenElement->addAttribute("style:name", frameStyleName);
+ frameStyleOpenElement->addAttribute("style:family", "graphic");
+
+ mFrameStyles.push_back(frameStyleOpenElement);
+
+ TagOpenElement *frameStylePropertiesOpenElement = new TagOpenElement("style:graphic-properties");
+
+ if (propList["text:anchor-type"])
+ frameStylePropertiesOpenElement->addAttribute("text:anchor-type", propList["text:anchor-type"]->getStr());
+ else
+ frameStylePropertiesOpenElement->addAttribute("text:anchor-type","paragraph");
+
+ if (propList["text:anchor-page-number"])
+ frameStylePropertiesOpenElement->addAttribute("text:anchor-page-number", propList["text:anchor-page-number"]->getStr());
+
+ if (propList["svg:x"])
+ frameStylePropertiesOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr());
+
+ if (propList["svg:y"])
+ frameStylePropertiesOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr());
+
+ if (propList["svg:width"])
+ frameStylePropertiesOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr());
+
+ if (propList["svg:height"])
+ frameStylePropertiesOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr());
+
+ if (propList["style:rel-width"])
+ frameStylePropertiesOpenElement->addAttribute("style:rel-width", propList["style:rel-width"]->getStr());
+
+ if (propList["style:rel-height"])
+ frameStylePropertiesOpenElement->addAttribute("style:rel-height", propList["style:rel-height"]->getStr());
+
+ if (propList["fo:max-width"])
+ frameStylePropertiesOpenElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr());
+
+ if (propList["fo:max-height"])
+ frameStylePropertiesOpenElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr());
+
+ if (propList["style:wrap"])
+ frameStylePropertiesOpenElement->addAttribute("style:wrap", propList["style:wrap"]->getStr());
+
+ mFrameStyles.push_back(frameStylePropertiesOpenElement);
+
+ mFrameStyles.push_back(new TagCloseElement("style:graphic-properties"));
+
+ mFrameStyles.push_back(new TagCloseElement("style:style"));
+
+ // Now, let's create an automatic style for this frame
+ TagOpenElement *frameAutomaticStyleElement = new TagOpenElement("style:style");
+ WPXString frameAutomaticStyleName;
+ frameAutomaticStyleName.sprintf("fr%i", miObjectNumber);
+ frameAutomaticStyleElement->addAttribute("style:name", frameAutomaticStyleName);
+ frameAutomaticStyleElement->addAttribute("style:family", "graphic");
+ frameAutomaticStyleElement->addAttribute("style:parent-style-name", frameStyleName);
+
+ mFrameAutomaticStyles.push_back(frameAutomaticStyleElement);
+
+ TagOpenElement *frameAutomaticStylePropertiesElement = new TagOpenElement("style:graphic-properties");
+ if (propList["style:horizontal-pos"])
+ frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-pos", propList["style:horizontal-pos"]->getStr());
+ else
+ frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-pos", "left");
+
+ if (propList["style:horizontal-rel"])
+ frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-rel", propList["style:horizontal-rel"]->getStr());
+ else
+ frameAutomaticStylePropertiesElement->addAttribute("style:horizontal-rel", "paragraph");
+
+ if (propList["style:vertical-pos"])
+ frameAutomaticStylePropertiesElement->addAttribute("style:vertical-pos", propList["style:vertical-pos"]->getStr());
+ else
+ frameAutomaticStylePropertiesElement->addAttribute("style:vertical-pos", "top");
+
+ if (propList["style:vertical-rel"])
+ frameAutomaticStylePropertiesElement->addAttribute("style:vertical-rel", propList["style:vertical-rel"]->getStr());
+ else
+ frameAutomaticStylePropertiesElement->addAttribute("style:vertical-rel", "page-content");
+
+ if (propList["fo:max-width"])
+ frameAutomaticStylePropertiesElement->addAttribute("fo:max-width", propList["fo:max-width"]->getStr());
+
+ if (propList["fo:max-height"])
+ frameAutomaticStylePropertiesElement->addAttribute("fo:max-height", propList["fo:max-height"]->getStr());
+
+ frameAutomaticStylePropertiesElement->addAttribute("draw:ole-draw-aspect", "1");
+
+ mFrameAutomaticStyles.push_back(frameAutomaticStylePropertiesElement);
+
+ mFrameAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties"));
+
+ mFrameAutomaticStyles.push_back(new TagCloseElement("style:style"));
+
+ // And write the frame itself
+ TagOpenElement *drawFrameOpenElement = new TagOpenElement("draw:frame");
+
+ drawFrameOpenElement->addAttribute("draw:style-name", frameAutomaticStyleName);
+ WPXString objectName;
+ objectName.sprintf("Object%i", miObjectNumber++);
+ drawFrameOpenElement->addAttribute("draw:name", objectName);
+ if (propList["text:anchor-type"])
+ drawFrameOpenElement->addAttribute("text:anchor-type", propList["text:anchor-type"]->getStr());
+ else
+ drawFrameOpenElement->addAttribute("text:anchor-type","paragraph");
+
+ if (propList["text:anchor-page-number"])
+ drawFrameOpenElement->addAttribute("text:anchor-page-number", propList["text:anchor-page-number"]->getStr());
+
+ if (propList["svg:x"])
+ drawFrameOpenElement->addAttribute("svg:x", propList["svg:x"]->getStr());
+
+ if (propList["svg:y"])
+ drawFrameOpenElement->addAttribute("svg:y", propList["svg:y"]->getStr());
+
+ if (propList["svg:width"])
+ drawFrameOpenElement->addAttribute("svg:width", propList["svg:width"]->getStr());
+
+ if (propList["svg:height"])
+ drawFrameOpenElement->addAttribute("svg:height", propList["svg:height"]->getStr());
+
+ if (propList["style:rel-width"])
+ drawFrameOpenElement->addAttribute("style:rel-width", propList["style:rel-width"]->getStr());
+
+ if (propList["style:rel-height"])
+ drawFrameOpenElement->addAttribute("style:rel-height", propList["style:rel-height"]->getStr());
+
+ mpCurrentContentElements->push_back(drawFrameOpenElement);
+
+ mWriterDocumentStates.top().mbInFrame = true;
+}
+
+void DocumentCollector::closeFrame()
+{
+ if (mWriterListStates.size() > 1)
+ mWriterListStates.pop();
+
+ mpCurrentContentElements->push_back(new TagCloseElement("draw:frame"));
+
+ mWriterDocumentStates.top().mbInFrame = false;
+}
+
+void DocumentCollector::insertBinaryObject(const WPXPropertyList &propList, const WPXBinaryData &data)
+{
+ if (!data.size())
+ return;
+ if (!mWriterDocumentStates.top().mbInFrame) // Embedded objects without a frame simply don't make sense for us
+ return;
+ if (!propList["libwpd:mimetype"])
+ return;
+
+ if (propList["libwpd:mimetype"]->getStr() == "image/x-wpg")
+ {
+ std::vector<DocumentElement *> tmpContentElements;
+ InternalHandler tmpHandler(&tmpContentElements);
+ OdgExporter exporter(&tmpHandler);
+
+ libwpg::WPGFileFormat fileFormat = libwpg::WPG_AUTODETECT;
+
+ if (!libwpg::WPGraphics::isSupported(const_cast<WPXInputStream *>(data.getDataStream())))
+ fileFormat = libwpg::WPG_WPG1;
+
+ if (libwpg::WPGraphics::parse(const_cast<WPXInputStream *>(data.getDataStream()), &exporter, fileFormat) && !tmpContentElements.empty())
+ {
+ mpCurrentContentElements->push_back(new TagOpenElement("draw:object"));
+ for (std::vector<DocumentElement *>::const_iterator iter = tmpContentElements.begin(); iter != tmpContentElements.end(); ++iter)
+ mpCurrentContentElements->push_back(*iter);
+ mpCurrentContentElements->push_back(new TagCloseElement("draw:object"));
+ }
+ }
+ else
+ {
+ mpCurrentContentElements->push_back(new TagOpenElement("draw:image"));
+
+ mpCurrentContentElements->push_back(new TagOpenElement("office:binary-data"));
+
+ WPXString binaryBase64Data = data.getBase64Data();
+
+ mpCurrentContentElements->push_back(new CharDataElement(binaryBase64Data.cstr()));
+
+ mpCurrentContentElements->push_back(new TagCloseElement("office:binary-data"));
+
+ mpCurrentContentElements->push_back(new TagCloseElement("draw:image"));
+ }
+}
+
+void DocumentCollector::openTextBox(const WPXPropertyList & /*propList*/)
+{
+ if (!mWriterDocumentStates.top().mbInFrame) // Text box without a frame simply doesn't make sense for us
+ return;
+ mWriterListStates.push(WriterListState());
+ mWriterDocumentStates.push(WriterDocumentState());
+ mpCurrentContentElements->push_back(new TagOpenElement("draw:text-box"));
+ mWriterDocumentStates.top().mbInTextBox = true;
+ mWriterDocumentStates.top().mbFirstElement = false;
+}
+
+void DocumentCollector::closeTextBox()
+{
+ if (!mWriterDocumentStates.top().mbInTextBox)
+ return;
+ if (mWriterListStates.size() > 1)
+ mWriterListStates.pop();
+ if (mWriterDocumentStates.size() > 1)
+ mWriterDocumentStates.pop();
+
+ mpCurrentContentElements->push_back(new TagCloseElement("draw:text-box"));
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/DocumentCollector.hxx b/writerperfect/source/filter/DocumentCollector.hxx
new file mode 100644
index 000000000000..619bc1de603d
--- /dev/null
+++ b/writerperfect/source/filter/DocumentCollector.hxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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 <libwps/libwps.h>
+#include <libwpd/libwpd.h>
+#if defined _MSC_VER
+#pragma warning( pop )
+#endif
+#include <vector>
+#include <map>
+#include <stack>
+#include <string.h>
+
+#include "DocumentHandlerInterface.hxx"
+
+class DocumentElement;
+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 mbFirstParagraphInPageSpan;
+ bool mbInFakeSection;
+ bool mbListElementOpenedAtCurrentLevel;
+ bool mbTableCellOpened;
+ bool mbHeaderRow;
+ bool mbInNote;
+ bool mbInTextBox;
+ bool mbInFrame;
+};
+
+// list state
+typedef struct _WriterListState WriterListState;
+struct _WriterListState
+{
+ _WriterListState();
+
+ ListStyle *mpCurrentListStyle;
+ unsigned int miCurrentListLevel;
+ unsigned int miLastListLevel;
+ unsigned int miLastListNumber;
+ bool mbListContinueNumbering;
+ bool mbListElementParagraphOpened;
+ std::stack<bool> mbListElementOpened;
+};
+
+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 WPXDocumentInterface
+{
+public:
+ DocumentCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler);
+ virtual ~DocumentCollector();
+ bool filter();
+
+ // WPXDocumentInterface's callbacks
+ virtual void setDocumentMetaData(const WPXPropertyList &propList);
+ virtual void startDocument() {}
+ virtual void endDocument() {}
+
+ virtual void definePageStyle(const WPXPropertyList&) {}
+ virtual void openPageSpan(const WPXPropertyList &propList);
+ virtual void closePageSpan() {}
+
+ virtual void defineSectionStyle(const WPXPropertyList&, const WPXPropertyListVector&) {}
+ 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 defineParagraphStyle(const WPXPropertyList&, const WPXPropertyListVector&) {}
+ virtual void openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops);
+ virtual void closeParagraph();
+
+ virtual void defineCharacterStyle(const WPXPropertyList&) {}
+ virtual void openSpan(const WPXPropertyList &propList);
+ virtual void closeSpan();
+
+ virtual void insertTab();
+ virtual void insertSpace();
+ virtual void insertText(const WPXString &text);
+ virtual void insertLineBreak();
+ virtual void insertField(const WPXString &type, const WPXPropertyList &propList);
+
+ 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 openComment(const WPXPropertyList &propList);
+ virtual void closeComment();
+ virtual void openTextBox(const WPXPropertyList &propList);
+ virtual void closeTextBox();
+
+ 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 void openFrame(const WPXPropertyList & propList);
+ virtual void closeFrame();
+
+ virtual void insertBinaryObject(const WPXPropertyList &propList, const WPXBinaryData &data);
+ virtual void insertEquation(const WPXPropertyList & /* propList */, const WPXString & /* data */) {}
+
+ virtual bool parseSourceDocument(WPXInputStream &input) = 0;
+
+protected:
+ void _resetDocumentState();
+ bool _writeTargetDocument(DocumentHandlerInterface *pHandler);
+ void _writeDefaultStyles(DocumentHandlerInterface *pHandler);
+ void _writeMasterPages(DocumentHandlerInterface *pHandler);
+ void _writePageLayouts(DocumentHandlerInterface *pHandler);
+ void _allocateFontName(const WPXString &);
+
+private:
+ void _openListLevel(TagOpenElement *pListLevelOpenElement);
+ void _closeListLevel();
+
+ WPXInputStream *mpInput;
+ DocumentHandlerInterface *mpHandler;
+ bool mbUsed; // whether or not it has been before (you can only use me once!)
+
+ std::stack<WriterDocumentState> mWriterDocumentStates;
+
+ std::stack<WriterListState> mWriterListStates;
+
+ // 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;
+
+ // frame styles
+ std::vector<DocumentElement *> mFrameStyles;
+
+ std::vector<DocumentElement *> mFrameAutomaticStyles;
+
+ // metadata
+ std::vector<DocumentElement *> mMetaData;
+
+ // 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
+ std::vector<ListStyle *> mListStyles;
+
+ // object state
+ unsigned miObjectNumber;
+
+ // table state
+ TableStyle *mpCurrentTableStyle;
+
+ const bool mbIsFlatXML;
+
+ const char * mpPassword;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/DocumentElement.cxx b/writerperfect/source/filter/DocumentElement.cxx
new file mode 100644
index 000000000000..f330ab0ace47
--- /dev/null
+++ b/writerperfect/source/filter/DocumentElement.cxx
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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 "DocumentHandler.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(DocumentHandlerInterface *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(DocumentHandlerInterface *pHandler) const
+{
+ WRITER_DEBUG_MSG(("TagCloseElement: write (%s)\n", getTagName().cstr()));
+
+ pHandler->endElement(getTagName().cstr());
+}
+
+void CharDataElement::write(DocumentHandlerInterface *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(DocumentHandlerInterface *pHandler) const
+{
+ if (msTextBuf.len() <= 0)
+ return;
+ 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);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/DocumentElement.hxx b/writerperfect/source/filter/DocumentElement.hxx
new file mode 100644
index 000000000000..cb84777a278a
--- /dev/null
+++ b/writerperfect/source/filter/DocumentElement.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+#include <libwpd/libwpd.h>
+#include <libwpd/WPXProperty.h>
+#include <libwpd/WPXString.h>
+#include <vector>
+
+#include "DocumentHandlerInterface.hxx"
+
+class DocumentElement
+{
+public:
+ virtual ~DocumentElement() {}
+ virtual void write(DocumentHandlerInterface *pHandler) const = 0;
+ virtual void print() const {}
+};
+
+class TagElement : public DocumentElement
+{
+public:
+ virtual ~TagElement() {}
+ 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) {}
+ virtual ~TagOpenElement() {}
+ void addAttribute(const char *szAttributeName, const WPXString &sAttributeValue);
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+ virtual void print () const;
+private:
+ WPXPropertyList maAttrList;
+};
+
+class TagCloseElement : public TagElement
+{
+public:
+ TagCloseElement(const char *szTagName) : TagElement(szTagName) {}
+ virtual ~TagCloseElement() {}
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+};
+
+class CharDataElement : public DocumentElement
+{
+public:
+ CharDataElement(const char *sData) : DocumentElement(), msData(sData) {}
+ virtual ~CharDataElement() {}
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+private:
+ WPXString msData;
+};
+
+class TextElement : public DocumentElement
+{
+public:
+ TextElement(const WPXString & sTextBuf);
+ virtual ~TextElement() {}
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+
+private:
+ WPXString msTextBuf;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/DocumentHandler.cxx b/writerperfect/source/filter/DocumentHandler.cxx
new file mode 100644
index 000000000000..c61ffc0c19c5
--- /dev/null
+++ b/writerperfect/source/filter/DocumentHandler.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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>
+
+#include <xmloff/attrlist.hxx>
+
+// #define DEBUG_XML 1
+
+using namespace ::rtl;
+using rtl::OUString;
+
+using com::sun::star::xml::sax::XAttributeList;
+
+DocumentHandler::DocumentHandler(Reference < XDocumentHandler > &xHandler) :
+ mxHandler(xHandler)
+{
+}
+
+void DocumentHandler::startDocument()
+{
+ mxHandler->startDocument();
+}
+
+void DocumentHandler::endDocument()
+{
+ mxHandler->endDocument();
+}
+
+void DocumentHandler::startElement(const char *psName, const WPXPropertyList &xPropList)
+{
+#ifdef DEBUG_XML
+ printf("<%s", psName);
+#endif
+ SvXMLAttributeList *pAttrList = new SvXMLAttributeList();
+ Reference < XAttributeList > xAttrList(pAttrList);
+ WPXPropertyList::Iter i(xPropList);
+ for (i.rewind(); i.next(); )
+ {
+ // filter out libwpd elements
+ if (strncmp(i.key(), "libwpd", 6) != 0)
+ {
+ pAttrList->AddAttribute(OUString::createFromAscii(i.key()),
+ OUString::createFromAscii(i()->getStr().cstr()));
+#ifdef DEBUG_XML
+ printf(" %s=\"%s\"", i.key(), i()->getStr().cstr());
+#endif
+ }
+ }
+#ifdef DEBUG_XML
+ printf(">");
+#endif
+
+ mxHandler->startElement(OUString::createFromAscii(psName), xAttrList);
+}
+
+void DocumentHandler::endElement(const char *psName)
+{
+#ifdef DEBUG_XML
+ printf("</%s>", psName);
+#endif
+ mxHandler->endElement(OUString::createFromAscii(psName));
+}
+
+void DocumentHandler::characters(const WPXString &sCharacters)
+{
+ OUString sCharU16(sCharacters.cstr(), strlen(sCharacters.cstr()), RTL_TEXTENCODING_UTF8);
+#ifdef DEBUG_XML
+ WPXString sEscapedCharacters(sCharacters, true);
+ printf("%s", sEscapedCharacters.cstr());
+#endif
+ mxHandler->characters(sCharU16);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/DocumentHandler.hxx b/writerperfect/source/filter/DocumentHandler.hxx
new file mode 100644
index 000000000000..249f64ff4e7b
--- /dev/null
+++ b/writerperfect/source/filter/DocumentHandler.hxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#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
+
+#include "DocumentHandlerInterface.hxx"
+
+using com::sun::star::uno::Reference;
+using com::sun::star::xml::sax::XDocumentHandler;
+
+class DocumentHandler: public DocumentHandlerInterface
+{
+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_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/DocumentHandlerInterface.hxx b/writerperfect/source/filter/DocumentHandlerInterface.hxx
new file mode 100644
index 000000000000..73ced7d39650
--- /dev/null
+++ b/writerperfect/source/filter/DocumentHandlerInterface.hxx
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2004 William Lachance (wlach@interlog.com)
+ * 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#ifndef _DOCUMENTHANDLERINTERFACE_H
+#define _DOCUMENTHANDLERINTERFACE_H
+#include <libwpd/libwpd.h>
+#include <libwpd/WPXProperty.h>
+#include <libwpd/WPXString.h>
+
+class DocumentHandlerInterface
+{
+public:
+ DocumentHandlerInterface() {};
+ virtual ~DocumentHandlerInterface() {};
+
+ virtual void startDocument() = 0;
+ virtual void endDocument() = 0;
+ virtual void startElement(const char *psName, const WPXPropertyList &xPropList) = 0;
+ virtual void endElement(const char *psName) = 0;
+ virtual void characters(const WPXString &sCharacters) = 0;
+};
+#endif
diff --git a/writerperfect/source/filter/FilterInternal.hxx b/writerperfect/source/filter/FilterInternal.hxx
new file mode 100644
index 000000000000..c53e83ec5d35
--- /dev/null
+++ b/writerperfect/source/filter/FilterInternal.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+ *
+ */
+
+#ifndef _FILTERINTERNAL_HXX
+#define _FILTERINTERNAL_HXX
+
+#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
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/FontStyle.cxx b/writerperfect/source/filter/FontStyle.cxx
new file mode 100644
index 000000000000..e15c6651edd9
--- /dev/null
+++ b/writerperfect/source/filter/FontStyle.cxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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, true),
+ msFontPitch(IMP_DEFAULT_FONT_PITCH)
+{
+}
+
+FontStyle::~FontStyle()
+{
+}
+
+void FontStyle::write(DocumentHandlerInterface *pHandler) const
+{
+ TagOpenElement styleOpen("style:font-face");
+ styleOpen.addAttribute("style:name", getName());
+ styleOpen.addAttribute("svg:font-family", msFontFamily);
+// styleOpen.addAttribute("style:font-pitch", msFontPitch);
+ styleOpen.write(pHandler);
+ TagCloseElement styleClose("style:font-face");
+ styleClose.write(pHandler);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/FontStyle.hxx b/writerperfect/source/filter/FontStyle.hxx
new file mode 100644
index 000000000000..aec430dbd43e
--- /dev/null
+++ b/writerperfect/source/filter/FontStyle.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+#include <libwpd/libwpd.h>
+
+#include "Style.hxx"
+#include "WriterProperties.hxx"
+#include "DocumentHandlerInterface.hxx"
+
+class FontStyle : public Style
+{
+public:
+ FontStyle(const char *psName, const char *psFontFamily);
+ ~FontStyle();
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+ const WPXString &getFontFamily() const { return msFontFamily; }
+
+private:
+ WPXString msFontFamily;
+ WPXString msFontPitch;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/GraphicsStyle.cxx b/writerperfect/source/filter/GraphicsStyle.cxx
new file mode 100644
index 000000000000..4067f55baf46
--- /dev/null
+++ b/writerperfect/source/filter/GraphicsStyle.cxx
@@ -0,0 +1,40 @@
+/* GraphicsStyle:
+ *
+ * Copyright (C) 2007 Fridrich Strba .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 "GraphicsStyle.hxx"
+#include "WriterProperties.hxx"
+#include "DocumentElement.hxx"
+
+GraphicsStyle::GraphicsStyle(const char *psName) : Style(psName)
+{
+}
+
+GraphicsStyle::~GraphicsStyle()
+{
+}
+
+void GraphicsStyle::write(DocumentHandlerInterface * /* pHandler */) const
+{
+}
diff --git a/writerperfect/source/filter/GraphicsStyle.hxx b/writerperfect/source/filter/GraphicsStyle.hxx
new file mode 100644
index 000000000000..b6ee0c66da88
--- /dev/null
+++ b/writerperfect/source/filter/GraphicsStyle.hxx
@@ -0,0 +1,40 @@
+/* GraphicsStyle:
+ *
+ * Copyright (C) 2007 Fridrich Strba .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 _GRAPHICSSTYLE_H
+#define _GRAPHICSSTYLE_H
+
+#include "Style.hxx"
+#include "WriterProperties.hxx"
+#include "DocumentHandlerInterface.hxx"
+
+class GraphicsStyle : public Style
+{
+public:
+ GraphicsStyle(const char *psName);
+ ~GraphicsStyle();
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+};
+#endif
diff --git a/writerperfect/source/filter/InternalHandler.cxx b/writerperfect/source/filter/InternalHandler.cxx
new file mode 100644
index 000000000000..82479bd2221a
--- /dev/null
+++ b/writerperfect/source/filter/InternalHandler.cxx
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 Fridrich Strba .strba@bluewin.ch)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "InternalHandler.hxx"
+
+#include <string.h>
+
+InternalHandler::InternalHandler(std::vector<DocumentElement *> *elements):
+ mpElements(elements)
+{
+}
+
+void InternalHandler::startElement(const char *psName, const WPXPropertyList &xPropList)
+{
+ TagOpenElement *element = new TagOpenElement(psName);
+ WPXPropertyList::Iter i(xPropList);
+ for (i.rewind(); i.next(); )
+ {
+ // filter out libwpd elements
+ if (strncmp(i.key(), "libwpd", 6) != 0)
+ element->addAttribute(i.key(), i()->getStr());
+ }
+ mpElements->push_back(element);
+}
+
+void InternalHandler::endElement(const char *psName)
+{
+ mpElements->push_back(new TagCloseElement(psName));
+}
+
+void InternalHandler::characters(const WPXString &sCharacters)
+{
+ mpElements->push_back(new CharDataElement(sCharacters.cstr()));
+}
diff --git a/writerperfect/source/filter/InternalHandler.hxx b/writerperfect/source/filter/InternalHandler.hxx
new file mode 100644
index 000000000000..9913ac803652
--- /dev/null
+++ b/writerperfect/source/filter/InternalHandler.hxx
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 Fridrich Strba .strba@bluewin.ch)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#ifndef _INTERNALHANDLER_H
+#define _INTERNALHANDLER_H
+#include <libwpd/libwpd.h>
+#include <libwpd/WPXProperty.h>
+#include <libwpd/WPXString.h>
+#include "DocumentElement.hxx"
+#include "DocumentHandlerInterface.hxx"
+
+class InternalHandler : public DocumentHandlerInterface
+{
+public:
+ InternalHandler(std::vector<DocumentElement *> *elements);
+ ~InternalHandler() {};
+
+ void startDocument() {};
+ void endDocument() {};
+ void startElement(const char *psName, const WPXPropertyList &xPropList);
+ void endElement(const char *psName);
+ void characters(const WPXString &sCharacters);
+private:
+ std::vector<DocumentElement *> *mpElements;
+};
+#endif
diff --git a/writerperfect/source/filter/ListStyle.cxx b/writerperfect/source/filter/ListStyle.cxx
new file mode 100644
index 000000000000..c7fdc0d0a835
--- /dev/null
+++ b/writerperfect/source/filter/ListStyle.cxx
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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(DocumentHandlerInterface *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"])
+ {
+ WPXString sEscapedString(mPropList["style:num-prefix"]->getStr(), true);
+ listLevelStyleOpen.addAttribute("style:num-prefix", sEscapedString);
+ }
+ if (mPropList["style:num-suffix"])
+ {
+ WPXString sEscapedString(mPropList["style:num-suffix"]->getStr(), true);
+ listLevelStyleOpen.addAttribute("style:num-suffix", sEscapedString);
+ }
+ if (mPropList["style:num-format"])
+ listLevelStyleOpen.addAttribute("style:num-format", mPropList["style:num-format"]->getStr());
+ if (mPropList["text:start-value"])
+ {
+ // odf as to the version 1.1 does require the text:start-value to be a positive integer, means > 0
+ if (mPropList["text:start-value"]->getInt() > 0)
+ listLevelStyleOpen.addAttribute("text:start-value", mPropList["text:start-value"]->getStr());
+ else
+ listLevelStyleOpen.addAttribute("text:start-value", "1");
+ }
+ listLevelStyleOpen.write(pHandler);
+
+ TagOpenElement stylePropertiesOpen("style:list-level-properties");
+ if (mPropList["text:space-before"] && mPropList["text:space-before"]->getDouble() > 0.0f)
+ stylePropertiesOpen.addAttribute("text:space-before", mPropList["text:space-before"]->getStr());
+ if (mPropList["text:min-label-width"] && mPropList["text:min-label-width"]->getDouble() > 0.0f)
+ stylePropertiesOpen.addAttribute("text:min-label-width", mPropList["text:min-label-width"]->getStr());
+ if (mPropList["text:min-label-distance"] && mPropList["text:min-label-distance"]->getDouble() > 0.0f)
+ stylePropertiesOpen.addAttribute("text:min-label-distance", mPropList["text:min-label-distance"]->getStr());
+ stylePropertiesOpen.write(pHandler);
+
+ pHandler->endElement("style:list-level-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(DocumentHandlerInterface *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");
+ if (mPropList["text:bullet-char"] && (mPropList["text:bullet-char"]->getStr().len()))
+ {
+ // The following is needed because the odf format does not accept bullet chars longer than one character
+ WPXString::Iter i(mPropList["text:bullet-char"]->getStr()); i.rewind();
+ WPXString sEscapedString(".");
+ if (i.next())
+ sEscapedString = WPXString(i(), true);
+ listLevelStyleOpen.addAttribute("text:bullet-char", sEscapedString);
+
+ }
+ else
+ listLevelStyleOpen.addAttribute("text:bullet-char", ".");
+ listLevelStyleOpen.write(pHandler);
+
+ TagOpenElement stylePropertiesOpen("style:list-level-properties");
+ if (mPropList["text:space-before"] && mPropList["text:space-before"]->getDouble() > 0.0f)
+ stylePropertiesOpen.addAttribute("text:space-before", mPropList["text:space-before"]->getStr());
+ if (mPropList["text:min-label-width"] && mPropList["text:min-label-width"]->getDouble() > 0.0f)
+ stylePropertiesOpen.addAttribute("text:min-label-width", mPropList["text:min-label-width"]->getStr());
+ if (mPropList["text:min-label-distance"] && mPropList["text:min-label-distance"]->getDouble() > 0.0f)
+ stylePropertiesOpen.addAttribute("text:min-label-distance", mPropList["text:min-label-distance"]->getStr());
+ stylePropertiesOpen.addAttribute("style:font-name", "OpenSymbol");
+ stylePropertiesOpen.write(pHandler);
+
+ pHandler->endElement("style:list-level-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(DocumentHandlerInterface *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");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/ListStyle.hxx b/writerperfect/source/filter/ListStyle.hxx
new file mode 100644
index 000000000000..cbba20a8352e
--- /dev/null
+++ b/writerperfect/source/filter/ListStyle.hxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+#include <libwpd/libwpd.h>
+
+#define WP6_NUM_LIST_LEVELS 8 // see WP6FileStructure.h (we shouldn't need to reference this)
+
+#include "Style.hxx"
+#include "WriterProperties.hxx"
+#include "DocumentHandlerInterface.hxx"
+
+class DocumentElement;
+
+class ListLevelStyle
+{
+public:
+ virtual ~ListLevelStyle() {};
+ virtual void write(DocumentHandlerInterface *pHandler, int iLevel) const = 0;
+};
+
+class OrderedListLevelStyle : public ListLevelStyle
+{
+public:
+ OrderedListLevelStyle(const WPXPropertyList &xPropList);
+ void write(DocumentHandlerInterface *pHandler, int iLevel) const;
+private:
+ WPXPropertyList mPropList;
+};
+
+class UnorderedListLevelStyle : public ListLevelStyle
+{
+public:
+ UnorderedListLevelStyle(const WPXPropertyList &xPropList);
+ void write(DocumentHandlerInterface *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(DocumentHandlerInterface *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
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/OdgExporter.cxx b/writerperfect/source/filter/OdgExporter.cxx
new file mode 100644
index 000000000000..429fc8d10dd1
--- /dev/null
+++ b/writerperfect/source/filter/OdgExporter.cxx
@@ -0,0 +1,648 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ * Copyright (C) 2006 Fridrich Strba (fridrich.strba@bluewin.ch)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include "OdgExporter.hxx"
+#include "DocumentElement.hxx"
+#include "DocumentHandler.hxx"
+#include <locale.h>
+#include <math.h>
+#include <string>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+OdgExporter::OdgExporter(DocumentHandlerInterface *pHandler):
+ mpHandler(pHandler),
+ miGradientIndex(1),
+ miDashIndex(1),
+ miGraphicsStyleIndex(1),
+ mfWidth(0.0),
+ mfHeight(0.0)
+{
+}
+
+OdgExporter::~OdgExporter()
+{
+
+ for (std::vector<DocumentElement *>::iterator iterBody = mBodyElements.begin(); iterBody != mBodyElements.end(); iterBody++)
+ {
+ delete (*iterBody);
+ (*iterBody) = NULL;
+ }
+
+ for (std::vector<DocumentElement *>::iterator iterGraphicsAutomaticStyles = mGraphicsAutomaticStyles.begin();
+ iterGraphicsAutomaticStyles != mGraphicsAutomaticStyles.end(); iterGraphicsAutomaticStyles++)
+ {
+ delete((*iterGraphicsAutomaticStyles));
+ }
+
+ for (std::vector<DocumentElement *>::iterator iterGraphicsStrokeDashStyles = mGraphicsStrokeDashStyles.begin();
+ iterGraphicsStrokeDashStyles != mGraphicsStrokeDashStyles.end(); iterGraphicsStrokeDashStyles++)
+ {
+ delete((*iterGraphicsStrokeDashStyles));
+ }
+
+ for (std::vector<DocumentElement *>::iterator iterGraphicsGradientStyles = mGraphicsGradientStyles.begin();
+ iterGraphicsGradientStyles != mGraphicsGradientStyles.end(); iterGraphicsGradientStyles++)
+ {
+ delete((*iterGraphicsGradientStyles));
+ }
+}
+
+void OdgExporter::startGraphics(const ::WPXPropertyList &propList)
+{
+ miGradientIndex = 1;
+ miDashIndex = 1;
+ miGraphicsStyleIndex = 1;
+ mfWidth = 0.0;
+ mfHeight = 0.0;
+
+ if (propList["svg:width"])
+ mfWidth = propList["svg:width"]->getDouble();
+
+ if (propList["svg:height"])
+ mfHeight = propList["svg:height"]->getDouble();
+
+ mpHandler->startDocument();
+ TagOpenElement tmpOfficeDocumentContent("office:document");
+ tmpOfficeDocumentContent.addAttribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0");
+ tmpOfficeDocumentContent.addAttribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0");
+ tmpOfficeDocumentContent.addAttribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0");
+ tmpOfficeDocumentContent.addAttribute("xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0");
+ tmpOfficeDocumentContent.addAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/");
+ tmpOfficeDocumentContent.addAttribute("xmlns:svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0");
+ tmpOfficeDocumentContent.addAttribute("xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0");
+ tmpOfficeDocumentContent.addAttribute("xmlns:config", "urn:oasis:names:tc:opendocument:xmlns:config:1.0");
+ tmpOfficeDocumentContent.addAttribute("xmlns:ooo", "http://openoffice.org/2004/office");
+ tmpOfficeDocumentContent.addAttribute("office:version", "1.0");
+ tmpOfficeDocumentContent.addAttribute("office:mimetype", "application/vnd.oasis.opendocument.graphics");
+ tmpOfficeDocumentContent.write(mpHandler);
+
+ TagOpenElement("office:settings").write(mpHandler);
+
+ TagOpenElement configItemSetOpenElement("config:config-item-set");
+ configItemSetOpenElement.addAttribute("config:name", "ooo:view-settings");
+ configItemSetOpenElement.write(mpHandler);
+
+ TagOpenElement configItemOpenElement("config:config-item");
+
+ configItemOpenElement.addAttribute("config:name", "VisibleAreaTop");
+ configItemOpenElement.addAttribute("config:type", "int");
+ configItemOpenElement.write(mpHandler);
+ mpHandler->characters("0");
+ mpHandler->endElement("config:config-item");
+
+ configItemOpenElement.addAttribute("config:name", "VisibleAreaLeft");
+ configItemOpenElement.addAttribute("config:type", "int");
+ configItemOpenElement.write(mpHandler);
+ mpHandler->characters("0");
+ mpHandler->endElement("config:config-item");
+
+ configItemOpenElement.addAttribute("config:name", "VisibleAreaWidth");
+ configItemOpenElement.addAttribute("config:type", "int");
+ configItemOpenElement.write(mpHandler);
+ WPXString sWidth; sWidth.sprintf("%li", (unsigned long)(2540 * mfWidth));
+ mpHandler->characters(sWidth);
+ mpHandler->endElement("config:config-item");
+
+ configItemOpenElement.addAttribute("config:name", "VisibleAreaHeight");
+ configItemOpenElement.addAttribute("config:type", "int");
+ configItemOpenElement.write(mpHandler);
+ WPXString sHeight; sHeight.sprintf("%li", (unsigned long)(2540 * mfHeight));
+ mpHandler->characters(sHeight);
+ mpHandler->endElement("config:config-item");
+
+ mpHandler->endElement("config:config-item-set");
+
+ mpHandler->endElement("office:settings");
+}
+
+void OdgExporter::endGraphics()
+{
+ TagOpenElement("office:styles").write(mpHandler);
+
+ for (std::vector<DocumentElement *>::const_iterator iterGraphicsStrokeDashStyles = mGraphicsStrokeDashStyles.begin();
+ iterGraphicsStrokeDashStyles != mGraphicsStrokeDashStyles.end(); iterGraphicsStrokeDashStyles++)
+ {
+ (*iterGraphicsStrokeDashStyles)->write(mpHandler);
+ }
+
+ for (std::vector<DocumentElement *>::const_iterator iterGraphicsGradientStyles = mGraphicsGradientStyles.begin();
+ iterGraphicsGradientStyles != mGraphicsGradientStyles.end(); iterGraphicsGradientStyles++)
+ {
+ (*iterGraphicsGradientStyles)->write(mpHandler);
+ }
+
+ mpHandler->endElement("office:styles");
+
+ TagOpenElement("office:automatic-styles").write(mpHandler);
+
+ // writing out the graphics automatic styles
+ for (std::vector<DocumentElement *>::iterator iterGraphicsAutomaticStyles = mGraphicsAutomaticStyles.begin();
+ iterGraphicsAutomaticStyles != mGraphicsAutomaticStyles.end(); iterGraphicsAutomaticStyles++)
+ {
+ (*iterGraphicsAutomaticStyles)->write(mpHandler);
+ }
+
+ TagOpenElement tmpStylePageLayoutOpenElement("style:page-layout");
+ tmpStylePageLayoutOpenElement.addAttribute("style:name", "PM0");
+ tmpStylePageLayoutOpenElement.write(mpHandler);
+
+ TagOpenElement tmpStylePageLayoutPropertiesOpenElement("style:page-layout-properties");
+ tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-top", "0in");
+ tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-bottom", "0in");
+ tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-left", "0in");
+ tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-right", "0in");
+ WPXString sValue;
+ sValue = doubleToString(mfWidth); sValue.append("in");
+ tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-width", sValue);
+ sValue = doubleToString(mfHeight); sValue.append("in");
+ tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-height", sValue);
+ tmpStylePageLayoutPropertiesOpenElement.addAttribute("style:print-orientation", "portrait");
+ tmpStylePageLayoutPropertiesOpenElement.write(mpHandler);
+
+ mpHandler->endElement("style:page-layout-properties");
+
+ mpHandler->endElement("style:page-layout");
+
+ TagOpenElement tmpStyleStyleOpenElement("style:style");
+ tmpStyleStyleOpenElement.addAttribute("style:name", "dp1");
+ tmpStyleStyleOpenElement.addAttribute("style:family", "drawing-page");
+ tmpStyleStyleOpenElement.write(mpHandler);
+
+ TagOpenElement tmpStyleDrawingPagePropertiesOpenElement("style:drawing-page-properties");
+ // tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:background-size", "border");
+ tmpStyleDrawingPagePropertiesOpenElement.addAttribute("draw:fill", "none");
+ tmpStyleDrawingPagePropertiesOpenElement.write(mpHandler);
+
+ mpHandler->endElement("style:drawing-page-properties");
+
+ mpHandler->endElement("style:style");
+
+ mpHandler->endElement("office:automatic-styles");
+
+ TagOpenElement("office:master-styles").write(mpHandler);
+
+ TagOpenElement tmpStyleMasterPageOpenElement("style:master-page");
+ tmpStyleMasterPageOpenElement.addAttribute("style:name", "Default");
+ tmpStyleMasterPageOpenElement.addAttribute("style:page-layout-name", "PM0");
+ tmpStyleMasterPageOpenElement.addAttribute("draw:style-name", "dp1");
+ tmpStyleMasterPageOpenElement.write(mpHandler);
+
+ mpHandler->endElement("style:master-page");
+
+ mpHandler->endElement("office:master-styles");
+
+ TagOpenElement("office:body").write(mpHandler);
+
+ TagOpenElement("office:drawing").write(mpHandler);
+
+ TagOpenElement tmpDrawPageOpenElement("draw:page");
+ tmpDrawPageOpenElement.addAttribute("draw:name", "page1");
+ tmpDrawPageOpenElement.addAttribute("draw:style-name", "dp1");
+ tmpDrawPageOpenElement.addAttribute("draw:master-page-name", "Default");
+ tmpDrawPageOpenElement.write(mpHandler);
+
+ for (std::vector<DocumentElement *>::const_iterator bodyIter = mBodyElements.begin();
+ bodyIter != mBodyElements.end(); bodyIter++)
+ {
+ (*bodyIter)->write(mpHandler);
+ }
+
+ mpHandler->endElement("draw:page");
+ mpHandler->endElement("office:drawing");
+ mpHandler->endElement("office:body");
+
+ mpHandler->endElement("office:document");
+
+ mpHandler->endDocument();
+}
+
+void OdgExporter::setStyle(const ::WPXPropertyList & propList, const ::WPXPropertyListVector& gradient)
+{
+ mxStyle = propList;
+ mxGradient = gradient;
+}
+
+void OdgExporter::startLayer(const ::WPXPropertyList & /* propList */)
+{
+}
+
+void OdgExporter::endLayer()
+{
+}
+
+void OdgExporter::drawRectangle(const ::WPXPropertyList &propList)
+{
+ writeGraphicsStyle();
+ TagOpenElement *pDrawRectElement = new TagOpenElement("draw:rect");
+ WPXString sValue;
+ sValue.sprintf("gr%i", miGraphicsStyleIndex-1);
+ pDrawRectElement->addAttribute("draw:style-name", sValue);
+ pDrawRectElement->addAttribute("svg:x", propList["svg:x"]->getStr());
+ pDrawRectElement->addAttribute("svg:y", propList["svg:y"]->getStr());
+ pDrawRectElement->addAttribute("svg:width", propList["svg:width"]->getStr());
+ pDrawRectElement->addAttribute("svg:height", propList["svg:height"]->getStr());
+ // FIXME: what to do when rx != ry ?
+ if (propList["svg:rx"])
+ pDrawRectElement->addAttribute("draw:corner-radius", propList["svg:rx"]->getStr());
+ else
+ pDrawRectElement->addAttribute("draw:corner-radius", "0.0000in");
+ mBodyElements.push_back(pDrawRectElement);
+ mBodyElements.push_back(new TagCloseElement("draw:rect"));
+}
+
+void OdgExporter::drawEllipse(const ::WPXPropertyList &propList)
+{
+ writeGraphicsStyle();
+ TagOpenElement *pDrawEllipseElement = new TagOpenElement("draw:ellipse");
+ WPXString sValue;
+ sValue.sprintf("gr%i", miGraphicsStyleIndex-1);
+ pDrawEllipseElement->addAttribute("draw:style-name", sValue);
+ sValue = doubleToString(2 * propList["svg:rx"]->getDouble()); sValue.append("in");
+ pDrawEllipseElement->addAttribute("svg:width", sValue);
+ sValue = doubleToString(2 * propList["svg:ry"]->getDouble()); sValue.append("in");
+ pDrawEllipseElement->addAttribute("svg:height", sValue);
+ if (propList["libwpg:rotate"] && propList["libwpg:rotate"]->getDouble() != 0.0)
+ {
+ double rotation = propList["libwpg:rotate"]->getDouble();
+ while(rotation < -180)
+ rotation += 360;
+ while(rotation > 180)
+ rotation -= 360;
+ double radrotation = rotation*M_PI/180.0;
+ double deltax = sqrt(pow(propList["svg:rx"]->getDouble(), 2.0)
+ + pow(propList["svg:ry"]->getDouble(), 2.0))*cos(atan(propList["svg:ry"]->getDouble()/propList["svg:rx"]->getDouble())
+ - radrotation ) - propList["svg:rx"]->getDouble();
+ double deltay = sqrt(pow(propList["svg:rx"]->getDouble(), 2.0)
+ + pow(propList["svg:ry"]->getDouble(), 2.0))*sin(atan(propList["svg:ry"]->getDouble()/propList["svg:rx"]->getDouble())
+ - radrotation ) - propList["svg:ry"]->getDouble();
+ sValue = "rotate("; sValue.append(doubleToString(radrotation)); sValue.append(") ");
+ sValue.append("translate("); sValue.append(doubleToString(propList["svg:cx"]->getDouble() - propList["svg:rx"]->getDouble() - deltax));
+ sValue.append("in, ");
+ sValue.append(doubleToString(propList["svg:cy"]->getDouble() - propList["svg:ry"]->getDouble() - deltay)); sValue.append("in)");
+ pDrawEllipseElement->addAttribute("draw:transform", sValue);
+ }
+ else
+ {
+ sValue = doubleToString(propList["svg:cx"]->getDouble()-propList["svg:rx"]->getDouble()); sValue.append("in");
+ pDrawEllipseElement->addAttribute("svg:x", sValue);
+ sValue = doubleToString(propList["svg:cy"]->getDouble()-propList["svg:ry"]->getDouble()); sValue.append("in");
+ pDrawEllipseElement->addAttribute("svg:y", sValue);
+ }
+ mBodyElements.push_back(pDrawEllipseElement);
+ mBodyElements.push_back(new TagCloseElement("draw:ellipse"));
+}
+
+void OdgExporter::drawPolyline(const ::WPXPropertyListVector& vertices)
+{
+ drawPolySomething(vertices, false);
+}
+
+void OdgExporter::drawPolygon(const ::WPXPropertyListVector& vertices)
+{
+ drawPolySomething(vertices, true);
+}
+
+void OdgExporter::drawPolySomething(const ::WPXPropertyListVector& vertices, bool isClosed)
+{
+ if(vertices.count() < 2)
+ return;
+
+ if(vertices.count() == 2)
+ {
+ writeGraphicsStyle();
+ TagOpenElement *pDrawLineElement = new TagOpenElement("draw:line");
+ WPXString sValue;
+ sValue.sprintf("gr%i", miGraphicsStyleIndex-1);
+ pDrawLineElement->addAttribute("draw:style-name", sValue);
+ pDrawLineElement->addAttribute("draw:text-style-name", "P1");
+ pDrawLineElement->addAttribute("draw:layer", "layout");
+ pDrawLineElement->addAttribute("svg:x1", vertices[0]["svg:x"]->getStr());
+ pDrawLineElement->addAttribute("svg:y1", vertices[0]["svg:y"]->getStr());
+ pDrawLineElement->addAttribute("svg:x2", vertices[1]["svg:x"]->getStr());
+ pDrawLineElement->addAttribute("svg:y2", vertices[1]["svg:y"]->getStr());
+ mBodyElements.push_back(pDrawLineElement);
+ mBodyElements.push_back(new TagCloseElement("draw:line"));
+ }
+ else
+ {
+ ::WPXPropertyListVector path;
+ ::WPXPropertyList element;
+
+ for (unsigned long ii = 0; ii < vertices.count(); ii++)
+ {
+ element = vertices[ii];
+ if (ii == 0)
+ element.insert("libwpg:path-action", "M");
+ else
+ element.insert("libwpg:path-action", "L");
+ path.append(element);
+ element.clear();
+ }
+ if (isClosed)
+ {
+ element.insert("libwpg:path-action", "Z");
+ path.append(element);
+ }
+ drawPath(path);
+ }
+}
+
+void OdgExporter::drawPath(const WPXPropertyListVector& path)
+{
+ if(path.count() == 0)
+ return;
+
+ // try to find the bounding box
+ // this is simple convex hull technique, the bounding box might not be
+ // accurate but that should be enough for this purpose
+ double px = path[0]["svg:x"]->getDouble();
+ double py = path[0]["svg:y"]->getDouble();
+ double qx = path[0]["svg:x"]->getDouble();
+ double qy = path[0]["svg:y"]->getDouble();
+ for(unsigned k = 0; k < path.count(); k++)
+ {
+ if (!path[k]["svg:x"] || !path[k]["svg:y"])
+ continue;
+ px = (px > path[k]["svg:x"]->getDouble()) ? path[k]["svg:x"]->getDouble() : px;
+ py = (py > path[k]["svg:y"]->getDouble()) ? path[k]["svg:y"]->getDouble() : py;
+ qx = (qx < path[k]["svg:x"]->getDouble()) ? path[k]["svg:x"]->getDouble() : qx;
+ qy = (qy < path[k]["svg:y"]->getDouble()) ? path[k]["svg:y"]->getDouble() : qy;
+ if(path[k]["libwpg:path-action"]->getStr() == "C")
+ {
+ px = (px > path[k]["svg:x1"]->getDouble()) ? path[k]["svg:x1"]->getDouble() : px;
+ py = (py > path[k]["svg:y1"]->getDouble()) ? path[k]["svg:y1"]->getDouble() : py;
+ qx = (qx < path[k]["svg:x1"]->getDouble()) ? path[k]["svg:x1"]->getDouble() : qx;
+ qy = (qy < path[k]["svg:y1"]->getDouble()) ? path[k]["svg:y1"]->getDouble() : qy;
+ px = (px > path[k]["svg:x2"]->getDouble()) ? path[k]["svg:x2"]->getDouble() : px;
+ py = (py > path[k]["svg:y2"]->getDouble()) ? path[k]["svg:y2"]->getDouble() : py;
+ qx = (qx < path[k]["svg:x2"]->getDouble()) ? path[k]["svg:x2"]->getDouble() : qx;
+ qy = (qy < path[k]["svg:y2"]->getDouble()) ? path[k]["svg:y2"]->getDouble() : qy;
+ }
+ if(path[k]["libwpg:path-action"]->getStr() == "A")
+ {
+ px = (px > path[k]["svg:x"]->getDouble()-2*path[k]["svg:rx"]->getDouble()) ? path[k]["svg:x"]->getDouble()-2*path[k]["svg:rx"]->getDouble() : px;
+ py = (py > path[k]["svg:y"]->getDouble()-2*path[k]["svg:ry"]->getDouble()) ? path[k]["svg:y"]->getDouble()-2*path[k]["svg:ry"]->getDouble() : py;
+ qx = (qx < path[k]["svg:x"]->getDouble()+2*path[k]["svg:rx"]->getDouble()) ? path[k]["svg:x"]->getDouble()+2*path[k]["svg:rx"]->getDouble() : qx;
+ qy = (qy < path[k]["svg:y"]->getDouble()+2*path[k]["svg:ry"]->getDouble()) ? path[k]["svg:y"]->getDouble()+2*path[k]["svg:ry"]->getDouble() : qy;
+ }
+ }
+ double vw = qx - px;
+ double vh = qy - py;
+
+ writeGraphicsStyle();
+
+ TagOpenElement *pDrawPathElement = new TagOpenElement("draw:path");
+ WPXString sValue;
+ sValue.sprintf("gr%i", miGraphicsStyleIndex-1);
+ pDrawPathElement->addAttribute("draw:style-name", sValue);
+ pDrawPathElement->addAttribute("draw:text-style-name", "P1");
+ pDrawPathElement->addAttribute("draw:layer", "layout");
+ sValue = doubleToString(px); sValue.append("in");
+ pDrawPathElement->addAttribute("svg:x", sValue);
+ sValue = doubleToString(py); sValue.append("in");
+ pDrawPathElement->addAttribute("svg:y", sValue);
+ sValue = doubleToString(vw); sValue.append("in");
+ pDrawPathElement->addAttribute("svg:width", sValue);
+ sValue = doubleToString(vh); sValue.append("in");
+ pDrawPathElement->addAttribute("svg:height", sValue);
+ sValue.sprintf("%i %i %i %i", 0, 0, (unsigned)(vw*2540), (unsigned)(vh*2540));
+ pDrawPathElement->addAttribute("svg:viewBox", sValue);
+
+ sValue.clear();
+ for(unsigned i = 0; i < path.count(); i++)
+ {
+ WPXString sElement;
+ if (path[i]["libwpg:path-action"]->getStr() == "M")
+ {
+ // 2540 is 2.54*1000, 2.54 in = 1 inch
+ sElement.sprintf("M%i %i", (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540),
+ (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540));
+ sValue.append(sElement);
+ }
+ else if (path[i]["libwpg:path-action"]->getStr() == "L")
+ {
+ sElement.sprintf("L%i %i", (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540),
+ (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540));
+ sValue.append(sElement);
+ }
+ else if (path[i]["libwpg:path-action"]->getStr() == "C")
+ {
+ sElement.sprintf("C%i %i %i %i %i %i", (unsigned)((path[i]["svg:x1"]->getDouble()-px)*2540),
+ (int)((path[i]["svg:y1"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x2"]->getDouble()-px)*2540),
+ (int)((path[i]["svg:y2"]->getDouble()-py)*2540), (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540),
+ (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540));
+ sValue.append(sElement);
+ }
+ else if (path[i]["libwpg:path-action"]->getStr() == "A")
+ {
+ sElement.sprintf("A%i %i %i %i %i %i %i", (unsigned)((path[i]["svg:rx"]->getDouble())*2540),
+ (int)((path[i]["svg:ry"]->getDouble())*2540), (path[i]["libwpg:rotate"] ? path[i]["libwpg:rotate"]->getInt() : 0),
+ 0, 0, (unsigned)((path[i]["svg:x"]->getDouble()-px)*2540), (unsigned)((path[i]["svg:y"]->getDouble()-py)*2540));
+ sValue.append(sElement);
+ }
+ else if (path[i]["libwpg:path-action"]->getStr() == "Z" && i >= (path.count() - 1))
+ sValue.append(" Z");
+ }
+ pDrawPathElement->addAttribute("svg:d", sValue);
+ mBodyElements.push_back(pDrawPathElement);
+ mBodyElements.push_back(new TagCloseElement("draw:path"));
+}
+
+void OdgExporter::drawGraphicObject(const ::WPXPropertyList &propList, const ::WPXBinaryData& binaryData)
+{
+ if (!propList["libwpg:mime-type"] && propList["libwpg:mime-type"]->getStr().len() <= 0)
+ return;
+ TagOpenElement *pDrawFrameElement = new TagOpenElement("draw:frame");
+
+
+ WPXString sValue;
+ if (propList["svg:x"])
+ pDrawFrameElement->addAttribute("svg:x", propList["svg:x"]->getStr());
+ if (propList["svg:y"])
+ pDrawFrameElement->addAttribute("svg:y", propList["svg:y"]->getStr());
+ if (propList["svg:height"])
+ pDrawFrameElement->addAttribute("svg:height", propList["svg:height"]->getStr());
+ if (propList["svg:width"])
+ pDrawFrameElement->addAttribute("svg:width", propList["svg:width"]->getStr());
+ mBodyElements.push_back(pDrawFrameElement);
+
+ mBodyElements.push_back(new TagOpenElement("draw:image"));
+
+ mBodyElements.push_back(new TagOpenElement("office:binary-data"));
+
+ ::WPXString base64Binary = binaryData.getBase64Data();
+ mBodyElements.push_back(new CharDataElement(base64Binary.cstr()));
+
+ mBodyElements.push_back(new TagCloseElement("office:binary-data"));
+
+ mBodyElements.push_back(new TagCloseElement("draw:image"));
+
+ mBodyElements.push_back(new TagCloseElement("draw:frame"));
+}
+
+void OdgExporter::writeGraphicsStyle()
+{
+#if 0
+ if(mxStyle["libwpg:stroke-solid"] && !mxStyle["libwpg:stroke-solid"]->getInt() && (mxDashArray.count() >=2 ) )
+ {
+ // ODG only supports dashes with the same length of spaces inbetween
+ // here we take the first space and assume everything else the same
+ // note that dash length is written in percentage ?????????????????
+ double distance = mxDashArray.at(1);
+ TagOpenElement *pDrawStrokeDashElement = new TagOpenElement("draw:stroke-dash");
+ pDrawStrokeDashElement->addAttribute("draw:style", "rect");
+ WPXString sValue;
+ sValue.sprintf("Dash_%i", miDashIndex++);
+ pDrawStrokeDashElement->addAttribute("draw:name", sValue);
+ sValue = doubleToString(distance); sValue.append("in");
+ pDrawStrokeDashElement->addAttribute("draw:distance", sValue);
+ WPXString sName;
+ // We have to find out how to do this intelligently, since the ODF is allowing only
+ // two pairs draw:dots1 draw:dots1-length and draw:dots2 draw:dots2-length
+ for(unsigned i = 0; i < mxDashArray.count()/2 && i < 2; i++)
+ {
+ sName.sprintf("draw:dots%i", i+1);
+ pDrawStrokeDashElement->addAttribute(sName.cstr(), "1");
+ sName.sprintf("draw:dots%i-length", i+1);
+ sValue = doubleToString(mxDashArray.at(i*2)); sValue.append("in");
+ pDrawStrokeDashElement->addAttribute(sName.cstr(), sValue);
+ }
+ mGraphicsStrokeDashStyles.push_back(pDrawStrokeDashElement);
+ mGraphicsStrokeDashStyles.push_back(new TagCloseElement("draw:stroke-dash"));
+ }
+#endif
+ if(mxStyle["draw:fill"] && mxStyle["draw:fill"]->getStr() == "gradient" && mxGradient.count() >= 2)
+ {
+ TagOpenElement *pDrawGradientElement = new TagOpenElement("draw:gradient");
+ pDrawGradientElement->addAttribute("draw:style", "linear");
+ WPXString sValue;
+ sValue.sprintf("Gradient_%i", miGradientIndex++);
+ pDrawGradientElement->addAttribute("draw:name", sValue);
+
+ // ODG angle unit is 0.1 degree
+ double angle = mxStyle["draw:angle"] ? -mxStyle["draw:angle"]->getDouble() : 0.0;
+ while(angle < 0)
+ angle += 360;
+ while(angle > 360)
+ angle -= 360;
+
+ sValue.sprintf("%i", (unsigned)(angle*10));
+ pDrawGradientElement->addAttribute("draw:angle", sValue);
+
+ pDrawGradientElement->addAttribute("draw:start-color", mxGradient[0]["svg:stop-color"]->getStr().cstr());
+ pDrawGradientElement->addAttribute("draw:end-color", mxGradient[1]["svg:stop-color"]->getStr().cstr());
+ pDrawGradientElement->addAttribute("draw:start-intensity", "100%");
+ pDrawGradientElement->addAttribute("draw:end-intensity", "100%");
+ pDrawGradientElement->addAttribute("draw:border", "0%");
+ mGraphicsGradientStyles.push_back(pDrawGradientElement);
+ mGraphicsGradientStyles.push_back(new TagCloseElement("draw:gradient"));
+ }
+
+ TagOpenElement *pStyleStyleElement = new TagOpenElement("style:style");
+ WPXString sValue;
+ sValue.sprintf("gr%i", miGraphicsStyleIndex);
+ pStyleStyleElement->addAttribute("style:name", sValue);
+ pStyleStyleElement->addAttribute("style:family", "graphic");
+ pStyleStyleElement->addAttribute("style:parent-style-name", "standard");
+ mGraphicsAutomaticStyles.push_back(pStyleStyleElement);
+
+ TagOpenElement *pStyleGraphicsPropertiesElement = new TagOpenElement("style:graphic-properties");
+
+ if(!(mxStyle["draw:stroke"] && mxStyle["draw:stroke"]->getStr() == "none") && mxStyle["svg:stroke-width"] && mxStyle["svg:stroke-width"]->getDouble() > 0.0)
+ {
+ if (mxStyle["svg:stroke-width"])
+ pStyleGraphicsPropertiesElement->addAttribute("svg:stroke-width", mxStyle["svg:stroke-width"]->getStr());
+
+ if (mxStyle["svg:stroke-color"])
+ pStyleGraphicsPropertiesElement->addAttribute("svg:stroke-color", mxStyle["svg:stroke-color"]->getStr());
+ if (mxStyle["svg:stroke-opacity"] && mxStyle["svg:stroke-opacity"]->getDouble() != 1.0)
+ pStyleGraphicsPropertiesElement->addAttribute("svg:stroke-opacity", mxStyle["svg:stroke-opacity"]->getStr());
+
+
+ if(mxStyle["libwpg:stroke-solid"] && mxStyle["libwpg:stroke-solid"]->getInt())
+ pStyleGraphicsPropertiesElement->addAttribute("draw:stroke", "solid");
+#if 0
+ else
+ {
+ pStyleGraphicsPropertiesElement->addAttribute("draw:stroke", "dash");
+ sValue.sprintf("Dash_%i", miDashIndex-1);
+ pStyleGraphicsPropertiesElement->addAttribute("draw:stroke-dash", sValue);
+ }
+#endif
+ }
+ else
+ pStyleGraphicsPropertiesElement->addAttribute("draw:stroke", "none");
+
+ if(mxStyle["draw:fill"] && mxStyle["draw:fill"]->getStr() == "none")
+ pStyleGraphicsPropertiesElement->addAttribute("draw:fill", "none");
+
+ if(mxStyle["draw:fill"] && mxStyle["draw:fill"]->getStr() == "solid")
+ {
+ pStyleGraphicsPropertiesElement->addAttribute("draw:fill", "solid");
+ if (mxStyle["draw:fill-color"])
+ pStyleGraphicsPropertiesElement->addAttribute("draw:fill-color", mxStyle["draw:fill-color"]->getStr());
+ if (mxStyle["draw:opacity"] && mxStyle["draw:opacity"]->getDouble() != 1.0)
+ pStyleGraphicsPropertiesElement->addAttribute("draw:opacity", mxStyle["draw:opacity"]->getStr());
+ }
+
+ if(mxStyle["draw:fill"] && mxStyle["draw:fill"]->getStr() == "gradient")
+ {
+ if (mxGradient.count() >= 2)
+ {
+ pStyleGraphicsPropertiesElement->addAttribute("draw:fill", "gradient");
+ sValue.sprintf("Gradient_%i", miGradientIndex-1);
+ pStyleGraphicsPropertiesElement->addAttribute("draw:fill-gradient-name", sValue);
+ }
+ else
+ pStyleGraphicsPropertiesElement->addAttribute("draw:fill", "none");
+ }
+
+ mGraphicsAutomaticStyles.push_back(pStyleGraphicsPropertiesElement);
+ mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:graphic-properties"));
+
+ mGraphicsAutomaticStyles.push_back(new TagCloseElement("style:style"));
+ miGraphicsStyleIndex++;
+}
+
+WPXString OdgExporter::doubleToString(const double value)
+{
+ WPXString tempString;
+ tempString.sprintf("%.4f", value);
+ std::string decimalPoint(localeconv()->decimal_point);
+ if ((decimalPoint.size() == 0) || (decimalPoint == "."))
+ return tempString;
+ std::string stringValue(tempString.cstr());
+ if (!stringValue.empty())
+ {
+ std::string::size_type pos;
+ while ((pos = stringValue.find(decimalPoint)) != std::string::npos)
+ stringValue.replace(pos,decimalPoint.size(),".");
+ }
+ return WPXString(stringValue.c_str());
+}
diff --git a/writerperfect/source/filter/OdgExporter.hxx b/writerperfect/source/filter/OdgExporter.hxx
new file mode 100644
index 000000000000..948d3b87374c
--- /dev/null
+++ b/writerperfect/source/filter/OdgExporter.hxx
@@ -0,0 +1,90 @@
+/* libwpg
+ * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02111-1301 USA
+ *
+ * For further information visit http://libwpg.sourceforge.net
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#ifndef __ODGEXPORTER_HXX__
+#define __ODGEXPORTER_HXX__
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <libwpd/libwpd.h>
+#include <libwpg/libwpg.h>
+#include "DocumentElement.hxx"
+#include "DocumentHandler.hxx"
+#include "FilterInternal.hxx"
+
+class OdgExporter : public libwpg::WPGPaintInterface {
+public:
+ OdgExporter(DocumentHandlerInterface *pHandler);
+ ~OdgExporter();
+
+ void startGraphics(const ::WPXPropertyList &propList);
+ void endGraphics();
+ void startLayer(const ::WPXPropertyList &propList);
+ void endLayer();
+ void startEmbeddedGraphics(const ::WPXPropertyList& /*propList*/) {}
+ void endEmbeddedGraphics() {}
+
+ void setStyle(const ::WPXPropertyList &propList, const ::WPXPropertyListVector& gradient);
+
+ void drawRectangle(const ::WPXPropertyList &propList);
+ void drawEllipse(const ::WPXPropertyList &propList);
+ void drawPolyline(const ::WPXPropertyListVector& vertices);
+ void drawPolygon(const ::WPXPropertyListVector& vertices);
+ void drawPath(const ::WPXPropertyListVector& path);
+ void drawGraphicObject(const ::WPXPropertyList &propList, const ::WPXBinaryData& binaryData);
+ void startTextObject(const ::WPXPropertyList & /*propList*/, const ::WPXPropertyListVector &/*path*/) {}
+ void endTextObject() {}
+ void startTextLine(const ::WPXPropertyList & /*propList*/) {}
+ void endTextLine() {}
+ void startTextSpan(const ::WPXPropertyList & /*propList*/) {}
+ void endTextSpan() {}
+ void insertText(const ::WPXString & /*str*/) {}
+
+private:
+ void writeGraphicsStyle();
+ WPXString doubleToString(const double value);
+ void drawPolySomething(const ::WPXPropertyListVector& vertices, bool isClosed);
+
+ // body elements
+ std::vector <DocumentElement *> mBodyElements;
+
+ // graphics styles
+ std::vector<DocumentElement *> mGraphicsStrokeDashStyles;
+ std::vector<DocumentElement *> mGraphicsGradientStyles;
+ std::vector<DocumentElement *> mGraphicsAutomaticStyles;
+
+ DocumentHandlerInterface *mpHandler;
+
+ ::WPXPropertyList mxStyle;
+ ::WPXPropertyListVector mxGradient;
+ int miGradientIndex;
+ int miDashIndex;
+ int miGraphicsStyleIndex;
+ double mfWidth;
+ double mfHeight;
+};
+
+#endif // __ODGEXPORTER_HXX__
diff --git a/writerperfect/source/filter/PageSpan.cxx b/writerperfect/source/filter/PageSpan.cxx
new file mode 100644
index 000000000000..7ff4d1ce6977
--- /dev/null
+++ b/writerperfect/source/filter/PageSpan.cxx
@@ -0,0 +1,276 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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"
+#include "DocumentHandler.hxx"
+
+PageSpan::PageSpan(const WPXPropertyList &xPropList) :
+ mxPropList(xPropList),
+ mpHeaderContent(NULL),
+ mpFooterContent(NULL),
+ mpHeaderLeftContent(NULL),
+ mpFooterLeftContent(NULL)
+{
+}
+
+namespace {
+ typedef std::vector<DocumentElement *>::iterator DEVIter;
+}
+
+PageSpan::~PageSpan()
+{
+ 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
+}
+
+double PageSpan::getMarginLeft() const
+{
+ if (mxPropList["fo:margin-left"])
+ return mxPropList["fo:margin-left"]->getDouble();
+
+ return 0.0;
+}
+
+double PageSpan::getMarginRight() const
+{
+ if (mxPropList["fo:margin-right"])
+ return mxPropList["fo:margin-right"]->getDouble();
+
+ return 0.0;
+}
+
+void PageSpan::setHeaderContent(std::vector<DocumentElement *> * pHeaderContent)
+{
+ if (mpHeaderContent)
+ {
+ for (DEVIter iterHeaderContent = mpHeaderContent->begin();
+ iterHeaderContent != mpHeaderContent->end();
+ iterHeaderContent++)
+ delete(*iterHeaderContent);
+ delete mpHeaderContent;
+ }
+
+ mpHeaderContent = pHeaderContent;
+}
+
+void PageSpan::setFooterContent(std::vector<DocumentElement *> * pFooterContent)
+{
+ if (mpFooterContent)
+ {
+ for (DEVIter iterFooterContent = mpFooterContent->begin();
+ iterFooterContent != mpFooterContent->end();
+ iterFooterContent++)
+ delete(*iterFooterContent);
+ delete mpFooterContent;
+ }
+
+ mpFooterContent = pFooterContent;
+}
+
+void PageSpan::setHeaderLeftContent(std::vector<DocumentElement *> * pHeaderContent)
+{
+ if (mpHeaderLeftContent)
+ {
+ for (DEVIter iterHeaderLeftContent = mpHeaderLeftContent->begin();
+ iterHeaderLeftContent != mpHeaderLeftContent->end();
+ iterHeaderLeftContent++)
+ delete(*iterHeaderLeftContent);
+ delete mpHeaderLeftContent;
+ }
+
+ mpHeaderLeftContent = pHeaderContent;
+}
+
+void PageSpan::setFooterLeftContent(std::vector<DocumentElement *> * pFooterContent)
+{
+ if (mpFooterLeftContent)
+ {
+ for (DEVIter iterFooterLeftContent = mpFooterLeftContent->begin();
+ iterFooterLeftContent != mpFooterLeftContent->end();
+ iterFooterLeftContent++)
+ delete(*iterFooterLeftContent);
+ delete mpFooterLeftContent;
+ }
+
+ mpFooterLeftContent = pFooterContent;
+}
+
+void PageSpan::writePageLayout(const int iNum, DocumentHandlerInterface *pHandler) const
+{
+ WPXPropertyList propList;
+
+ WPXString sPageLayoutName;
+ sPageLayoutName.sprintf("PM%i", iNum+2);
+ propList.insert("style:name", sPageLayoutName);
+ pHandler->startElement("style:page-layout", 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("0in"));
+ pHandler->startElement("style:page-layout-properties", tempPropList);
+
+ WPXPropertyList footnoteSepPropList;
+ footnoteSepPropList.insert("style:width", WPXString("0.0071in"));
+ footnoteSepPropList.insert("style:distance-before-sep", WPXString("0.0398in"));
+ footnoteSepPropList.insert("style:distance-after-sep", WPXString("0.0398in"));
+ 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:page-layout-properties");
+ pHandler->endElement("style:page-layout");
+}
+
+void PageSpan::writeMasterPages(const int iStartingNum, const int iPageLayoutNum, const bool bLastPageSpan,
+ DocumentHandlerInterface *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, sMasterPageDisplayName;
+ sMasterPageName.sprintf("Page_Style_%i", i);
+ sMasterPageDisplayName.sprintf("Page Style %i", i);
+ WPXString sPageLayoutName;
+ WPXPropertyList propList;
+ sPageLayoutName.sprintf("PM%i", iPageLayoutNum+2);
+ propList.insert("style:name", sMasterPageName);
+ propList.insert("style:display-name", sMasterPageDisplayName);
+ propList.insert("style:page-layout-name", sPageLayoutName);
+ 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);
+ pHandler->endElement("style:header");
+ if (mpHeaderLeftContent)
+ {
+ _writeHeaderFooter("style:header-left", *mpHeaderLeftContent, pHandler);
+ pHandler->endElement("style:header-left");
+ }
+ }
+ else if (mpHeaderLeftContent)
+ {
+ TagOpenElement("style:header").write(pHandler);
+ pHandler->endElement("style:header");
+ _writeHeaderFooter("style:header-left", *mpHeaderLeftContent, pHandler);
+ pHandler->endElement("style:header-left");
+ }
+
+ if (mpFooterContent)
+ {
+ _writeHeaderFooter("style:footer", *mpFooterContent, pHandler);
+ pHandler->endElement("style:footer");
+ if (mpFooterLeftContent)
+ {
+ _writeHeaderFooter("style:footer-left", *mpFooterLeftContent, pHandler);
+ pHandler->endElement("style:footer-left");
+ }
+ }
+ else if (mpFooterLeftContent)
+ {
+ TagOpenElement("style:footer").write(pHandler);
+ pHandler->endElement("style:footer");
+ _writeHeaderFooter("style:footer-left", *mpFooterLeftContent, pHandler);
+ pHandler->endElement("style:footer-left");
+ }
+
+ pHandler->endElement("style:master-page");
+ }
+
+}
+
+void PageSpan::_writeHeaderFooter(const char *headerFooterTagName,
+ const std::vector<DocumentElement *> & headerFooterContent,
+ DocumentHandlerInterface *pHandler) const
+{
+ TagOpenElement headerFooterOpen(headerFooterTagName);
+ headerFooterOpen.write(pHandler);
+ for (std::vector<DocumentElement *>::const_iterator iter = headerFooterContent.begin();
+ iter != headerFooterContent.end();
+ ++iter) {
+ (*iter)->write(pHandler);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/PageSpan.hxx b/writerperfect/source/filter/PageSpan.hxx
new file mode 100644
index 000000000000..92eba26fe4a4
--- /dev/null
+++ b/writerperfect/source/filter/PageSpan.hxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+#include <libwpd/libwpd.h>
+#include <vector>
+
+class DocumentElement;
+class DocumentHandlerInterface;
+
+class PageSpan
+{
+public:
+ PageSpan(const WPXPropertyList &xPropList);
+ virtual ~PageSpan();
+ void writePageLayout(const int iNum, DocumentHandlerInterface *pHandler) const;
+ void writeMasterPages(const int iStartingNum, const int iPageLayoutNum, const bool bLastPageSpan, DocumentHandlerInterface *pHandler) const;
+ int getSpan() const;
+ double getMarginLeft() const;
+ double getMarginRight() const;
+
+ void setHeaderContent(std::vector<DocumentElement *> * pHeaderContent);
+ void setFooterContent(std::vector<DocumentElement *> * pFooterContent);
+ void setHeaderLeftContent(std::vector<DocumentElement *> * pHeaderContent);
+ void setFooterLeftContent(std::vector<DocumentElement *> * pFooterContent);
+protected:
+ void _writeHeaderFooter(const char *headerFooterTagName, const std::vector<DocumentElement *> & headerFooterContent,
+ DocumentHandlerInterface *pHandler) const;
+private:
+ WPXPropertyList mxPropList;
+ std::vector<DocumentElement *> * mpHeaderContent;
+ std::vector<DocumentElement *> * mpFooterContent;
+ std::vector<DocumentElement *> * mpHeaderLeftContent;
+ std::vector<DocumentElement *> * mpFooterLeftContent;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/SectionStyle.cxx b/writerperfect/source/filter/SectionStyle.cxx
new file mode 100644
index 000000000000..1b65fc7eae38
--- /dev/null
+++ b/writerperfect/source/filter/SectionStyle.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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(DocumentHandlerInterface *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:section-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:section-properties");
+
+ pHandler->endElement("style:style");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/SectionStyle.hxx b/writerperfect/source/filter/SectionStyle.hxx
new file mode 100644
index 000000000000..ee7a003fffae
--- /dev/null
+++ b/writerperfect/source/filter/SectionStyle.hxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+#include <libwpd/libwpd.h>
+#include <libwpd/WPXPropertyListVector.h>
+
+#include "Style.hxx"
+#include "WriterProperties.hxx"
+
+
+class SectionStyle : public Style
+{
+public:
+ SectionStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &xColumns, const char *psName);
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+
+private:
+ WPXPropertyList mPropList;
+ WPXPropertyListVector mColumns;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/Style.hxx b/writerperfect/source/filter/Style.hxx
new file mode 100644
index 000000000000..282041542017
--- /dev/null
+++ b/writerperfect/source/filter/Style.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+#include <libwpd/libwpd.h>
+#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(DocumentHandlerInterface * /* pHandler */) const {};
+ const WPXString &getName() const { return msName; }
+
+ private:
+ WPXString msName;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/TableStyle.cxx b/writerperfect/source/filter/TableStyle.cxx
new file mode 100644
index 000000000000..2fc66ed04841
--- /dev/null
+++ b/writerperfect/source/filter/TableStyle.cxx
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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 "FilterInternal.hxx"
+#include "TableStyle.hxx"
+#include "DocumentElement.hxx"
+
+#ifdef _MSC_VER
+#include <minmax.h>
+#endif
+
+#include <string.h>
+
+TableCellStyle::TableCellStyle(const WPXPropertyList &xPropList, const char *psName) :
+ Style(psName),
+ mPropList(xPropList)
+{
+}
+
+void TableCellStyle::write(DocumentHandlerInterface *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.0382in");
+ pHandler->startElement("style:table-cell-properties", stylePropList);
+ pHandler->endElement("style:table-cell-properties");
+
+ pHandler->endElement("style:style");
+}
+
+TableRowStyle::TableRowStyle(const WPXPropertyList &propList, const char *psName) :
+ Style(psName),
+ mPropList(propList)
+{
+}
+
+void TableRowStyle::write(DocumentHandlerInterface *pHandler) const
+{
+ TagOpenElement styleOpen("style:style");
+ styleOpen.addAttribute("style:name", getName());
+ styleOpen.addAttribute("style:family", "table-row");
+ styleOpen.write(pHandler);
+
+ TagOpenElement stylePropertiesOpen("style:table-row-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.addAttribute("fo:keep-together", "auto");
+ stylePropertiesOpen.write(pHandler);
+ pHandler->endElement("style:table-row-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(DocumentHandlerInterface *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:table-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:table-properties");
+
+ pHandler->endElement("style:style");
+
+ int i=1;
+ WPXPropertyListVector::Iter j(mColumns);
+ for (j.rewind(); j.next();)
+ {
+ TagOpenElement styleOpen2("style:style");
+ WPXString sColumnName;
+ sColumnName.sprintf("%s.Column%i", getName().cstr(), i);
+ styleOpen2.addAttribute("style:name", sColumnName);
+ styleOpen2.addAttribute("style:family", "table-column");
+ styleOpen2.write(pHandler);
+
+ pHandler->startElement("style:table-column-properties", j());
+ pHandler->endElement("style:table-column-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);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/TableStyle.hxx b/writerperfect/source/filter/TableStyle.hxx
new file mode 100644
index 000000000000..95c30892faf5
--- /dev/null
+++ b/writerperfect/source/filter/TableStyle.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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"
+#include "DocumentHandlerInterface.hxx"
+
+class DocumentElement;
+
+class TableCellStyle : public Style
+{
+public:
+ virtual ~TableCellStyle() {};
+ TableCellStyle(const WPXPropertyList &xPropList, const char *psName);
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+private:
+ WPXPropertyList mPropList;
+};
+
+class TableRowStyle : public Style
+{
+public:
+ virtual ~TableRowStyle() {};
+ TableRowStyle(const WPXPropertyList &propList, const char *psName);
+ virtual void write(DocumentHandlerInterface *pHandler) const;
+private:
+ WPXPropertyList mPropList;
+};
+
+class TableStyle : public Style, public TopLevelElementStyle
+{
+public:
+ TableStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &columns, const char *psName);
+ virtual ~TableStyle();
+ virtual void write(DocumentHandlerInterface *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
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/TextRunStyle.cxx b/writerperfect/source/filter/TextRunStyle.cxx
new file mode 100644
index 000000000000..9b3bc9825fd9
--- /dev/null
+++ b/writerperfect/source/filter/TextRunStyle.cxx
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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(DocumentHandlerInterface *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 i((*mpPropList));
+ for (i.rewind(); i.next(); )
+ {
+#if 0
+ if (strcmp(i.key(), "style:list-style-name") == 0)
+ propList.insert("style:list-style-name", i()->getStr());
+#endif
+ if (strcmp(i.key(), "fo:margin-left") == 0)
+ propList.insert("fo:margin-left", i()->getStr());
+ if (strcmp(i.key(), "fo:margin-right") == 0)
+ propList.insert("fo:margin-right", i()->getStr());
+ if (strcmp(i.key(), "fo:text-indent") == 0)
+ propList.insert("fo:text-indent", i()->getStr());
+ if (strcmp(i.key(), "fo:margin-top") == 0)
+ propList.insert("fo:margin-top", i()->getStr());
+ if (strcmp(i.key(), "fo:margin-bottom") == 0)
+ {
+ if (i()->getDouble() > 0.0f)
+ propList.insert("fo:margin-bottom", i()->getStr());
+ else
+ propList.insert("fo:margin-bottom", 0.0f);
+ }
+ if (strcmp(i.key(), "fo:line-height") == 0)
+ propList.insert("fo:line-height", i()->getStr());
+ if (strcmp(i.key(), "fo:break-before") == 0)
+ propList.insert("fo:break-before", i()->getStr());
+ if (strcmp(i.key(), "fo:text-align") == 0)
+ propList.insert("fo:text-align", i()->getStr());
+ if (strcmp(i.key(), "fo:text-align-last") == 0)
+ propList.insert("fo:text-align-last", i()->getStr());
+ }
+
+ propList.insert("style:justify-single-word", "false");
+ pHandler->startElement("style:paragraph-properties", propList);
+
+ if (mxTabStops.count() > 0)
+ {
+ TagOpenElement tabListOpen("style:tab-stops");
+ tabListOpen.write(pHandler);
+ WPXPropertyListVector::Iter i2(mxTabStops);
+ for (i2.rewind(); i2.next();)
+ {
+ if (i2()["style:position"] && i2()["style:position"]->getDouble() < 0)
+ continue;
+ TagOpenElement tabStopOpen("style:tab-stop");
+
+ WPXPropertyList::Iter j(i2());
+ 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:paragraph-properties");
+ pHandler->endElement("style:style");
+}
+
+SpanStyle::SpanStyle(const char *psName, const WPXPropertyList &xPropList) :
+ Style(psName),
+ mPropList(xPropList)
+{
+}
+
+void SpanStyle::write(DocumentHandlerInterface *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"])
+ {
+ if (mPropList["fo:font-size"]->getDouble() > 0.0f)
+ {
+ propList.insert("style:font-size-asian", mPropList["fo:font-size"]->getStr());
+ propList.insert("style:font-size-complex", mPropList["fo:font-size"]->getStr());
+ }
+ else
+ propList.remove("fo:font-size");
+ }
+
+ 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:text-properties", propList);
+
+ pHandler->endElement("style:text-properties");
+ pHandler->endElement("style:style");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/TextRunStyle.hxx b/writerperfect/source/filter/TextRunStyle.hxx
new file mode 100644
index 000000000000..492132cfc54d
--- /dev/null
+++ b/writerperfect/source/filter/TextRunStyle.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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
+#include <libwpd/libwpd.h>
+
+#include "Style.hxx"
+
+class TagOpenElement;
+class DocumentElement;
+
+class ParagraphStyle
+{
+public:
+ ParagraphStyle(WPXPropertyList *propList, const WPXPropertyListVector &tabStops, const WPXString &sName);
+ virtual ~ParagraphStyle();
+ virtual void write(DocumentHandlerInterface *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(DocumentHandlerInterface *pHandler) const;
+
+private:
+ WPXPropertyList mPropList;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/WriterProperties.hxx b/writerperfect/source/filter/WriterProperties.hxx
new file mode 100644
index 000000000000..757807ef3977
--- /dev/null
+++ b/writerperfect/source/filter/WriterProperties.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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"
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/filter/makefile.mk b/writerperfect/source/filter/makefile.mk
new file mode 100644
index 000000000000..f211101f706e
--- /dev/null
+++ b/writerperfect/source/filter/makefile.mk
@@ -0,0 +1,38 @@
+PRJ=..$/..
+
+PRJNAME=writerperfect
+TARGET=filter
+ENABLE_EXCEPTIONS=true
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_LIBWPD)" == "YES"
+INCPRE+=$(LIBWPD_CFLAGS)
+.ENDIF
+
+.IF "$(SYSTEM_LIBWPG)" == "YES"
+INCPRE+=$(LIBWPG_CFLAGS)
+.ENDIF
+
+.IF "$(SYSTEM_LIBWPS)" == "YES"
+INCPRE+=$(LIBWPS_CFLAGS)
+.ENDIF
+
+# broken but ... necessary, internal include shafted ...
+INCPRE+= -I..
+
+SLOFILES= \
+ $(SLO)$/DocumentCollector.obj \
+ $(SLO)$/DocumentElement.obj \
+ $(SLO)$/DocumentHandler.obj \
+ $(SLO)$/FontStyle.obj \
+ $(SLO)$/GraphicsStyle.obj \
+ $(SLO)$/InternalHandler.obj \
+ $(SLO)$/ListStyle.obj \
+ $(SLO)$/OdgExporter.obj \
+ $(SLO)$/PageSpan.obj \
+ $(SLO)$/SectionStyle.obj \
+ $(SLO)$/TableStyle.obj \
+ $(SLO)$/TextRunStyle.obj
+
+.INCLUDE : target.mk
diff --git a/writerperfect/source/stream/WPXSvStream.cxx b/writerperfect/source/stream/WPXSvStream.cxx
new file mode 100644
index 000000000000..fd7d98604a07
--- /dev/null
+++ b/writerperfect/source/stream/WPXSvStream.cxx
@@ -0,0 +1,172 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "WPXSvStream.h"
+#include "filter/FilterInternal.hxx"
+#include <tools/stream.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <limits>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+
+WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
+ WPXInputStream(),
+ mxChildStorage(),
+ mxChildStream(),
+ mxStream(xStream),
+ mxSeekable(xStream, UNO_QUERY),
+ maData(0)
+{
+ if (!xStream.is() || !mxStream.is())
+ mnLength = 0;
+ else
+ {
+ if (!mxSeekable.is())
+ mnLength = 0;
+ else
+ {
+ try
+ {
+ mnLength = mxSeekable->getLength();
+ }
+ catch ( ... )
+ {
+ WRITER_DEBUG_MSG(("mnLength = mxSeekable->getLength() threw exception\n"));
+ mnLength = 0;
+ }
+ }
+ }
+}
+
+WPXSvInputStream::~WPXSvInputStream()
+{
+}
+
+const unsigned char * WPXSvInputStream::read(unsigned long numBytes, unsigned long &numBytesRead)
+{
+ numBytesRead = 0;
+
+ if (numBytes == 0 || atEOS())
+ return 0;
+
+ numBytesRead = mxStream->readSomeBytes (maData, numBytes);
+ if (numBytesRead == 0)
+ return 0;
+
+ return (const unsigned char *)maData.getConstArray();
+}
+
+long WPXSvInputStream::tell()
+{
+ if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
+ return -1L;
+ else
+ {
+ sal_Int64 tmpPosition = mxSeekable->getPosition();
+ if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
+ return -1L;
+ return (long)tmpPosition;
+ }
+}
+
+int WPXSvInputStream::seek(long offset, WPX_SEEK_TYPE seekType)
+{
+ if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
+ return -1;
+
+ sal_Int64 tmpPosition = mxSeekable->getPosition();
+ if ((tmpPosition < 0) || (tmpPosition > (std::numeric_limits<long>::max)()))
+ return -1;
+
+ sal_Int64 tmpOffset = offset;
+ if (seekType == WPX_SEEK_CUR)
+ tmpOffset += tmpPosition;
+
+ int retVal = 0;
+ if (tmpOffset < 0)
+ {
+ tmpOffset = 0;
+ retVal = -1;
+ }
+ if (offset > mnLength)
+ {
+ tmpOffset = mnLength;
+ retVal = -1;
+ }
+
+ try
+ {
+ mxSeekable->seek(tmpOffset);
+ return retVal;
+ }
+ catch (...)
+ {
+ WRITER_DEBUG_MSG(("mxSeekable->seek(offset) threw exception\n"));
+ return -1;
+ }
+}
+
+bool WPXSvInputStream::atEOS()
+{
+ if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
+ return true;
+ return (mxSeekable->getPosition() >= mnLength);
+}
+
+bool WPXSvInputStream::isOLEStream()
+{
+ if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
+ return false;
+
+ sal_Int64 tmpPosition = mxSeekable->getPosition();
+ mxSeekable->seek(0);
+
+ SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
+ bool bAns = pStream && SotStorage::IsOLEStorage( pStream );
+ if (pStream)
+ delete pStream;
+
+ mxSeekable->seek(tmpPosition);
+
+ return bAns;
+}
+
+WPXInputStream * WPXSvInputStream::getDocumentOLEStream(const char * name)
+{
+ if ((mnLength == 0) || !mxStream.is() || !mxSeekable.is())
+ return 0;
+
+ sal_Int64 tmpPosition = mxSeekable->getPosition();
+ mxSeekable->seek(0);
+
+ SvStream *pStream = utl::UcbStreamHelper::CreateStream( mxStream );
+
+ if (!pStream || !SotStorage::IsOLEStorage( pStream ))
+ {
+ mxSeekable->seek(tmpPosition);
+ return 0;
+ }
+
+ mxChildStorage = new SotStorage( pStream, TRUE );
+
+ mxChildStream = mxChildStorage->OpenSotStream(
+ rtl::OUString::createFromAscii( name ),
+ STREAM_STD_READ );
+
+ mxSeekable->seek(tmpPosition);
+
+ if ( !mxChildStream.Is() || mxChildStream->GetError() )
+ {
+ mxSeekable->seek(tmpPosition);
+ return 0;
+ }
+
+ Reference < XInputStream > xContents(new utl::OSeekableInputStreamWrapper( mxChildStream ));
+ mxSeekable->seek(tmpPosition);
+ if (xContents.is())
+ return new WPXSvInputStream( xContents );
+ else
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/stream/WPXSvStream.h b/writerperfect/source/stream/WPXSvStream.h
new file mode 100644
index 000000000000..37d905adcc41
--- /dev/null
+++ b/writerperfect/source/stream/WPXSvStream.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#ifndef WPXSVSTREAM_H
+#define WPXSVSTREAM_H
+
+#include <sot/storage.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+
+#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_H_
+#include <com/sun/star/io/XSeekable.hpp>
+#endif
+
+
+#if defined _MSC_VER
+#pragma warning( push, 1 )
+#endif
+#include <libwpd-stream/WPXStream.h>
+#if defined _MSC_VER
+#pragma warning( pop )
+#endif
+
+class WPXSvInputStream : public WPXInputStream
+{
+public:
+ WPXSvInputStream( ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream > xStream );
+ virtual ~WPXSvInputStream();
+
+ virtual bool isOLEStream();
+ virtual WPXInputStream * getDocumentOLEStream(const char *name);
+
+ virtual const unsigned char *read(unsigned long numBytes, unsigned long &numBytesRead);
+ virtual int seek(long offset, WPX_SEEK_TYPE seekType);
+ virtual long tell();
+ virtual bool atEOS();
+
+private:
+ SotStorageRef mxChildStorage;
+ SotStorageStreamRef mxChildStream;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XInputStream > mxStream;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::io::XSeekable > mxSeekable;
+ ::com::sun::star::uno::Sequence< sal_Int8 > maData;
+ sal_Int64 mnLength;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/stream/makefile.mk b/writerperfect/source/stream/makefile.mk
new file mode 100644
index 000000000000..97262e7b7486
--- /dev/null
+++ b/writerperfect/source/stream/makefile.mk
@@ -0,0 +1,24 @@
+PRJ=..$/..
+
+PRJNAME=writerperfect
+TARGET=stream
+ENABLE_EXCEPTIONS=true
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_LIBWPD)" == "YES"
+INCPRE+=$(LIBWPD_CFLAGS)
+.ENDIF
+
+.IF "$(SYSTEM_LIBWPS)" == "YES"
+INCPRE+=$(LIBWPS_CFLAGS)
+.ELSE
+INCPRE+=$(SOLARVER)$/$(UPD)$/$(INPATH)$/inc$/libwps
+.ENDIF
+
+# broken but ... necessary, internal include shafted ...
+INCPRE+= -I..
+
+SLOFILES= $(SLO)$/WPXSvStream.obj
+
+.INCLUDE : target.mk
diff --git a/writerperfect/source/wpdimp/WordPerfectCollector.cxx b/writerperfect/source/wpdimp/WordPerfectCollector.cxx
new file mode 100644
index 000000000000..83fdec5ff9cd
--- /dev/null
+++ b/writerperfect/source/wpdimp/WordPerfectCollector.cxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* WordPerfectCollector: Collects sections and runs of text from a
+ * wordperfect file (and styles to go along with them) and writes them
+ * to a Writer target document
+ *
+ * Copyright (C) 2006 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 "WordPerfectCollector.hxx"
+#include <libwpd/WPDocument.h>
+#if defined _MSC_VER
+#pragma warning( pop )
+#endif
+
+WordPerfectCollector::WordPerfectCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler, const rtl::OString& password) :
+ DocumentCollector(pInput, pHandler),
+ maUtf8Password(password)
+{
+}
+
+WordPerfectCollector::~WordPerfectCollector()
+{
+}
+
+bool WordPerfectCollector::parseSourceDocument(WPXInputStream &input)
+{
+ WPDResult result;
+ if (maUtf8Password.getLength())
+ result = WPDocument::parse(&input, static_cast<WPXDocumentInterface *>(this), maUtf8Password.getStr());
+ else
+ result = WPDocument::parse(&input, static_cast<WPXDocumentInterface *>(this), NULL);
+ if (result != WPD_OK)
+ return false;
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpdimp/WordPerfectCollector.hxx b/writerperfect/source/wpdimp/WordPerfectCollector.hxx
new file mode 100644
index 000000000000..fce25691e951
--- /dev/null
+++ b/writerperfect/source/wpdimp/WordPerfectCollector.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* WordPerfectCollector: Collects sections and runs of text from a
+ * wordperfect file (and styles to go along with them) and writes them
+ * to a Writer target document
+ *
+ * Copyright (C) 2006 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 _WORDPERFECTCOLLECTOR_HXX
+#define _WORDPERFECTCOLLECTOR_HXX
+
+#include "filter/DocumentCollector.hxx"
+#include "filter/DocumentHandlerInterface.hxx"
+#include <rtl/ustring.hxx>
+
+class WordPerfectCollector : public DocumentCollector
+{
+public:
+ WordPerfectCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler, const rtl::OString& password);
+ virtual ~WordPerfectCollector();
+ bool parseSourceDocument(WPXInputStream &pInput);
+private:
+ rtl::OString maUtf8Password;
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpdimp/WordPerfectImportFilter.cxx b/writerperfect/source/wpdimp/WordPerfectImportFilter.cxx
new file mode 100644
index 000000000000..1bd7e16cd6fa
--- /dev/null
+++ b/writerperfect/source/wpdimp/WordPerfectImportFilter.cxx
@@ -0,0 +1,434 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2000 by Sun Microsystems, Inc.
+ * Copyright (C) 2002-2004 William Lachance (wlach@interlog.com)
+ * Copyright (C) 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ */
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include <osl/diagnose.h>
+#include <rtl/tencinfo.h>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+
+#include <xmloff/attrlist.hxx>
+#include <ucbhelper/content.hxx>
+#include <sfx2/passwd.hxx>
+
+#include "filter/FilterInternal.hxx"
+#include "filter/DocumentHandler.hxx"
+#include "filter/DocumentCollector.hxx"
+#include "stream/WPXSvStream.h"
+
+#if defined _MSC_VER
+#pragma warning( push, 1 )
+#endif
+#include <libwpd/WPDocument.h>
+#if defined _MSC_VER
+#pragma warning( pop )
+#endif
+
+#include "WordPerfectCollector.hxx"
+#include "WordPerfectImportFilter.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+using rtl::OString;
+using rtl::OUString;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Exception;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::lang::XMultiServiceFactory;
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::document::XFilter;
+using com::sun::star::document::XExtendedFilterDetection;
+using com::sun::star::ucb::XCommandEnvironment;
+
+using com::sun::star::io::XInputStream;
+using com::sun::star::document::XImporter;
+using com::sun::star::xml::sax::InputSource;
+using com::sun::star::xml::sax::XAttributeList;
+using com::sun::star::xml::sax::XDocumentHandler;
+using com::sun::star::xml::sax::XParser;
+
+void callHandler(uno::Reference < XDocumentHandler > xDocHandler);
+
+sal_Bool SAL_CALL WordPerfectImportFilter::importImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (RuntimeException)
+{
+ WRITER_DEBUG_MSG(("WordPerfectImportFilter::importImpl: Got here!\n"));
+
+ sal_Int32 nLength = aDescriptor.getLength();
+ const PropertyValue * pValue = aDescriptor.getConstArray();
+ OUString sURL;
+ uno::Reference < XInputStream > xInputStream;
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
+ pValue[i].Value >>= xInputStream;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "URL" ) ) )
+ pValue[i].Value >>= sURL;
+ }
+ if ( !xInputStream.is() )
+ {
+ OSL_ASSERT( 0 );
+ return sal_False;
+ }
+
+ WPXSvInputStream input( xInputStream );
+
+ OString aUtf8Passwd;
+
+#if 1
+ WPDConfidence confidence = WPDocument::isFileFormatSupported(&input);
+
+ if (WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence)
+ {
+ int unsuccessfulAttempts = 0;
+ while (true )
+ {
+ SfxPasswordDialog aPasswdDlg( 0 );
+ aPasswdDlg.SetMinLen(0);
+ if(!aPasswdDlg.Execute())
+ return sal_False;
+ String aPasswd = aPasswdDlg.GetPassword();
+ OUString aUniPasswd(aPasswd.GetBuffer() /*, aPasswd.Len(), RTL_TEXTENCODING_UCS2 */);
+ aUtf8Passwd = OUStringToOString(aUniPasswd, RTL_TEXTENCODING_UTF8);
+ if (WPD_PASSWORD_MATCH_OK == WPDocument::verifyPassword(&input, aUtf8Passwd.getStr()))
+ break;
+ else
+ unsuccessfulAttempts++;
+ if (unsuccessfulAttempts == 3) // timeout after 3 password atempts
+ return sal_False;
+ }
+ }
+#endif
+
+ // An XML import service: what we push sax messages to..
+ OUString sXMLImportService ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.XMLOasisImporter" ) );
+ uno::Reference < XDocumentHandler > xInternalHandler( mxMSF->createInstance( sXMLImportService ), UNO_QUERY );
+
+ // The XImporter sets up an empty target document for XDocumentHandler to write to..
+ uno::Reference < XImporter > xImporter(xInternalHandler, UNO_QUERY);
+ xImporter->setTargetDocument(mxDoc);
+
+ // OO Document Handler: abstract class to handle document SAX messages, concrete implementation here
+ // writes to in-memory target doc
+ DocumentHandler xHandler(xInternalHandler);
+
+ WordPerfectCollector collector(&input, &xHandler, aUtf8Passwd);
+ collector.filter();
+
+ return true;
+}
+
+sal_Bool SAL_CALL WordPerfectImportFilter::filter( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (RuntimeException)
+{
+ WRITER_DEBUG_MSG(("WordPerfectImportFilter::filter: Got here!\n"));
+ return importImpl ( aDescriptor );
+}
+void SAL_CALL WordPerfectImportFilter::cancel( )
+ throw (RuntimeException)
+{
+ WRITER_DEBUG_MSG(("WordPerfectImportFilter::cancel: Got here!\n"));
+}
+
+// XImporter
+void SAL_CALL WordPerfectImportFilter::setTargetDocument( const uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
+{
+ WRITER_DEBUG_MSG(("WordPerfectImportFilter::getTargetDocument: Got here!\n"));
+ meType = FILTER_IMPORT;
+ mxDoc = xDoc;
+}
+
+// XExtendedFilterDetection
+OUString SAL_CALL WordPerfectImportFilter::detect( com::sun::star::uno::Sequence< PropertyValue >& Descriptor )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ WRITER_DEBUG_MSG(("WordPerfectImportFilter::detect: Got here!\n"));
+
+ WPDConfidence confidence = WPD_CONFIDENCE_NONE;
+ OUString sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "" ) );
+ sal_Int32 nLength = Descriptor.getLength();
+ sal_Int32 location = nLength;
+ OUString sURL;
+ const PropertyValue * pValue = Descriptor.getConstArray();
+ uno::Reference < XInputStream > xInputStream;
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "TypeName" ) ) )
+ location=i;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
+ pValue[i].Value >>= xInputStream;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "URL" ) ) )
+ pValue[i].Value >>= sURL;
+ }
+
+ uno::Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
+ if (!xInputStream.is())
+ {
+ try
+ {
+ ::ucbhelper::Content aContent(sURL, xEnv);
+ xInputStream = aContent.openStream();
+ }
+ catch ( ... )
+ {
+ return ::rtl::OUString();
+ }
+
+ if (!xInputStream.is())
+ return ::rtl::OUString();
+ }
+
+ WPXSvInputStream input( xInputStream );
+
+ if (input.atEOS())
+ return ::rtl::OUString();
+
+ confidence = WPDocument::isFileFormatSupported(&input);
+
+ if (confidence == WPD_CONFIDENCE_EXCELLENT || confidence == WPD_CONFIDENCE_SUPPORTED_ENCRYPTION)
+ sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "writer_WordPerfect_Document" ) );
+
+ if (sTypeName.getLength())
+ {
+ if ( location == Descriptor.getLength() )
+ {
+ Descriptor.realloc(nLength+1);
+ Descriptor[location].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
+ }
+
+ Descriptor[location].Value <<=sTypeName;
+ }
+
+ return sTypeName;
+}
+
+
+// XInitialization
+void SAL_CALL WordPerfectImportFilter::initialize( const Sequence< Any >& aArguments )
+ throw (Exception, RuntimeException)
+{
+ WRITER_DEBUG_MSG(("WordPerfectImportFilter::initialize: Got here!\n"));
+ Sequence < PropertyValue > aAnySeq;
+ sal_Int32 nLength = aArguments.getLength();
+ if ( nLength && ( aArguments[0] >>= aAnySeq ) )
+ {
+ const PropertyValue * pValue = aAnySeq.getConstArray();
+ nLength = aAnySeq.getLength();
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Type" ) ) )
+ {
+ pValue[i].Value >>= msFilterName;
+ break;
+ }
+ }
+ }
+}
+OUString WordPerfectImportFilter_getImplementationName ()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.WordPerfectImportFilter" ) );
+}
+
+#define SERVICE_NAME1 "com.sun.star.document.ImportFilter"
+#define SERVICE_NAME2 "com.sun.star.document.ExtendedTypeDetection"
+sal_Bool SAL_CALL WordPerfectImportFilter_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+ return (ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) ||
+ ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME2 ) ) );
+}
+Sequence< OUString > SAL_CALL WordPerfectImportFilter_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ Sequence < OUString > aRet(2);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
+ pArray[1] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
+ return aRet;
+}
+#undef SERVICE_NAME2
+#undef SERVICE_NAME1
+
+uno::Reference< XInterface > SAL_CALL WordPerfectImportFilter_createInstance( const uno::Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+ return (cppu::OWeakObject*) new WordPerfectImportFilter( rSMgr );
+}
+
+// XServiceInfo
+OUString SAL_CALL WordPerfectImportFilter::getImplementationName( )
+ throw (RuntimeException)
+{
+ return WordPerfectImportFilter_getImplementationName();
+}
+sal_Bool SAL_CALL WordPerfectImportFilter::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return WordPerfectImportFilter_supportsService( rServiceName );
+}
+Sequence< OUString > SAL_CALL WordPerfectImportFilter::getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ return WordPerfectImportFilter_getSupportedServiceNames();
+}
+
+
+WordPerfectImportFilterDialog::WordPerfectImportFilterDialog(const ::com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory > &r ) :
+ mxMSF( r ) {}
+
+WordPerfectImportFilterDialog::~WordPerfectImportFilterDialog()
+{
+}
+
+void SAL_CALL WordPerfectImportFilterDialog::setTitle( const ::rtl::OUString& )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+sal_Int16 SAL_CALL WordPerfectImportFilterDialog::execute()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ WPXSvInputStream input( mxInputStream );
+
+ OString aUtf8Passwd;
+
+ WPDConfidence confidence = WPDocument::isFileFormatSupported(&input);
+
+ if (WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence)
+ {
+ int unsuccessfulAttempts = 0;
+ while (true )
+ {
+ SfxPasswordDialog aPasswdDlg(0);
+ aPasswdDlg.SetMinLen(0);
+ if(!aPasswdDlg.Execute())
+ return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL;
+ msPassword = ::rtl::OUString(aPasswdDlg.GetPassword().GetBuffer());
+ aUtf8Passwd = OUStringToOString(msPassword, RTL_TEXTENCODING_UTF8);
+ if (WPD_PASSWORD_MATCH_OK == WPDocument::verifyPassword(&input, aUtf8Passwd.getStr()))
+ break;
+ else
+ unsuccessfulAttempts++;
+ if (unsuccessfulAttempts == 3) // timeout after 3 password atempts
+ return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL;
+ }
+ }
+ return com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL WordPerfectImportFilterDialog::getPropertyValues() throw(uno::RuntimeException)
+{
+ uno::Sequence<beans::PropertyValue> aRet(1);
+ beans::PropertyValue* pArray = aRet.getArray();
+
+ pArray[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Password") );
+ pArray[0].Value <<= msPassword;
+
+ return aRet;
+}
+
+void SAL_CALL WordPerfectImportFilterDialog::setPropertyValues( const uno::Sequence<beans::PropertyValue>& aProps)
+ throw(beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
+{
+ const beans::PropertyValue* pPropArray = aProps.getConstArray();
+ long nPropCount = aProps.getLength();
+ for (long i = 0; i < nPropCount; i++)
+ {
+ const beans::PropertyValue& rProp = pPropArray[i];
+ ::rtl::OUString aPropName = rProp.Name;
+
+ if ( aPropName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Password")) )
+ rProp.Value >>= msPassword;
+ else if ( aPropName.equalsAscii( "InputStream" ) )
+ rProp.Value >>= mxInputStream;
+ }
+}
+
+
+// XServiceInfo
+OUString SAL_CALL WordPerfectImportFilterDialog::getImplementationName( )
+ throw (RuntimeException)
+{
+ return WordPerfectImportFilterDialog_getImplementationName();
+}
+
+sal_Bool SAL_CALL WordPerfectImportFilterDialog::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return WordPerfectImportFilterDialog_supportsService( rServiceName );
+}
+
+Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog::getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ return WordPerfectImportFilterDialog_getSupportedServiceNames();
+}
+
+OUString WordPerfectImportFilterDialog_getImplementationName ()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.WordPerfectImportFilterDialog" ) );
+}
+
+#define SERVICE_NAME "com.sun.star.ui.dialogs.FilterOptionsDialog"
+sal_Bool SAL_CALL WordPerfectImportFilterDialog_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+ return ( ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) ) );
+}
+
+Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ Sequence < OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
+ return aRet;
+}
+#undef SERVICE_NAME
+
+uno::Reference< XInterface > SAL_CALL WordPerfectImportFilterDialog_createInstance( const uno::Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+ return (cppu::OWeakObject*) new WordPerfectImportFilterDialog( rSMgr );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpdimp/WordPerfectImportFilter.hxx b/writerperfect/source/wpdimp/WordPerfectImportFilter.hxx
new file mode 100644
index 000000000000..50b995ff70bf
--- /dev/null
+++ b/writerperfect/source/wpdimp/WordPerfectImportFilter.hxx
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2000 by Sun Microsystems, Inc.
+ * Copyright (C) 2002-2004 William Lachance (wlach@interlog.com)
+ * Copyright (C) 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#ifndef _WORDPERFECTIMPORTFILTER_HXX
+#define _WORDPERFECTIMPORTFILTER_HXX
+
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implbase5.hxx>
+
+enum FilterType
+{
+ FILTER_IMPORT,
+ FILTER_EXPORT
+};
+/* This component will be instantiated for both import or export. Whether it calls
+ * setSourceDocument or setTargetDocument determines which Impl function the filter
+ * member calls */
+class WordPerfectImportFilter : public cppu::WeakImplHelper5
+<
+ com::sun::star::document::XFilter,
+ com::sun::star::document::XImporter,
+ com::sun::star::document::XExtendedFilterDetection,
+ com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XServiceInfo
+>
+{
+protected:
+ // oo.org declares
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mxDoc;
+ ::rtl::OUString msFilterName;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > mxHandler;
+
+ FilterType meType;
+
+ sal_Bool SAL_CALL importImpl( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ WordPerfectImportFilter( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > &rxMSF)
+ : mxMSF( rxMSF ) {}
+ virtual ~WordPerfectImportFilter() {}
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancel( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XImporter
+ virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ //XExtendedFilterDetection
+ virtual ::rtl::OUString SAL_CALL detect( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& Descriptor )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+};
+
+::rtl::OUString WordPerfectImportFilter_getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+sal_Bool SAL_CALL WordPerfectImportFilter_supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL WordPerfectImportFilter_getSupportedServiceNames( )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+SAL_CALL WordPerfectImportFilter_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr)
+ throw ( ::com::sun::star::uno::Exception );
+
+
+class WordPerfectImportFilterDialog : public cppu::WeakImplHelper3 <
+ com::sun::star::ui::dialogs::XExecutableDialog,
+ com::sun::star::lang::XServiceInfo,
+ com::sun::star::beans::XPropertyAccess
+>
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF;
+ ::rtl::OUString msPassword;
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > mxInputStream;
+
+ ~WordPerfectImportFilterDialog();
+
+ // XExecutableDialog
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Int16 SAL_CALL execute()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XPropertyAccess
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
+ SAL_CALL getPropertyValues() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::beans::PropertyValue >& aProps )
+ throw (::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::beans::PropertyVetoException,
+ ::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+public:
+ WordPerfectImportFilterDialog(const ::com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory > &r );
+
+};
+
+::rtl::OUString WordPerfectImportFilterDialog_getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+sal_Bool SAL_CALL WordPerfectImportFilterDialog_supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL WordPerfectImportFilterDialog_getSupportedServiceNames( )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+SAL_CALL WordPerfectImportFilterDialog_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr)
+ throw ( ::com::sun::star::uno::Exception );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpdimp/makefile.mk b/writerperfect/source/wpdimp/makefile.mk
new file mode 100644
index 000000000000..e2dd8d746546
--- /dev/null
+++ b/writerperfect/source/wpdimp/makefile.mk
@@ -0,0 +1,29 @@
+PRJ=..$/..
+
+PRJNAME=writerperfect
+TARGET=wpdimp
+ENABLE_EXCEPTIONS=true
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_LIBWPD)" == "YES"
+INCPRE+=$(LIBWPD_CFLAGS)
+.ENDIF
+
+.IF "$(SYSTEM_LIBWPG)" == "YES"
+INCPRE+=$(LIBWPG_CFLAGS)
+.ENDIF
+
+.IF "$(SYSTEM_LIBWPS)" == "YES"
+INCPRE+=$(LIBWPS_CFLAGS)
+.ENDIF
+
+# broken but ... necessary, internal include shafted ...
+INCPRE+= -I..
+
+SLOFILES= \
+ $(SLO)$/WordPerfectCollector.obj \
+ $(SLO)$/WordPerfectImportFilter.obj \
+ $(SLO)$/wpft_genericfilter.obj
+
+.INCLUDE : target.mk
diff --git a/writerperfect/source/wpdimp/wpft_genericfilter.cxx b/writerperfect/source/wpdimp/wpft_genericfilter.cxx
new file mode 100644
index 000000000000..eb3cb035a001
--- /dev/null
+++ b/writerperfect/source/wpdimp/wpft_genericfilter.cxx
@@ -0,0 +1,124 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* genericfilter: mostly generic code for registering the filter
+ *
+ * Portions of this code Copyright 2000 by Sun Microsystems, Inc.
+ * Rest is Copyright (C) 2002 William Lachance (wlach@interlog.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#include <stdio.h>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <cppuhelper/factory.hxx>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include "WordPerfectImportFilter.hxx"
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+
+extern "C"
+{
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+sal_Bool SAL_CALL component_writeInfo(
+ void * /* pServiceManager */, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ sal_Int32 nPos = 0;
+ Reference< XRegistryKey > xNewKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( WordPerfectImportFilter_getImplementationName() ) );
+ xNewKey = xNewKey->createKey( OUString(RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES")) );
+
+ const Sequence< OUString > & rSNL = WordPerfectImportFilter_getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( nPos = rSNL.getLength(); nPos--; )
+ xNewKey->createKey( pArray[nPos] );
+#if 0
+ xNewKey = reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( WordPerfectImportFilterDialog_getImplementationName() );
+ xNewKey = xNewKey->createKey( OUString(RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES")) );
+
+ const Sequence< OUString > & rSNL2 = WordPerfectImportFilterDialog_getSupportedServiceNames();
+ pArray = rSNL2.getConstArray();
+ for ( nPos = rSNL2.getLength(); nPos--; )
+ xNewKey->createKey( pArray[nPos] );
+#endif
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /* pRegistryKey */ )
+{
+ void * pRet = 0;
+
+ OUString implName = OUString::createFromAscii( pImplName );
+ if ( pServiceManager && implName.equals(WordPerfectImportFilter_getImplementationName()) )
+ {
+ Reference< XSingleServiceFactory > xFactory( createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString::createFromAscii( pImplName ),
+ WordPerfectImportFilter_createInstance, WordPerfectImportFilter_getSupportedServiceNames() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+#if 0
+ else if ( pServiceManager && implName.equals(WordPerfectImportFilterDialog_getImplementationName()) )
+ {
+ Reference< XSingleServiceFactory > xFactory( createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString::createFromAscii( pImplName ),
+ WordPerfectImportFilterDialog_createInstance, WordPerfectImportFilterDialog_getSupportedServiceNames() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+#endif
+
+ return pRet;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpgimp/WPGImportFilter.cxx b/writerperfect/source/wpgimp/WPGImportFilter.cxx
new file mode 100644
index 000000000000..8a1f92d97041
--- /dev/null
+++ b/writerperfect/source/wpgimp/WPGImportFilter.cxx
@@ -0,0 +1,285 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* WPGImportFilter: Sets up the filter, and calls OdgExporter
+ * to do the actual filtering
+ *
+ * Copyright (C) 2000 by Sun Microsystems, Inc.
+ * Copyright (C) 2002-2004 William Lachance (wlach@interlog.com)
+ * Copyright (C) 2004 Net Integration Technologies (http://www.net-itech.com)
+ * Copyright (C) 2004-2006 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include <osl/diagnose.h>
+#include <rtl/tencinfo.h>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/uno/Reference.h>
+
+#include <xmloff/attrlist.hxx>
+
+#include "filter/DocumentHandler.hxx"
+#include "filter/OdgExporter.hxx"
+#include "WPGImportFilter.hxx"
+#include "stream/WPXSvStream.h"
+
+#include <iostream>
+
+using namespace ::com::sun::star::uno;
+using com::sun::star::uno::Reference;
+using com::sun::star::io::XInputStream;
+using com::sun::star::io::XSeekable;
+using com::sun::star::uno::Sequence;
+using namespace ::rtl;
+using rtl::OString;
+using rtl::OUString;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Exception;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::lang::XMultiServiceFactory;
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::document::XFilter;
+using com::sun::star::document::XExtendedFilterDetection;
+
+using com::sun::star::io::XInputStream;
+using com::sun::star::document::XImporter;
+using com::sun::star::xml::sax::InputSource;
+using com::sun::star::xml::sax::XAttributeList;
+using com::sun::star::xml::sax::XDocumentHandler;
+using com::sun::star::xml::sax::XParser;
+
+
+sal_Bool SAL_CALL WPGImportFilter::filter( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::filter" << std::endl;
+#endif
+ sal_Int32 nLength = aDescriptor.getLength();
+ const PropertyValue * pValue = aDescriptor.getConstArray();
+ OUString sURL;
+ Reference < XInputStream > xInputStream;
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
+ pValue[i].Value >>= xInputStream;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "URL" ) ) )
+ pValue[i].Value >>= sURL;
+ }
+ if ( !xInputStream.is() )
+ {
+ OSL_ASSERT( 0 );
+ return sal_False;
+ }
+ OString sFileName;
+ sFileName = OUStringToOString(sURL, RTL_TEXTENCODING_INFO_ASCII);
+
+ // An XML import service: what we push sax messages to..
+ OUString sXMLImportService ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Draw.XMLOasisImporter" ) );
+ Reference < XDocumentHandler > xInternalHandler( mxMSF->createInstance( sXMLImportService ), UNO_QUERY );
+
+ // The XImporter sets up an empty target document for XDocumentHandler to write to..
+ Reference < XImporter > xImporter(xInternalHandler, UNO_QUERY);
+ xImporter->setTargetDocument( mxDoc );
+
+ // OO Graphics Handler: abstract class to handle document SAX messages, concrete implementation here
+ // writes to in-memory target doc
+ DocumentHandler xHandler(xInternalHandler);
+
+ WPXInputStream* input = new WPXSvInputStream( xInputStream );
+
+ OdgExporter exporter(&xHandler);
+ bool tmpParseResult = libwpg::WPGraphics::parse(input, &exporter);
+ if (input)
+ delete input;
+ xInputStream->closeInput();
+ return tmpParseResult;
+}
+
+void SAL_CALL WPGImportFilter::cancel( )
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::cancel" << std::endl;
+#endif
+}
+
+// XImporter
+void SAL_CALL WPGImportFilter::setTargetDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::setTargetDocument" << std::endl;
+#endif
+ meType = FILTER_IMPORT;
+ mxDoc = xDoc;
+}
+
+// XExtendedFilterDetection
+OUString SAL_CALL WPGImportFilter::detect( com::sun::star::uno::Sequence< PropertyValue >& Descriptor )
+ throw( com::sun::star::uno::RuntimeException )
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::detect" << std::endl;
+#endif
+ OUString sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "" ) );
+ sal_Int32 nLength = Descriptor.getLength();
+ sal_Int32 location = nLength;
+ const PropertyValue * pValue = Descriptor.getConstArray();
+ Reference < XInputStream > xInputStream;
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "TypeName" ) ) )
+ location=i;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
+ pValue[i].Value >>= xInputStream;
+ }
+
+ WPXInputStream* input = new WPXSvInputStream( xInputStream );
+
+ if (libwpg::WPGraphics::isSupported(input))
+ sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "draw_WordPerfect_Graphics" ) );
+
+ if (input)
+ delete input;
+
+ if (!sTypeName.equalsAscii(""))
+ {
+ if ( location == Descriptor.getLength() )
+ {
+ Descriptor.realloc(nLength+1);
+ Descriptor[location].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
+ }
+
+ Descriptor[location].Value <<=sTypeName;
+ }
+ return sTypeName;
+}
+
+
+// XInitialization
+void SAL_CALL WPGImportFilter::initialize( const Sequence< Any >& aArguments )
+ throw (Exception, RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::initialize" << std::endl;
+#endif
+ Sequence < PropertyValue > aAnySeq;
+ sal_Int32 nLength = aArguments.getLength();
+ if ( nLength && ( aArguments[0] >>= aAnySeq ) )
+ {
+ const PropertyValue * pValue = aAnySeq.getConstArray();
+ nLength = aAnySeq.getLength();
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Type" ) ) )
+ {
+ pValue[i].Value >>= msFilterName;
+ break;
+ }
+ }
+ }
+}
+OUString WPGImportFilter_getImplementationName ()
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter_getImplementationName" << std::endl;
+#endif
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Draw.WPGImportFilter" ) );
+}
+
+#define SERVICE_NAME1 "com.sun.star.document.ImportFilter"
+#define SERVICE_NAME2 "com.sun.star.document.ExtendedTypeDetection"
+sal_Bool SAL_CALL WPGImportFilter_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter_supportsService" << std::endl;
+#endif
+ return (ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) ||
+ ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME2 ) ) );
+}
+Sequence< OUString > SAL_CALL WPGImportFilter_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter_getSupportedServiceNames" << std::endl;
+#endif
+ Sequence < OUString > aRet(2);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
+ pArray[1] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
+ return aRet;
+}
+#undef SERVICE_NAME2
+#undef SERVICE_NAME1
+
+Reference< XInterface > SAL_CALL WPGImportFilter_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter_createInstance" << std::endl;
+#endif
+ return (cppu::OWeakObject*) new WPGImportFilter( rSMgr );
+}
+
+// XServiceInfo
+OUString SAL_CALL WPGImportFilter::getImplementationName( )
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::getImplementationName" << std::endl;
+#endif
+ return WPGImportFilter_getImplementationName();
+}
+sal_Bool SAL_CALL WPGImportFilter::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::supportsService" << std::endl;
+#endif
+ return WPGImportFilter_supportsService( rServiceName );
+}
+Sequence< OUString > SAL_CALL WPGImportFilter::getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+#ifdef DEBUG
+ std::cerr << "WPGImportFilter::getSupportedServiceNames" << std::endl;
+#endif
+ return WPGImportFilter_getSupportedServiceNames();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpgimp/WPGImportFilter.hxx b/writerperfect/source/wpgimp/WPGImportFilter.hxx
new file mode 100644
index 000000000000..bab1fd474f3e
--- /dev/null
+++ b/writerperfect/source/wpgimp/WPGImportFilter.hxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2000 by Sun Microsystems, Inc.
+ * Copyright (C) 2002-2004 William Lachance (wlach@interlog.com)
+ * Copyright (C) 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#ifndef _WPGIMPORTFILTER_HXX
+#define _WPGIMPORTFILTER_HXX
+
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <cppuhelper/implbase5.hxx>
+
+#include <stdio.h>
+
+enum FilterType
+{
+ FILTER_IMPORT,
+ FILTER_EXPORT
+};
+/* This component will be instantiated for both import or export. Whether it calls
+ * setSourceDocument or setTargetDocument determines which Impl function the filter
+ * member calls */
+class WPGImportFilter : public cppu::WeakImplHelper5
+<
+ com::sun::star::document::XFilter,
+ com::sun::star::document::XImporter,
+ com::sun::star::document::XExtendedFilterDetection,
+ com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XServiceInfo
+>
+{
+protected:
+ // oo.org declares
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mxDoc;
+ ::rtl::OUString msFilterName;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > mxHandler;
+
+ FilterType meType;
+
+public:
+ WPGImportFilter( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > &rxMSF)
+ : mxMSF( rxMSF ) {}
+ virtual ~WPGImportFilter() {}
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancel( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XImporter
+ virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ //XExtendedFilterDetection
+ virtual ::rtl::OUString SAL_CALL detect( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& Descriptor )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+};
+
+::rtl::OUString WPGImportFilter_getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+sal_Bool SAL_CALL WPGImportFilter_supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL WPGImportFilter_getSupportedServiceNames( )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+SAL_CALL WPGImportFilter_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr)
+ throw ( ::com::sun::star::uno::Exception );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpgimp/makefile.mk b/writerperfect/source/wpgimp/makefile.mk
new file mode 100644
index 000000000000..ccf1d7df9e34
--- /dev/null
+++ b/writerperfect/source/wpgimp/makefile.mk
@@ -0,0 +1,24 @@
+PRJ=..$/..
+
+PRJNAME=writerperfect
+TARGET=wpgimp
+ENABLE_EXCEPTIONS=true
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_LIBWPD)" == "YES"
+INCPRE+=$(LIBWPD_CFLAGS)
+.ENDIF
+
+.IF "$(SYSTEM_LIBWPG)" == "YES"
+INCPRE+=$(LIBWPG_CFLAGS)
+.ENDIF
+
+# broken but ... necessary, internal include shafted ...
+INCPRE+= -I..
+
+SLOFILES= \
+ $(SLO)$/WPGImportFilter.obj \
+ $(SLO)$/wpgimport_genericfilter.obj
+
+.INCLUDE : target.mk
diff --git a/writerperfect/source/wpgimp/wpgimport_genericfilter.cxx b/writerperfect/source/wpgimp/wpgimport_genericfilter.cxx
new file mode 100644
index 000000000000..d1686773ffe9
--- /dev/null
+++ b/writerperfect/source/wpgimp/wpgimport_genericfilter.cxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* genericfilter: mostly generic code for registering the filter
+ *
+ * Portions of this code Copyright 2000 by Sun Microsystems, Inc.
+ * Rest is Copyright (C) 2002 William Lachance (wlach@interlog.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#include <stdio.h>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <cppuhelper/factory.hxx>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include "WPGImportFilter.hxx"
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+
+extern "C"
+{
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+sal_Bool SAL_CALL component_writeInfo(
+ void * /* pServiceManager */, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ sal_Int32 nPos = 0;
+ Reference< XRegistryKey > xNewKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( WPGImportFilter_getImplementationName() ) );
+ xNewKey = xNewKey->createKey( OUString(RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES")) );
+
+ const Sequence< OUString > & rSNL = WPGImportFilter_getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( nPos = rSNL.getLength(); nPos--; )
+ xNewKey->createKey( pArray[nPos] );
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /* pRegistryKey */ )
+{
+ void * pRet = 0;
+
+ OUString implName = OUString::createFromAscii( pImplName );
+ if ( pServiceManager && implName.equals(WPGImportFilter_getImplementationName()) )
+ {
+ Reference< XSingleServiceFactory > xFactory( createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString::createFromAscii( pImplName ),
+ WPGImportFilter_createInstance, WPGImportFilter_getSupportedServiceNames() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpsimp/MSWorksCollector.cxx b/writerperfect/source/wpsimp/MSWorksCollector.cxx
new file mode 100644
index 000000000000..bed21d8bed73
--- /dev/null
+++ b/writerperfect/source/wpsimp/MSWorksCollector.cxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* MSWorksCollector: Collects sections and runs of text from a
+ * wordperfect file (and styles to go along with them) and writes them
+ * to a Writer target document
+ *
+ * Copyright (C) 2006 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 "MSWorksCollector.hxx"
+#include <libwps/WPSDocument.h>
+
+MSWorksCollector::MSWorksCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler) :
+ DocumentCollector(pInput, pHandler)
+{
+}
+
+MSWorksCollector::~MSWorksCollector()
+{
+}
+
+bool MSWorksCollector::parseSourceDocument(WPXInputStream &input)
+{
+ WPSResult result = WPSDocument::parse(&input, static_cast<WPXDocumentInterface *>(this));
+ if (result != WPS_OK)
+ return false;
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpsimp/MSWorksCollector.hxx b/writerperfect/source/wpsimp/MSWorksCollector.hxx
new file mode 100644
index 000000000000..9db02532a5f1
--- /dev/null
+++ b/writerperfect/source/wpsimp/MSWorksCollector.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* MSWorksCollector: Collects sections and runs of text from a
+ * wordperfect file (and styles to go along with them) and writes them
+ * to a Writer target document
+ *
+ * Copyright (C) 2006 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 _MSWORKSCOLLECTOR_HXX
+#define _MSWORKSCOLLECTOR_HXX
+
+#include "filter/DocumentCollector.hxx"
+#include "filter/DocumentHandlerInterface.hxx"
+
+class MSWorksCollector : public DocumentCollector
+{
+public:
+ MSWorksCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler);
+ virtual ~MSWorksCollector();
+ bool parseSourceDocument(WPXInputStream &input);
+};
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpsimp/MSWorksImportFilter.cxx b/writerperfect/source/wpsimp/MSWorksImportFilter.cxx
new file mode 100644
index 000000000000..211d3ae33fd3
--- /dev/null
+++ b/writerperfect/source/wpsimp/MSWorksImportFilter.cxx
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* MSWorksImportFilter: Sets up the filter, and calls DocumentCollector
+ * to do the actual filtering
+ *
+ * Copyright (C) 2000 by Sun Microsystems, Inc.
+ * Copyright (C) 2002-2004 William Lachance (wlach@interlog.com)
+ * Copyright (C) 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ */
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+
+#include <osl/diagnose.h>
+#include <rtl/tencinfo.h>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+
+#include <xmloff/attrlist.hxx>
+#include <ucbhelper/content.hxx>
+
+#include "filter/FilterInternal.hxx"
+#include "filter/DocumentHandler.hxx"
+#include "filter/DocumentCollector.hxx"
+#include "stream/WPXSvStream.h"
+
+#include <libwps/WPSDocument.h>
+#include "MSWorksImportFilter.hxx"
+#include "MSWorksCollector.hxx"
+
+// using namespace ::rtl;
+using rtl::OString;
+using rtl::OUString;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Exception;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::lang::XMultiServiceFactory;
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::document::XFilter;
+using com::sun::star::document::XExtendedFilterDetection;
+using com::sun::star::ucb::XCommandEnvironment;
+
+using com::sun::star::io::XInputStream;
+using com::sun::star::document::XImporter;
+using com::sun::star::xml::sax::InputSource;
+using com::sun::star::xml::sax::XAttributeList;
+using com::sun::star::xml::sax::XDocumentHandler;
+using com::sun::star::xml::sax::XParser;
+
+void callHandler(Reference < XDocumentHandler > xDocHandler);
+
+sal_Bool SAL_CALL MSWorksImportFilter::importImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (RuntimeException)
+{
+ WRITER_DEBUG_MSG(("MSWorksImportFilter::importImpl: Got here!\n"));
+
+ sal_Int32 nLength = aDescriptor.getLength();
+ const PropertyValue * pValue = aDescriptor.getConstArray();
+ OUString sURL;
+ Reference < XInputStream > xInputStream;
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
+ pValue[i].Value >>= xInputStream;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "URL" ) ) )
+ pValue[i].Value >>= sURL;
+ }
+ if ( !xInputStream.is() )
+ {
+ OSL_ASSERT( 0 );
+ return sal_False;
+ }
+ OString sFileName;
+ sFileName = OUStringToOString(sURL, RTL_TEXTENCODING_INFO_ASCII);
+
+ // An XML import service: what we push sax messages to..
+ OUString sXMLImportService ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.XMLOasisImporter" ) );
+ Reference < XDocumentHandler > xInternalHandler( mxMSF->createInstance( sXMLImportService ), UNO_QUERY );
+
+ // The XImporter sets up an empty target document for XDocumentHandler to write to..
+ Reference < XImporter > xImporter(xInternalHandler, UNO_QUERY);
+ xImporter->setTargetDocument(mxDoc);
+
+ // OO Document Handler: abstract class to handle document SAX messages, concrete implementation here
+ // writes to in-memory target doc
+ DocumentHandler xHandler(xInternalHandler);
+
+ WPXSvInputStream input( xInputStream );
+
+ MSWorksCollector collector(&input, &xHandler);
+ collector.filter();
+
+ return true;
+}
+
+sal_Bool SAL_CALL MSWorksImportFilter::filter( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (RuntimeException)
+{
+ WRITER_DEBUG_MSG(("MSWorksImportFilter::filter: Got here!\n"));
+ return importImpl ( aDescriptor );
+}
+void SAL_CALL MSWorksImportFilter::cancel( )
+ throw (RuntimeException)
+{
+ WRITER_DEBUG_MSG(("MSWorksImportFilter::cancel: Got here!\n"));
+}
+
+// XImporter
+void SAL_CALL MSWorksImportFilter::setTargetDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
+{
+ WRITER_DEBUG_MSG(("MSWorksImportFilter::getTargetDocument: Got here!\n"));
+ meType = FILTER_IMPORT;
+ mxDoc = xDoc;
+}
+
+// XExtendedFilterDetection
+OUString SAL_CALL MSWorksImportFilter::detect( com::sun::star::uno::Sequence< PropertyValue >& Descriptor )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ WRITER_DEBUG_MSG(("MSWorksImportFilter::detect: Got here!\n"));
+
+ WPSConfidence confidence = WPS_CONFIDENCE_NONE;
+ OUString sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "" ) );
+ sal_Int32 nLength = Descriptor.getLength();
+ sal_Int32 location = nLength;
+ OUString sURL;
+ const PropertyValue * pValue = Descriptor.getConstArray();
+ Reference < XInputStream > xInputStream;
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "TypeName" ) ) )
+ location=i;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
+ pValue[i].Value >>= xInputStream;
+ else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "URL" ) ) )
+ pValue[i].Value >>= sURL;
+ }
+
+ Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
+ if (!xInputStream.is())
+ {
+ try
+ {
+ ::ucbhelper::Content aContent(sURL, xEnv);
+ xInputStream = aContent.openStream();
+ }
+ catch ( ... )
+ {
+ return ::rtl::OUString();
+ }
+
+ if (!xInputStream.is())
+ return ::rtl::OUString();
+ }
+
+ WPXSvInputStream input( xInputStream );
+
+ if (input.atEOS())
+ return ::rtl::OUString();
+
+ confidence = WPSDocument::isFileFormatSupported(&input);
+
+ if ((confidence == WPS_CONFIDENCE_EXCELLENT) || (confidence == WPS_CONFIDENCE_GOOD))
+ sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "writer_MS_Works_Document" ) );
+
+ if (sTypeName.getLength())
+ {
+ if ( location == Descriptor.getLength() )
+ {
+ Descriptor.realloc(nLength+1);
+ Descriptor[location].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
+ }
+
+ Descriptor[location].Value <<=sTypeName;
+ }
+
+ return sTypeName;
+}
+
+
+// XInitialization
+void SAL_CALL MSWorksImportFilter::initialize( const Sequence< Any >& aArguments )
+ throw (Exception, RuntimeException)
+{
+ WRITER_DEBUG_MSG(("MSWorksImportFilter::initialize: Got here!\n"));
+ Sequence < PropertyValue > aAnySeq;
+ sal_Int32 nLength = aArguments.getLength();
+ if ( nLength && ( aArguments[0] >>= aAnySeq ) )
+ {
+ const PropertyValue * pValue = aAnySeq.getConstArray();
+ nLength = aAnySeq.getLength();
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Type" ) ) )
+ {
+ pValue[i].Value >>= msFilterName;
+ break;
+ }
+ }
+ }
+}
+OUString MSWorksImportFilter_getImplementationName ()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.MSWorksImportFilter" ) );
+}
+
+#define SERVICE_NAME1 "com.sun.star.document.ImportFilter"
+#define SERVICE_NAME2 "com.sun.star.document.ExtendedTypeDetection"
+sal_Bool SAL_CALL MSWorksImportFilter_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+ return (ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) ||
+ ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME2 ) ) );
+}
+Sequence< OUString > SAL_CALL MSWorksImportFilter_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ Sequence < OUString > aRet(2);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
+ pArray[1] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
+ return aRet;
+}
+#undef SERVICE_NAME2
+#undef SERVICE_NAME1
+
+Reference< XInterface > SAL_CALL MSWorksImportFilter_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+ return (cppu::OWeakObject*) new MSWorksImportFilter( rSMgr );
+}
+
+// XServiceInfo
+OUString SAL_CALL MSWorksImportFilter::getImplementationName( )
+ throw (RuntimeException)
+{
+ return MSWorksImportFilter_getImplementationName();
+}
+sal_Bool SAL_CALL MSWorksImportFilter::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return MSWorksImportFilter_supportsService( rServiceName );
+}
+Sequence< OUString > SAL_CALL MSWorksImportFilter::getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ return MSWorksImportFilter_getSupportedServiceNames();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpsimp/MSWorksImportFilter.hxx b/writerperfect/source/wpsimp/MSWorksImportFilter.hxx
new file mode 100644
index 000000000000..71e621298f35
--- /dev/null
+++ b/writerperfect/source/wpsimp/MSWorksImportFilter.hxx
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2000 by Sun Microsystems, Inc.
+ * Copyright (C) 2002-2004 William Lachance (wlach@interlog.com)
+ * Copyright (C) 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Contributor(s): Martin Gallwey (gallwey@sun.com)
+ *
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#ifndef _WORDPERFECTIMPORTFILTER_HXX
+#define _WORDPERFECTIMPORTFILTER_HXX
+
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/document/XExtendedFilterDetection.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <cppuhelper/implbase5.hxx>
+
+enum FilterType
+{
+ FILTER_IMPORT,
+ FILTER_EXPORT
+};
+/* This component will be instantiated for both import or export. Whether it calls
+ * setSourceDocument or setTargetDocument determines which Impl function the filter
+ * member calls */
+class MSWorksImportFilter : public cppu::WeakImplHelper5
+<
+ com::sun::star::document::XFilter,
+ com::sun::star::document::XImporter,
+ com::sun::star::document::XExtendedFilterDetection,
+ com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XServiceInfo
+>
+{
+protected:
+ // oo.org declares
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMSF;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mxDoc;
+ ::rtl::OUString msFilterName;
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > mxHandler;
+
+ FilterType meType;
+
+ sal_Bool SAL_CALL importImpl( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (::com::sun::star::uno::RuntimeException);
+
+public:
+ MSWorksImportFilter( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > &rxMSF)
+ : mxMSF( rxMSF )
+ , meType( FILTER_IMPORT )
+ {}
+ virtual ~MSWorksImportFilter() {}
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancel( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XImporter
+ virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ //XExtendedFilterDetection
+ virtual ::rtl::OUString SAL_CALL detect( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& Descriptor )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+};
+
+::rtl::OUString MSWorksImportFilter_getImplementationName()
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+sal_Bool SAL_CALL MSWorksImportFilter_supportsService( const ::rtl::OUString& ServiceName )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL MSWorksImportFilter_getSupportedServiceNames( )
+ throw ( ::com::sun::star::uno::RuntimeException );
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+SAL_CALL MSWorksImportFilter_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr)
+ throw ( ::com::sun::star::uno::Exception );
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerperfect/source/wpsimp/makefile.mk b/writerperfect/source/wpsimp/makefile.mk
new file mode 100644
index 000000000000..da17e806f9b0
--- /dev/null
+++ b/writerperfect/source/wpsimp/makefile.mk
@@ -0,0 +1,29 @@
+PRJ=..$/..
+
+PRJNAME=writerperfect
+TARGET=wpsimp
+ENABLE_EXCEPTIONS=true
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_LIBWPD)" == "YES"
+INCPRE+=$(LIBWPD_CFLAGS)
+.ELSE
+INCPRE+=$(SOLARVER)$/$(UPD)$/$(INPATH)$/inc$/libwpd
+.ENDIF
+
+.IF "$(SYSTEM_LIBWPS)" == "YES"
+INCPRE+=$(LIBWPS_CFLAGS)
+.ELSE
+INCPRE+=$(SOLARVER)$/$(UPD)$/$(INPATH)$/inc$/libwps
+.ENDIF
+
+# broken but ... necessary, internal include shafted ...
+INCPRE+= -I..
+
+SLOFILES= \
+ $(SLO)$/MSWorksCollector.obj \
+ $(SLO)$/MSWorksImportFilter.obj \
+ $(SLO)$/msworks_genericfilter.obj
+
+.INCLUDE : target.mk
diff --git a/writerperfect/source/wpsimp/msworks_genericfilter.cxx b/writerperfect/source/wpsimp/msworks_genericfilter.cxx
new file mode 100644
index 000000000000..695791431103
--- /dev/null
+++ b/writerperfect/source/wpsimp/msworks_genericfilter.cxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* genericfilter: mostly generic code for registering the filter
+ *
+ * Portions of this code Copyright 2000 by Sun Microsystems, Inc.
+ * Rest is Copyright (C) 2002 William Lachance (wlach@interlog.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+/* "This product is not manufactured, approved, or supported by
+ * Corel Corporation or Corel Corporation Limited."
+ */
+#include <stdio.h>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <cppuhelper/factory.hxx>
+
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include "MSWorksImportFilter.hxx"
+
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+
+extern "C"
+{
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+sal_Bool SAL_CALL component_writeInfo(
+ void * /* pServiceManager */, void * pRegistryKey )
+{
+ if (pRegistryKey)
+ {
+ try
+ {
+ sal_Int32 nPos = 0;
+ Reference< XRegistryKey > xNewKey(
+ reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey( MSWorksImportFilter_getImplementationName() ) );
+ xNewKey = xNewKey->createKey( OUString(RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES")) );
+
+ const Sequence< OUString > & rSNL = MSWorksImportFilter_getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( nPos = rSNL.getLength(); nPos--; )
+ xNewKey->createKey( pArray[nPos] );
+
+ return sal_True;
+ }
+ catch (InvalidRegistryException &)
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ }
+ }
+ return sal_False;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * /* pRegistryKey */ )
+{
+ void * pRet = 0;
+
+ OUString implName = OUString::createFromAscii( pImplName );
+ if ( pServiceManager && implName.equals(MSWorksImportFilter_getImplementationName()) )
+ {
+ Reference< XSingleServiceFactory > xFactory( createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString::createFromAscii( pImplName ),
+ MSWorksImportFilter_createInstance, MSWorksImportFilter_getSupportedServiceNames() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */