[libreoffice/f16] merge rhel6 ifdefs
Caolán McNamara
caolanm at fedoraproject.org
Mon Jan 16 11:04:17 UTC 2012
commit cda8f7fe2f04d114c9845ca12b17abdf78d81026
Author: Caolán McNamara <caolanm at redhat.com>
Date: Mon Jan 16 11:04:12 2012 +0000
merge rhel6 ifdefs
...riterperfect.diff-WPS-Import-filter-core-.patch | 292 ++
libreoffice-gcj.patch | 21 +
libreoffice-libwpd08-1.patch | 262 +
libreoffice-libwpd08-2.patch | 5439 ++++++++++++++++++++
libreoffice-rhel6poppler.patch | 38 +
libreoffice.spec | 84 +-
6 files changed, 6105 insertions(+), 31 deletions(-)
---
diff --git a/0001-wpsimport-writerperfect.diff-WPS-Import-filter-core-.patch b/0001-wpsimport-writerperfect.diff-WPS-Import-filter-core-.patch
new file mode 100644
index 0000000..ad1e52b
--- /dev/null
+++ b/0001-wpsimport-writerperfect.diff-WPS-Import-filter-core-.patch
@@ -0,0 +1,292 @@
+From f409dd088f95b2e00c59dc5642769b95245ba7fc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Fridrich=20=C5=A0trba?= <fridrich.strba at bluewin.ch>
+Date: Tue, 14 Sep 2010 11:07:30 +0200
+Subject: [PATCH] wpsimport-writerperfect.diff: WPS Import filter - core
+ implementation.
+
+---
+ writerperfect/prj/d.lst | 4 +-
+ writerperfect/source/filter/DocumentCollector.cxx | 2 +-
+ writerperfect/source/filter/DocumentCollector.hxx | 7 ++-
+ writerperfect/source/filter/DocumentHandler.cxx | 10 ++--
+ writerperfect/source/filter/SectionStyle.cxx | 2 +-
+ writerperfect/source/filter/makefile.mk | 12 +++--
+ writerperfect/source/stream/WPXSvStream.cxx | 2 +-
+ writerperfect/source/stream/WPXSvStream.h | 3 +-
+ writerperfect/source/stream/makefile.mk | 6 +++
+ .../source/wpdimp/WordPerfectCollector.cxx | 5 +-
+ .../source/wpdimp/WordPerfectCollector.hxx | 4 +-
+ writerperfect/source/wpdimp/makefile.mk | 12 +++--
+ writerperfect/util/makefile.mk | 47 +++++++++++++++++--
+ 14 files changed, 88 insertions(+), 33 deletions(-)
+
+diff --git a/writerperfect/prj/d.lst b/writerperfect/prj/d.lst
+index 5b5852c..fb11fa9 100644
+--- a/writerperfect/prj/d.lst
++++ b/writerperfect/prj/d.lst
+@@ -1,4 +1,4 @@
+-..\%__SRC%\lib\libwpft*.so %_DEST%\lib%_EXT%
+-..\%__SRC%\bin\wpft*.dll %_DEST%\bin%_EXT%
++..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT%
++..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%
+ ..\%__SRC%\bin\wpftgo.dll %_DEST%\bin%_EXT%\wpftgo.dll
+ ..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+diff --git a/writerperfect/source/filter/DocumentCollector.cxx b/writerperfect/source/filter/DocumentCollector.cxx
+index 828e799..5baae93 100644
+--- a/writerperfect/source/filter/DocumentCollector.cxx
++++ b/writerperfect/source/filter/DocumentCollector.cxx
+@@ -58,7 +58,7 @@ _WriterDocumentState::_WriterDocumentState() :
+ {
+ }
+
+-DocumentCollector::DocumentCollector(WPXInputStream *pInput, DocumentHandler *pHandler) :
++DocumentCollector::DocumentCollector(WPSInputStream *pInput, DocumentHandler *pHandler) :
+ mpInput(pInput),
+ mpHandler(pHandler),
+ mbUsed(false),
+diff --git a/writerperfect/source/filter/DocumentCollector.hxx b/writerperfect/source/filter/DocumentCollector.hxx
+index 18ebcdb..a1e7fbc 100644
+--- a/writerperfect/source/filter/DocumentCollector.hxx
++++ b/writerperfect/source/filter/DocumentCollector.hxx
+@@ -35,6 +35,7 @@
+ #if defined _MSC_VER
+ #pragma warning( push, 1 )
+ #endif
++#include <libwps/libwps.h>
+ #include <libwpd/libwpd.h>
+ #if defined _MSC_VER
+ #pragma warning( pop )
+@@ -82,7 +83,7 @@ struct ltstr
+ class DocumentCollector : public WPXHLListenerImpl
+ {
+ public:
+- DocumentCollector(WPXInputStream *pInput, DocumentHandler *pHandler);
++ DocumentCollector(WPSInputStream *pInput, DocumentHandler *pHandler);
+ virtual ~DocumentCollector();
+ bool filter();
+
+@@ -133,7 +134,7 @@ public:
+ virtual void closeTableCell();
+ virtual void insertCoveredTableCell(const WPXPropertyList &propList);
+ virtual void closeTable();
+- virtual bool parseSourceDocument(WPXInputStream &input) = 0;
++ virtual bool parseSourceDocument(WPSInputStream &input) = 0;
+
+ protected:
+ void _resetDocumentState();
+@@ -147,7 +148,7 @@ private:
+ void _openListLevel(TagOpenElement *pListLevelOpenElement);
+ void _closeListLevel(const char *szListType);
+
+- WPXInputStream *mpInput;
++ WPSInputStream *mpInput;
+ DocumentHandler *mpHandler;
+ bool mbUsed; // whether or not it has been before (you can only use me once!)
+
+diff --git a/writerperfect/source/filter/DocumentHandler.cxx b/writerperfect/source/filter/DocumentHandler.cxx
+index e0a11ab..2af504c 100644
+--- a/writerperfect/source/filter/DocumentHandler.cxx
++++ b/writerperfect/source/filter/DocumentHandler.cxx
+@@ -42,19 +42,19 @@ DocumentHandler::DocumentHandler(Reference < XDocumentHandler > &xHandler) :
+
+ void DocumentHandler::startDocument()
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::startDocument"));
++ WRITER_DEBUG_MSG(("DocumentHandler::startDocument\n"));
+ mxHandler->startDocument();
+ }
+
+ void DocumentHandler::endDocument()
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::endDocument"));
++ WRITER_DEBUG_MSG(("DocumentHandler::endDocument\n"));
+ mxHandler->endDocument();
+ }
+
+ void DocumentHandler::startElement(const char *psName, const WPXPropertyList &xPropList)
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::startElement"));
++ WRITER_DEBUG_MSG(("DocumentHandler::startElement\n"));
+ SvXMLAttributeList *pAttrList = new SvXMLAttributeList();
+ Reference < XAttributeList > xAttrList(pAttrList);
+ WPXPropertyList::Iter i(xPropList);
+@@ -71,13 +71,13 @@ void DocumentHandler::startElement(const char *psName, const WPXPropertyList &xP
+
+ void DocumentHandler::endElement(const char *psName)
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::endElement"));
++ WRITER_DEBUG_MSG(("DocumentHandler::endElement\n"));
+ mxHandler->endElement(OUString::createFromAscii(psName));
+ }
+
+ void DocumentHandler::characters(const WPXString &sCharacters)
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::characters"));
++ WRITER_DEBUG_MSG(("DocumentHandler::characters\n"));
+ OUString sCharU16(sCharacters.cstr(), strlen(sCharacters.cstr()), RTL_TEXTENCODING_UTF8);
+ mxHandler->characters(sCharU16);
+ }
+diff --git a/writerperfect/source/filter/SectionStyle.cxx b/writerperfect/source/filter/SectionStyle.cxx
+index 7dae06c..de94e9c 100644
+--- a/writerperfect/source/filter/SectionStyle.cxx
++++ b/writerperfect/source/filter/SectionStyle.cxx
+@@ -33,7 +33,7 @@
+
+ #ifdef _MSC_VER
+ double rint(double x);
+-#endif /* _WIN32 */
++#endif /* _MSC_VER */
+
+ SectionStyle::SectionStyle(const WPXPropertyList &xPropList,
+ const WPXPropertyListVector &xColumns,
+diff --git a/writerperfect/source/filter/makefile.mk b/writerperfect/source/filter/makefile.mk
+index e535d2a..a092ce2 100644
+--- a/writerperfect/source/filter/makefile.mk
++++ b/writerperfect/source/filter/makefile.mk
+@@ -7,12 +7,16 @@ ENABLE_EXCEPTIONS=true
+ .INCLUDE : settings.mk
+
+ .IF "$(SYSTEM_LIBWPD)" == "YES"
+-INCPRE+=$(LIBWPD_CFLAGS) -I..
+-.ELSE
+-# broken but ... necessary, internal include shafted ...
+-INCPRE+=-I..
++INCPRE+=$(LIBWPD_CFLAGS)
++.ENDIF
++
++.IF "$(SYSTEM_LIBWPS)" == "YES"
++INCPRE+=$(LIBWPS_CFLAGS)
+ .ENDIF
+
++# broken but ... necessary, internal include shafted ...
++INCPRE+= -I..
++
+ SLOFILES= \
+ $(SLO)$/DocumentElement.obj \
+ $(SLO)$/FontStyle.obj \
+diff --git a/writerperfect/source/stream/WPXSvStream.cxx b/writerperfect/source/stream/WPXSvStream.cxx
+index 3737e93..f7cfe35 100644
+--- a/writerperfect/source/stream/WPXSvStream.cxx
++++ b/writerperfect/source/stream/WPXSvStream.cxx
+@@ -10,7 +10,7 @@
+ using namespace ::com::sun::star::io;
+
+ WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
+- WPXInputStream(true),
++ WPSInputStream(),
+ mxChildStorage(),
+ mxChildStream(),
+ mxStream(xStream),
+@@ -147,7 +147,7 @@
+ return 0;
+ }
+
+- mxChildStorage = new SotStorage( pStream, true );
++ mxChildStorage = new SotStorage( pStream, TRUE );
+
+ mxChildStream = mxChildStorage->OpenSotStream(
+ rtl::OUString::createFromAscii( name ),
+diff --git a/writerperfect/source/stream/WPXSvStream.h b/writerperfect/source/stream/WPXSvStream.h
+index 099c5a7..f4f3b7e 100644
+--- a/writerperfect/source/stream/WPXSvStream.h
++++ b/writerperfect/source/stream/WPXSvStream.h
+@@ -12,12 +12,13 @@
+ #if defined _MSC_VER
+ #pragma warning( push, 1 )
+ #endif
++#include <libwps/WPSStream.h>
+ #include <libwpd/WPXStream.h>
+ #if defined _MSC_VER
+ #pragma warning( pop )
+ #endif
+
+-class WPXSvInputStream : public WPXInputStream
++class WPXSvInputStream : public WPSInputStream
+ {
+ public:
+ WPXSvInputStream( ::com::sun::star::uno::Reference<
+diff --git a/writerperfect/source/stream/makefile.mk b/writerperfect/source/stream/makefile.mk
+index 7e684b7..97262e7 100644
+--- a/writerperfect/source/stream/makefile.mk
++++ b/writerperfect/source/stream/makefile.mk
+@@ -10,6 +10,12 @@ ENABLE_EXCEPTIONS=true
+ 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..
+
+diff --git a/writerperfect/source/wpdimp/WordPerfectCollector.cxx b/writerperfect/source/wpdimp/WordPerfectCollector.cxx
+index 0bc10cc..9d32fde 100644
+--- a/writerperfect/source/wpdimp/WordPerfectCollector.cxx
++++ b/writerperfect/source/wpdimp/WordPerfectCollector.cxx
+@@ -30,11 +30,12 @@
+ #pragma warning( push, 1 )
+ #endif
+ #include "WordPerfectCollector.hxx"
++#include <libwpd/WPDocument.h>
+ #if defined _MSC_VER
+ #pragma warning( pop )
+ #endif
+
+-WordPerfectCollector::WordPerfectCollector(WPXInputStream *pInput, DocumentHandler *pHandler) :
++WordPerfectCollector::WordPerfectCollector(WPSInputStream *pInput, DocumentHandler *pHandler) :
+ DocumentCollector(pInput, pHandler)
+ {
+ }
+@@ -43,7 +44,7 @@ WordPerfectCollector::~WordPerfectCollector()
+ {
+ }
+
+-bool WordPerfectCollector::parseSourceDocument(WPXInputStream &input)
++bool WordPerfectCollector::parseSourceDocument(WPSInputStream &input)
+ {
+ WPDResult result = WPDocument::parse(&input, static_cast<WPXHLListenerImpl *>(this));
+ if (result != WPD_OK)
+diff --git a/writerperfect/source/wpdimp/WordPerfectCollector.hxx b/writerperfect/source/wpdimp/WordPerfectCollector.hxx
+index 400a5ca..95ed7af 100644
+--- a/writerperfect/source/wpdimp/WordPerfectCollector.hxx
++++ b/writerperfect/source/wpdimp/WordPerfectCollector.hxx
+@@ -35,9 +35,9 @@
+ class WordPerfectCollector : public DocumentCollector
+ {
+ public:
+- WordPerfectCollector(WPXInputStream *pInput, DocumentHandler *pHandler);
++ WordPerfectCollector(WPSInputStream *pInput, DocumentHandler *pHandler);
+ virtual ~WordPerfectCollector();
+- bool parseSourceDocument(WPXInputStream &pInput);
++ bool parseSourceDocument(WPSInputStream &pInput);
+ };
+ #endif
+
+diff --git a/writerperfect/source/wpdimp/makefile.mk b/writerperfect/source/wpdimp/makefile.mk
+index bc2a3cd..745887e 100644
+--- a/writerperfect/source/wpdimp/makefile.mk
++++ b/writerperfect/source/wpdimp/makefile.mk
+@@ -7,12 +7,16 @@ ENABLE_EXCEPTIONS=true
+ .INCLUDE : settings.mk
+
+ .IF "$(SYSTEM_LIBWPD)" == "YES"
+-INCPRE+=$(LIBWPD_CFLAGS) -I..
+-.ELSE
+-# broken but ... necessary, internal include shafted ...
+-INCPRE+=-I..
++INCPRE+=$(LIBWPD_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 \
diff --git a/libreoffice-gcj.patch b/libreoffice-gcj.patch
new file mode 100644
index 0000000..b91e21d
--- /dev/null
+++ b/libreoffice-gcj.patch
@@ -0,0 +1,21 @@
+--- a/scp2/source/ooo/profileitem_ooo.scp 2011-11-02 09:25:43.058473566 +0000
++++ b/scp2/source/ooo/profileitem_ooo.scp 2011-11-02 09:27:00.110473381 +0000
+@@ -383,14 +383,15 @@
+ Section = "Bootstrap";
+ Key = "URE_MORE_JAVA_CLASSPATH_URLS";
+ Value = "";
++ ValueList1 = "$ORIGIN/../ure-link/lib";
+ #ifdef SYSTEM_BSH
+- ValueList1 = BSH_JAR;
++ ValueList2 = BSH_JAR;
+ #endif
+ #ifdef SYSTEM_HSQLDB
+- ValueList2 = HSQLDB_JAR;
++ ValueList3 = HSQLDB_JAR;
+ #endif
+ #ifdef SYSTEM_SAXON
+- ValueList3 = SAXON_JAR;
++ ValueList4 = SAXON_JAR;
+ #endif
+ End
+
diff --git a/libreoffice-libwpd08-1.patch b/libreoffice-libwpd08-1.patch
new file mode 100644
index 0000000..778a377
--- /dev/null
+++ b/libreoffice-libwpd08-1.patch
@@ -0,0 +1,262 @@
+--- a/set_soenv.in 2011-08-15 19:34:27.000000000 +0100
++++ b/set_soenv.in 2011-09-29 10:15:05.920863766 +0100
+@@ -1972,12 +1972,6 @@
+ ToFile( "SYSTEM_LIBWPD", "@SYSTEM_LIBWPD@", "e" );
+ ToFile( "LIBWPD_CFLAGS", "@LIBWPD_CFLAGS@", "e" );
+ ToFile( "LIBWPD_LIBS", "@LIBWPD_LIBS@", "e" );
+-ToFile( "SYSTEM_LIBWPS", "@SYSTEM_LIBWPS@", "e" );
+-ToFile( "LIBWPS_CFLAGS", "@LIBWPS_CFLAGS@", "e" );
+-ToFile( "LIBWPS_LIBS", "@LIBWPS_LIBS@", "e" );
+-ToFile( "SYSTEM_LIBWPG", "@SYSTEM_LIBWPG@", "e" );
+-ToFile( "LIBWPG_CFLAGS", "@LIBWPG_CFLAGS@", "e" );
+-ToFile( "LIBWPG_LIBS", "@LIBWPG_LIBS@", "e" );
+ ToFile( "SYSTEM_CPPUNIT", "@SYSTEM_CPPUNIT@", "e" );
+ ToFile( "CPPUNIT_CFLAGS", "@CPPUNIT_CFLAGS@", "e" );
+ ToFile( "CPPUNIT_LIBS", "@CPPUNIT_LIBS@", "e" );
+--- a/configure.in 2011-09-29 11:12:20.342862974 +0100
++++ b/configure.in 2011-09-29 11:21:15.687862230 +0100
+@@ -709,16 +709,6 @@
+ [Use libwpd already on system.]),
+ ,)
+
+-AC_ARG_WITH(system-libwps,
+- AS_HELP_STRING([--with-system-libwps],
+- [Use libwps already on system.]),
+-,)
+-
+-AC_ARG_WITH(system-libwpg,
+- AS_HELP_STRING([--with-system-libwpg],
+- [Use libwpg already on system.]),
+-,)
+-
+ AC_ARG_WITH(system-libxml,
+ AS_HELP_STRING([--with-system-libxml],
+ [Use libxml already on system.]),
+@@ -4004,7 +3994,7 @@
+ test "$with_system_libwpd" != "no"; then
+ AC_MSG_RESULT([external])
+ SYSTEM_LIBWPD=YES
+- PKG_CHECK_MODULES( LIBWPD, libwpd-0.9 libwpd-stream-0.9 )
++ PKG_CHECK_MODULES( LIBWPD, libwpd-0.8 libwpd-stream-0.8 )
+ else
+ AC_MSG_RESULT([internal])
+ SYSTEM_LIBWPD=NO
+@@ -4044,42 +4034,6 @@
+ AC_SUBST(FREETYPE_LIBS)
+
+ dnl ===================================================================
+-dnl Check for system libwps
+-dnl ===================================================================
+-AC_MSG_CHECKING([which libwps to use])
+-if test -n "$with_system_libwps" -o -n "$with_system_libs" && \
+- test "$with_system_libwps" != "no"; then
+- AC_MSG_RESULT([external])
+- SYSTEM_LIBWPS=YES
+- PKG_CHECK_MODULES( LIBWPS, libwps-0.2 )
+-else
+- AC_MSG_RESULT([internal])
+- SYSTEM_LIBWPS=NO
+- BUILD_TYPE="$BUILD_TYPE LIBWPS"
+-fi
+-AC_SUBST(SYSTEM_LIBWPS)
+-AC_SUBST(LIBWPS_CFLAGS)
+-AC_SUBST(LIBWPS_LIBS)
+-
+-dnl ===================================================================
+-dnl Check for system libwpg
+-dnl ===================================================================
+-AC_MSG_CHECKING([which libwpg to use])
+-if test -n "$with_system_libwpg" -o -n "$with_system_libs" && \
+- test "$with_system_libwpg" != "no"; then
+- AC_MSG_RESULT([external])
+- SYSTEM_LIBWPG=YES
+- PKG_CHECK_MODULES( LIBWPG, libwpg-0.2 )
+-else
+- AC_MSG_RESULT([internal])
+- SYSTEM_LIBWPG=NO
+- BUILD_TYPE="$BUILD_TYPE LIBWPG"
+-fi
+-AC_SUBST(SYSTEM_LIBWPG)
+-AC_SUBST(LIBWPG_CFLAGS)
+-AC_SUBST(LIBWPG_LIBS)
+-
+-dnl ===================================================================
+ dnl Check whether freetype2 supports emboldening
+ dnl ===================================================================
+ if test "$test_freetype" = "yes"; then
+@@ -4356,22 +4310,6 @@
+ AC_CHECK_FILE($LUCENE_CORE_JAR, [],
+ [ AC_MSG_ERROR(lucene-analyzers.jar not found.)], [])
+ fi
+- AC_MSG_CHECKING([whether lucene is version 2.x])
+- export LUCENE_CORE_JAR
+- if $PERL -e 'use Archive::Zip;
+- my $file = "$ENV{'LUCENE_CORE_JAR'}";
+- my $zip = Archive::Zip->new( $file );
+- my $mf = $zip->contents ( "META-INF/MANIFEST.MF" );
+- if ( $mf =~ m/Specification-Version: 2.*/ ) {
+- exit 0;
+- } else {
+- exit 1;
+- }'; then
+- AC_MSG_RESULT([yes])
+- else
+- AC_MSG_ERROR([no, you need lucene 2])
+- fi
+-
+ else
+ AC_MSG_RESULT([internal])
+ SYSTEM_LUCENE=NO
+@@ -5545,8 +5483,7 @@
+ test "$with_system_redland" != "no"; then
+ AC_MSG_RESULT([external])
+ SYSTEM_REDLAND=YES
+- dnl versions before 1.0.8 write RDF/XML that is useless for ODF (@xml:base)
+- PKG_CHECK_MODULES(REDLAND, redland >= 1.0.8)
++ PKG_CHECK_MODULES( REDLAND, redland )
+ else
+ AC_MSG_RESULT([internal])
+ BUILD_TYPE="$BUILD_TYPE REDLAND"
+diff --git a/writerperfect/util/makefile.mk b/writerperfect/util/makefile.mk
+index dca29e0..56bdfb2 100644
+--- a/writerperfect/util/makefile.mk
++++ b/writerperfect/util/makefile.mk
+@@ -13,23 +13,9 @@
+ LIBWPD=-lwpdlib
+ .ENDIF
+
+-.IF "$(SYSTEM_LIBWPS)" == "YES"
+-LIBWPS=$(LIBWPS_LIBS)
+-.ELSE
+-LIBWPS=-lwpslib
+-.ENDIF
+-
+-.IF "$(SYSTEM_LIBWPG)" == "YES"
+-LIBWPG=$(LIBWPG_LIBS)
+-.ELSE
+-LIBWPG=-lwpglib
+-.ENDIF
+-
+ .ELSE
+
+ LIBWPD=$(LIBPRE) wpdlib.lib
+-LIBWPS=$(LIBPRE) wpslib.lib
+-LIBWPG=$(LIBPRE) wpglib.lib
+
+ .ENDIF
+
+@@ -60,82 +46,12 @@
+ SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+ DEF1NAME=$(SHL1TARGET)
+
+-
+-LIB2TARGET= $(SLB)$/msworks.lib
+-LIB2FILES= \
+- $(SLB)$/stream.lib \
+- $(SLB)$/filter.lib \
+- $(SLB)$/wpsimp.lib
+-SHL2LIBS=$(LIB2TARGET)
+-SHL2STDLIBS+= \
+- $(SVLLIB) \
+- $(SOTLIB) \
+- $(SO2LIB) \
+- $(SVTOOLLIB) \
+- $(UNOTOOLSLIB) \
+- $(TOOLSLIB) \
+- $(COMPHELPERLIB) \
+- $(UCBHELPERLIB) \
+- $(CPPUHELPERLIB) \
+- $(CPPULIB) \
+- $(SALLIB) \
+- $(XMLOFFLIB) \
+- $(LIBWPS) \
+- $(LIBWPG) \
+- $(LIBWPD)
+-
+-SHL2TARGET = msworks$(DLLPOSTFIX)
+-SHL2IMPLIB = i$(SHL2TARGET)
+-SHL2LIBS = $(LIB2TARGET)
+-SHL2VERSIONMAP = $(SOLARENV)/src/component.map
+-DEF2NAME = $(SHL2TARGET)
+-
+-LIB3TARGET= $(SLB)$/wpgimport.lib
+-LIB3FILES= \
+- $(SLB)$/stream.lib \
+- $(SLB)$/filter.lib \
+- $(SLB)$/wpgimp.lib
+-SHL3LIBS=$(LIB3TARGET)
+-SHL3STDLIBS+= \
+- $(SVLLIB) \
+- $(SOTLIB) \
+- $(SO2LIB) \
+- $(SVTOOLLIB) \
+- $(UNOTOOLSLIB) \
+- $(TOOLSLIB) \
+- $(COMPHELPERLIB) \
+- $(UCBHELPERLIB) \
+- $(CPPUHELPERLIB) \
+- $(CPPULIB) \
+- $(SALLIB) \
+- $(XMLOFFLIB) \
+- $(LIBWPG) \
+- $(LIBWPD)
+-
+-SHL3TARGET = wpgimport$(DLLPOSTFIX)
+-SHL3IMPLIB = i$(SHL3TARGET)
+-SHL3LIBS = $(LIB3TARGET)
+-SHL3VERSIONMAP = $(SOLARENV)/src/component.map
+-DEF3NAME = $(SHL3TARGET)
+-
+ .INCLUDE : target.mk
+
+-ALLTAR : $(MISC)/wpft.component $(MISC)/wpgfilter.component $(MISC)/msworksfilter.component
++ALLTAR : $(MISC)/wpft.component
+
+ $(MISC)/wpft.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ wpft.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt wpft.component
+-
+-$(MISC)/wpgfilter.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+- wpgfilter.component
+- $(XSLTPROC) --nonet --stringparam uri \
+- '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL3TARGETN:f)' -o $@ \
+- $(SOLARENV)/bin/createcomponent.xslt wpgfilter.component
+-
+-$(MISC)/msworksfilter.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+- msworksfilter.component
+- $(XSLTPROC) --nonet --stringparam uri \
+- '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL2TARGETN:f)' -o $@ \
+- $(SOLARENV)/bin/createcomponent.xslt msworksfilter.component
+--- a/writerperfect/prj/build.lst 2011-05-20 17:05:36.000000000 +0100
++++ b/writerperfect/prj/build.lst 2011-10-20 09:06:36.065483147 +0100
+@@ -1,8 +1,6 @@
+-wp writerperfect : LIBWPG:libwpg LIBWPS:libwps LIBWPD:libwpd sot comphelper xmloff svtools sfx2 LIBXSLT:libxslt NULL
++wp writerperfect : LIBWPD:libwpd sot comphelper xmloff svtools NULL
+ wp writerperfect usr1 - all wp_mkout NULL
+ wp writerperfect\source\stream nmake - all wp_stream NULL
+ wp writerperfect\source\filter nmake - all wp_filter NULL
+ wp writerperfect\source\wpdimp nmake - all wp_wpdimp NULL
+-wp writerperfect\source\wpsimp nmake - all wp_wpsimp NULL
+-wp writerperfect\source\wpgimp nmake - all wp_wpgimp NULL
+-wp writerperfect\util nmake - all wp_util wp_wpgimp wp_wpsimp wp_wpdimp wp_filter wp_stream NULL
++wp writerperfect\util nmake - all wp_util wp_wpdimp wp_filter wp_stream NULL
+--- a/postprocess/packcomponents/makefile.mk 2011-10-20 11:04:07.518473380 +0100
++++ b/postprocess/packcomponents/makefile.mk 2011-10-20 11:06:51.434484830 +0100
+@@ -129,7 +129,6 @@
+ migrationoo3 \
+ mtfrenderer \
+ msfilter \
+- msworksfilter \
+ mysql \
+ odbc \
+ odfflatxml \
+@@ -185,7 +184,6 @@
+ vcl \
+ vclcanvas \
+ wpft \
+- wpgfilter \
+ writerfilter \
+ xcr \
+ xmlfa \
diff --git a/libreoffice-libwpd08-2.patch b/libreoffice-libwpd08-2.patch
new file mode 100644
index 0000000..137efa4
--- /dev/null
+++ b/libreoffice-libwpd08-2.patch
@@ -0,0 +1,5439 @@
+diff --git a/writerperfect/source/filter/DocumentCollector.cxx b/writerperfect/source/filter/DocumentCollector.cxx
+index 879e1d0..cae7736 100644
+--- a/writerperfect/source/filter/DocumentCollector.cxx
++++ b/writerperfect/source/filter/DocumentCollector.cxx
+@@ -40,6 +40,8 @@
+
+ #include "DocumentCollector.hxx"
+ #include "DocumentElement.hxx"
++#include "DocumentHandler.hxx"
++#include "InternalHandler.hxx"
+ #include "TextRunStyle.hxx"
+ #include "FontStyle.hxx"
+ #include "ListStyle.hxx"
+@@ -48,34 +50,49 @@
+ #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)
++ mbInNote(false),
++ mbInTextBox(false),
++ mbInFrame(false)
+ {
+ }
+
+-DocumentCollector::DocumentCollector(WPSInputStream *pInput, DocumentHandler *pHandler) :
++_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),
+- mfSectionSpaceAfter(0.0f),
++ mWriterDocumentStates(),
++ mWriterListStates(),
++ mfSectionSpaceAfter(0.0),
+ miNumListStyles(0),
+ mpCurrentContentElements(&mBodyElements),
+ mpCurrentPageSpan(NULL),
+ miNumPageStyles(0),
+- mpCurrentListStyle(NULL),
+- miCurrentListLevel(0),
+- miLastListLevel(0),
+- miLastListNumber(0),
+- mbListContinueNumbering(false),
+- mbListElementOpened(false),
+- mbListElementParagraphOpened(false)
++ miObjectNumber(0),
++ mbIsFlatXML(true),
++ mpPassword(NULL)
+ {
++ mWriterDocumentStates.push(WriterDocumentState());
++ mWriterListStates.push(WriterListState());
+ }
+
+ DocumentCollector::~DocumentCollector()
+@@ -102,111 +119,132 @@ bool DocumentCollector::filter()
+ 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));
++ 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++) {
++ 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, 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, 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::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++) {
++ 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++) {
++ 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<TableStyle *>::iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); ++iterTableStyles) {
++ delete((*iterTableStyles));
+ }
+
+- for (std::vector<PageSpan *>::iterator iterPageSpans = mPageSpans.begin(); iterPageSpans != mPageSpans.end(); iterPageSpans++) {
++ 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(DocumentHandler *pHandler)
++void DocumentCollector::_writeDefaultStyles(DocumentHandlerInterface *pHandler)
+ {
+- TagOpenElement stylesOpenElement("office:styles");
+- stylesOpenElement.write(pHandler);
++ TagOpenElement("office:styles").write(pHandler);
+
+ TagOpenElement defaultParagraphStyleOpenElement("style:default-style");
+ defaultParagraphStyleOpenElement.addAttribute("style:family", "paragraph");
+ defaultParagraphStyleOpenElement.write(pHandler);
+
+- TagOpenElement defaultParagraphStylePropertiesOpenElement("style:properties");
+- defaultParagraphStylePropertiesOpenElement.addAttribute("style:family", "paragraph");
+- defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5inch");
++ TagOpenElement defaultParagraphStylePropertiesOpenElement("style:paragraph-properties");
++ defaultParagraphStylePropertiesOpenElement.addAttribute("style:tab-stop-distance", "0.5in");
+ defaultParagraphStylePropertiesOpenElement.write(pHandler);
+- TagCloseElement defaultParagraphStylePropertiesCloseElement("style:properties");
++ TagCloseElement defaultParagraphStylePropertiesCloseElement("style:paragraph-properties");
+ defaultParagraphStylePropertiesCloseElement.write(pHandler);
+
+- TagCloseElement defaultParagraphStyleCloseElement("style:default-style");
+- defaultParagraphStyleCloseElement.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);
+- TagCloseElement standardStyleCloseElement("style:style");
+- standardStyleCloseElement.write(pHandler);
++
++ pHandler->endElement("style:style");
+
+ TagOpenElement textBodyStyleOpenElement("style:style");
+- textBodyStyleOpenElement.addAttribute("style:name", "Text Body");
++ 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);
+- TagCloseElement textBodyStyleCloseElement("style:style");
+- textBodyStyleCloseElement.write(pHandler);
++
++ pHandler->endElement("style:style");
+
+ TagOpenElement tableContentsStyleOpenElement("style:style");
+- tableContentsStyleOpenElement.addAttribute("style:name", "Table Contents");
++ 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:parent-style-name", "Text_Body");
+ tableContentsStyleOpenElement.addAttribute("style:class", "extra");
+ tableContentsStyleOpenElement.write(pHandler);
+- TagCloseElement tableContentsStyleCloseElement("style:style");
+- tableContentsStyleCloseElement.write(pHandler);
++
++ pHandler->endElement("style:style");
+
+ TagOpenElement tableHeadingStyleOpenElement("style:style");
+- tableHeadingStyleOpenElement.addAttribute("style:name", "Table Heading");
++ 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:parent-style-name", "Table_Contents");
+ tableHeadingStyleOpenElement.addAttribute("style:class", "extra");
+ tableHeadingStyleOpenElement.write(pHandler);
+- TagCloseElement tableHeadingStyleCloseElement("style:style");
+- tableHeadingStyleCloseElement.write(pHandler);
+
+- TagCloseElement stylesCloseElement("office:styles");
+- stylesCloseElement.write(pHandler);
++ 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(DocumentHandler *pHandler)
++void DocumentCollector::_writeMasterPages(DocumentHandlerInterface *pHandler)
+ {
+- WPXPropertyList xBlankAttrList;
+-
+- pHandler->startElement("office:master-styles", xBlankAttrList);
++ TagOpenElement("office:master-styles").write(mpHandler);
+ int pageNumber = 1;
+ for (unsigned int i=0; i<mPageSpans.size(); i++)
+ {
+@@ -218,66 +256,80 @@ void DocumentCollector::_writeMasterPages(DocumentHandler *pHandler)
+ pHandler->endElement("office:master-styles");
+ }
+
+-void DocumentCollector::_writePageMasters(DocumentHandler *pHandler)
++void DocumentCollector::_writePageLayouts(DocumentHandlerInterface *pHandler)
+ {
+ for (unsigned int i=0; i<mPageSpans.size(); i++)
+ {
+- mPageSpans[i]->writePageMaster(i, pHandler);
++ mPageSpans[i]->writePageLayout(i, pHandler);
+ }
+ }
+
+-bool DocumentCollector::_writeTargetDocument(DocumentHandler *pHandler)
++bool DocumentCollector::_writeTargetDocument(DocumentHandlerInterface *pHandler)
+ {
+ WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Printing out the header stuff..\n"));
+- WPXPropertyList xBlankAttrList;
+
+ WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Start Document\n"));
+ mpHandler->startDocument();
+
+ WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: preamble\n"));
+ WPXPropertyList docContentPropList;
+- docContentPropList.insert("xmlns:office", "http://openoffice.org/2000/office");
+- docContentPropList.insert("xmlns:style", "http://openoffice.org/2000/style");
+- docContentPropList.insert("xmlns:text", "http://openoffice.org/2000/text");
+- docContentPropList.insert("xmlns:table", "http://openoffice.org/2000/table");
+- docContentPropList.insert("xmlns:draw", "http://openoffice.org/2000/draw");
+- docContentPropList.insert("xmlns:fo", "http://www.w3.org/1999/XSL/Format");
++ docContentPropList.insert("xmlns: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", "http://www.w3.org/2000/svg");
+- docContentPropList.insert("xmlns:chart", "http://openoffice.org/2000/chart");
+- docContentPropList.insert("xmlns:dr3d", "http://openoffice.org/2000/dr3d");
++ docContentPropList.insert("xmlns: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", "http://openoffice.org/2000/form");
+- docContentPropList.insert("xmlns:script", "http://openoffice.org/2000/script");
+- docContentPropList.insert("office:class", "text");
++ 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");
+- mpHandler->startElement("office:document-content", docContentPropList);
++ 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
+- mpHandler->startElement("office:font-decls", xBlankAttrList);
+- for (std::map<WPXString, FontStyle *, ltstr>::iterator iterFont = mFontHash.begin(); iterFont != mFontHash.end(); iterFont++) {
++ 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-decl");
++ TagOpenElement symbolFontOpen("style:font-face");
+ symbolFontOpen.addAttribute("style:name", "StarSymbol");
+- symbolFontOpen.addAttribute("fo:font-family", "StarSymbol");
++ symbolFontOpen.addAttribute("svg:font-family", "StarSymbol");
+ symbolFontOpen.addAttribute("style:font-charset", "x-symbol");
+ symbolFontOpen.write(mpHandler);
+- mpHandler->endElement("style:font-decl");
+-
+- mpHandler->endElement("office:font-decls");
++ 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);
+
+- mpHandler->startElement("office:automatic-styles", xBlankAttrList);
++ 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>::iterator iterTextStyle = mTextStyleHash.begin();
+- iterTextStyle != mTextStyleHash.end(); iterTextStyle++)
++ 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"))
+@@ -288,29 +340,29 @@ bool DocumentCollector::_writeTargetDocument(DocumentHandler *pHandler)
+ }
+
+ // span styles..
+- for (std::map<WPXString, SpanStyle *, ltstr>::iterator iterSpanStyle = mSpanStyleHash.begin();
+- iterSpanStyle != mSpanStyleHash.end(); iterSpanStyle++)
++ 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 *>::iterator iterSectionStyles = mSectionStyles.begin(); iterSectionStyles != mSectionStyles.end(); iterSectionStyles++) {
++ 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 *>::iterator iterListStyles = mListStyles.begin(); iterListStyles != mListStyles.end(); iterListStyles++) {
++ 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 *>::iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); iterTableStyles++) {
++ for (std::vector<TableStyle *>::const_iterator iterTableStyles = mTableStyles.begin(); iterTableStyles != mTableStyles.end(); ++iterTableStyles) {
+ (*iterTableStyles)->write(pHandler);
+ }
+
+ // writing out the page masters
+- _writePageMasters(pHandler);
++ _writePageLayouts(pHandler);
+
+
+ pHandler->endElement("office:automatic-styles");
+@@ -319,15 +371,17 @@ bool DocumentCollector::_writeTargetDocument(DocumentHandler *pHandler)
+
+ WRITER_DEBUG_MSG(("WriterWordPerfect: Document Body: Writing out the document..\n"));
+ // writing out the document
+- pHandler->startElement("office:body", xBlankAttrList);
++ TagOpenElement("office:body").write(mpHandler);
++ TagOpenElement("office:text").write(mpHandler);
+
+- for (std::vector<DocumentElement *>::iterator iterBodyElements = mBodyElements.begin(); iterBodyElements != mBodyElements.end(); iterBodyElements++) {
++ 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-content");
++ pHandler->endElement("office:document");
+
+ pHandler->endDocument();
+
+@@ -375,21 +429,47 @@ void DocumentCollector::_allocateFontName(const WPXString & sFontName)
+ }
+ }
+
++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;
++}
++
++static bool
++isOccurrenceEven (const WPXPropertyList &propList)
++{
++ const WPXProperty *occurance = propList["libwpd:occurence"];
++ return occurance && occurance->getStr() == "even";
+ }
+
+ 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);
++ if (isOccurrenceEven (propList))
++ mpCurrentPageSpan->setHeaderLeftContent(pHeaderFooterContentElements);
++ else
++ mpCurrentPageSpan->setHeaderContent(pHeaderFooterContentElements);
+
+ mpCurrentContentElements = pHeaderFooterContentElements;
+ }
+@@ -403,10 +483,10 @@ 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);
++ if (isOccurrenceEven (propList))
++ mpCurrentPageSpan->setFooterLeftContent(pHeaderFooterContentElements);
++ else
++ mpCurrentPageSpan->setFooterContent(pHeaderFooterContentElements);
+
+ mpCurrentContentElements = pHeaderFooterContentElements;
+ }
+@@ -419,16 +499,20 @@ void DocumentCollector::closeFooter()
+ void DocumentCollector::openSection(const WPXPropertyList &propList, const WPXPropertyListVector &columns)
+ {
+ int iNumColumns = columns.count();
+- float fSectionMarginLeft = 0.0f;
+- float fSectionMarginRight = 0.0f;
++ double fSectionMarginLeft = 0.0;
++ double fSectionMarginRight = 0.0;
+ if (propList["fo:margin-left"])
+- fSectionMarginLeft = propList["fo:margin-left"]->getFloat();
++ fSectionMarginLeft = propList["fo:margin-left"]->getDouble();
+ if (propList["fo:margin-right"])
+- fSectionMarginRight = propList["fo:margin-right"]->getFloat();
++ fSectionMarginRight = propList["fo:margin-right"]->getDouble();
+
+ if (iNumColumns > 1 || fSectionMarginLeft != 0 || fSectionMarginRight != 0)
+ {
+- mfSectionSpaceAfter = propList["fo:margin-bottom"]->getFloat();
++ 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());
+
+@@ -438,29 +522,20 @@ void DocumentCollector::openSection(const WPXPropertyList &propList, const WPXPr
+ TagOpenElement *pSectionOpenElement = new TagOpenElement("text:section");
+ pSectionOpenElement->addAttribute("text:style-name", pSectionStyle->getName());
+ pSectionOpenElement->addAttribute("text:name", pSectionStyle->getName());
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pSectionOpenElement));
++ mpCurrentContentElements->push_back(pSectionOpenElement);
+ }
+ else
+- mWriterDocumentState.mbInFakeSection = true;
++ mWriterDocumentStates.top().mbInFakeSection = true;
+ }
+
+ void DocumentCollector::closeSection()
+ {
+- if (!mWriterDocumentState.mbInFakeSection)
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:section")));
++ if (!mWriterDocumentStates.top().mbInFakeSection)
++ mpCurrentContentElements->push_back(new TagCloseElement("text:section"));
+ else
+- mWriterDocumentState.mbInFakeSection = false;
++ mWriterDocumentStates.top().mbInFakeSection = false;
+
+- // open as many paragraphs as needed to simulate section space after
+- // WLACH_REFACTORING: disable this for now..
+- #if 0
+- for (float f=0.0f; f<mfSectionSpaceAfter; f+=1.0f) {
+- vector<WPXTabStop> dummyTabStops;
+- openParagraph(WPX_PARAGRAPH_JUSTIFICATION_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, dummyTabStops, false, false);
+- closeParagraph();
+- }
+- #endif
+- mfSectionSpaceAfter = 0.0f;
++ mfSectionSpaceAfter = 0.0;
+ }
+
+ void DocumentCollector::openParagraph(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops)
+@@ -471,7 +546,7 @@ void DocumentCollector::openParagraph(const WPXPropertyList &propList, const WPX
+ WPXPropertyList *pPersistPropList = new WPXPropertyList(propList);
+ ParagraphStyle *pStyle = NULL;
+
+- if (mWriterDocumentState.mbFirstElement && mpCurrentContentElements == &mBodyElements)
++ 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
+@@ -483,26 +558,36 @@ void DocumentCollector::openParagraph(const WPXPropertyList &propList, const WPX
+ sName.sprintf("FS");
+
+ WPXString sParagraphHashKey("P|FS");
+- pPersistPropList->insert("style:master-page-name", "Page Style 1");
++ pPersistPropList->insert("style:master-page-name", "Page_Style_1");
+ pStyle = new ParagraphStyle(pPersistPropList, tabStops, sName);
+ mTextStyleHash[sParagraphHashKey] = pStyle;
+- mWriterDocumentState.mbFirstElement = false;
++ mWriterDocumentStates.top().mbFirstElement = false;
++ mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false;
+ }
+ else
+ {
+- if (mWriterDocumentState.mbTableCellOpened)
++ 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 (mWriterDocumentState.mbHeaderRow)
+- pPersistPropList->insert("style:parent-style-name", "Table Heading");
++ if (mWriterDocumentStates.top().mbHeaderRow)
++ pPersistPropList->insert("style:parent-style-name", "Table_Heading");
+ else
+- pPersistPropList->insert("style:parent-style-name", "Table Contents");
++ 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()) {
++ if (mTextStyleHash.find(sKey) == mTextStyleHash.end())
++ {
+ WPXString sName;
+ sName.sprintf("S%i", mTextStyleHash.size());
+
+@@ -519,12 +604,12 @@ void DocumentCollector::openParagraph(const WPXPropertyList &propList, const WPX
+ // create a document element corresponding to the paragraph, and append it to our list of document elements
+ TagOpenElement *pParagraphOpenElement = new TagOpenElement("text:p");
+ pParagraphOpenElement->addAttribute("text:style-name", pStyle->getName());
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pParagraphOpenElement));
++ mpCurrentContentElements->push_back(pParagraphOpenElement);
+ }
+
+ void DocumentCollector::closeParagraph()
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p")));
++ mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
+ }
+
+ void DocumentCollector::openSpan(const WPXPropertyList &propList)
+@@ -552,12 +637,12 @@ void DocumentCollector::openSpan(const WPXPropertyList &propList)
+ // create a document element corresponding to the paragraph, and append it to our list of document elements
+ TagOpenElement *pSpanOpenElement = new TagOpenElement("text:span");
+ pSpanOpenElement->addAttribute("text:style-name", sName.cstr());
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pSpanOpenElement));
++ mpCurrentContentElements->push_back(pSpanOpenElement);
+ }
+
+ void DocumentCollector::closeSpan()
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:span")));
++ mpCurrentContentElements->push_back(new TagCloseElement("text:span"));
+ }
+
+ void DocumentCollector::defineOrderedListLevel(const WPXPropertyList &propList)
+@@ -567,8 +652,8 @@ void DocumentCollector::defineOrderedListLevel(const WPXPropertyList &propList)
+ id = propList["libwpd:id"]->getInt();
+
+ OrderedListStyle *pOrderedListStyle = NULL;
+- if (mpCurrentListStyle && mpCurrentListStyle->getListID() == id)
+- pOrderedListStyle = static_cast<OrderedListStyle *>(mpCurrentListStyle); // FIXME: using a dynamic cast here causes oo to crash?!
++ 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
+@@ -576,27 +661,27 @@ void DocumentCollector::defineOrderedListLevel(const WPXPropertyList &propList)
+ // is starting a new list at level 1 (and only level 1)
+ if (pOrderedListStyle == NULL || pOrderedListStyle->getListID() != id ||
+ (propList["libwpd:level"] && propList["libwpd:level"]->getInt()==1 &&
+- (propList["text:start-value"] && (unsigned int)(propList["text:start-value"]->getInt()) != (miLastListNumber+1))))
++ (propList["text:start-value"] && propList["text:start-value"]->getInt() != static_cast<int>(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(), propList["libwpd:id"]->getInt());
+- mListStyles.push_back(static_cast<ListStyle *>(pOrderedListStyle));
+- mpCurrentListStyle = static_cast<ListStyle *>(pOrderedListStyle);
+- mbListContinueNumbering = false;
+- miLastListNumber = 0;
++ pOrderedListStyle = new OrderedListStyle(sName.cstr(), id);
++ mListStyles.push_back(pOrderedListStyle);
++ mWriterListStates.top().mpCurrentListStyle = pOrderedListStyle;
++ mWriterListStates.top().mbListContinueNumbering = false;
++ mWriterListStates.top().miLastListNumber = 0;
+ }
+ else
+- mbListContinueNumbering = true;
++ 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++)
++ for (std::vector<ListStyle *>::iterator iterOrderedListStyles = mListStyles.begin(); iterOrderedListStyles != mListStyles.end(); ++iterOrderedListStyles)
+ {
+- if ((* iterOrderedListStyles)->getListID() == propList["libwpd:id"]->getInt())
++ if ((* iterOrderedListStyles)->getListID() == id)
+ (* iterOrderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList);
+ }
+ }
+@@ -608,106 +693,114 @@ void DocumentCollector::defineUnorderedListLevel(const WPXPropertyList &propList
+ id = propList["libwpd:id"]->getInt();
+
+ UnorderedListStyle *pUnorderedListStyle = NULL;
+- if (mpCurrentListStyle && mpCurrentListStyle->getListID() == id)
+- pUnorderedListStyle = static_cast<UnorderedListStyle *>(mpCurrentListStyle); // FIXME: using a dynamic cast here causes oo to crash?!
++ if (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(static_cast<ListStyle *>(pUnorderedListStyle));
+- mpCurrentListStyle = static_cast<ListStyle *>(pUnorderedListStyle);
++ 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++)
++ for (std::vector<ListStyle *>::iterator iterUnorderedListStyles = mListStyles.begin(); iterUnorderedListStyles != mListStyles.end(); ++iterUnorderedListStyles)
+ {
+- if ((* iterUnorderedListStyles)->getListID() == propList["libwpd:id"]->getInt())
++ if ((* iterUnorderedListStyles)->getListID() == id)
+ (* iterUnorderedListStyles)->updateListLevel((propList["libwpd:level"]->getInt() - 1), propList);
+ }
+ }
+
+ void DocumentCollector::openOrderedListLevel(const WPXPropertyList & /* propList */)
+ {
+- miCurrentListLevel++;
+- TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:ordered-list");
++ if (mWriterListStates.top().mbListElementParagraphOpened)
++ {
++ mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
++ mWriterListStates.top().mbListElementParagraphOpened = false;
++ }
++ TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:list");
+ _openListLevel(pListLevelOpenElement);
+
+- if (mbListContinueNumbering) {
++ if (mWriterListStates.top().mbListContinueNumbering) {
+ pListLevelOpenElement->addAttribute("text:continue-numbering", "true");
+ }
+
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pListLevelOpenElement));
++ mpCurrentContentElements->push_back(pListLevelOpenElement);
+ }
+
+ void DocumentCollector::openUnorderedListLevel(const WPXPropertyList & /* propList */)
+ {
+- miCurrentListLevel++;
+- TagOpenElement *pListLevelOpenElement = new TagOpenElement("text:unordered-list");
++ 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(static_cast<DocumentElement *>(pListLevelOpenElement));
++ mpCurrentContentElements->push_back(pListLevelOpenElement);
+ }
+
+ void DocumentCollector::_openListLevel(TagOpenElement *pListLevelOpenElement)
+ {
+- if (!mbListElementOpened && miCurrentListLevel > 1)
+- {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:list-item")));
+- }
+- else if (mbListElementParagraphOpened)
++ if (!mWriterListStates.top().mbListElementOpened.empty() &&
++ !mWriterListStates.top().mbListElementOpened.top())
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p")));
+- mbListElementParagraphOpened = false;
++ mpCurrentContentElements->push_back(new TagOpenElement("text:list-item"));
++ mWriterListStates.top().mbListElementOpened.top() = true;
+ }
+
+- if (miCurrentListLevel==1) {
+- pListLevelOpenElement->addAttribute("text:style-name", mpCurrentListStyle->getName());
++ mWriterListStates.top().mbListElementOpened.push(false);
++ if (mWriterListStates.top().mbListElementOpened.size() == 1) {
++ pListLevelOpenElement->addAttribute("text:style-name", mWriterListStates.top().mpCurrentListStyle->getName());
+ }
+-
+- mbListElementOpened = false;
+ }
+
+ void DocumentCollector::closeOrderedListLevel()
+ {
+- _closeListLevel("ordered-list");
++ _closeListLevel();
+ }
+
+ void DocumentCollector::closeUnorderedListLevel()
+ {
+- _closeListLevel("unordered-list");
++ _closeListLevel();
+ }
+
+-void DocumentCollector::_closeListLevel(const char *szListType)
++void DocumentCollector::_closeListLevel()
+ {
+- if (mbListElementOpened)
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item")));
+-
+- miCurrentListLevel--;
++ if (mWriterListStates.top().mbListElementOpened.top())
++ {
++ mpCurrentContentElements->push_back(new TagCloseElement("text:list-item"));
++ mWriterListStates.top().mbListElementOpened.top() = false;
++ }
+
+- WPXString sCloseElement;
+- sCloseElement.sprintf("text:%s", szListType);
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement(sCloseElement.cstr())));
++ mpCurrentContentElements->push_back(new TagCloseElement("text:list"));
+
+- if (miCurrentListLevel > 0)
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item")));
+- mbListElementOpened = false;
++ if (!mWriterListStates.top().mbListElementOpened.empty())
++ {
++ mWriterListStates.top().mbListElementOpened.pop();
++ }
+ }
+
+ void DocumentCollector::openListElement(const WPXPropertyList &propList, const WPXPropertyListVector &tabStops)
+ {
+- miLastListLevel = miCurrentListLevel;
+- if (miCurrentListLevel == 1)
+- miLastListNumber++;
++ mWriterListStates.top().miLastListLevel = mWriterListStates.top().miCurrentListLevel;
++ if (mWriterListStates.top().miCurrentListLevel == 1)
++ mWriterListStates.top().miLastListNumber++;
+
+- if (mbListElementOpened)
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:list-item")));
++ 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", mpCurrentListStyle->getName());
++ pPersistPropList->insert("style:list-style-name", mWriterListStates.top().mpCurrentListStyle->getName());
+ pPersistPropList->insert("style:parent-style-name", "Standard");
+
+ WPXString sKey = getParagraphStyleKey(*pPersistPropList, tabStops);
+@@ -727,17 +820,18 @@ void DocumentCollector::openListElement(const WPXPropertyList &propList, const W
+ delete pPersistPropList;
+ }
+
+- TagOpenElement *pOpenListElement = new TagOpenElement("text:list-item");
+- TagOpenElement *pOpenListElementParagraph = new TagOpenElement("text:p");
++ 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);
+
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenListElement));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pOpenListElementParagraph));
++ if (mpCurrentContentElements == &mBodyElements)
++ mWriterDocumentStates.top().mbFirstParagraphInPageSpan = false;
+
+- mbListElementOpened = true;
+- mbListElementParagraphOpened = true;
+- mbListContinueNumbering = false;
++ mWriterListStates.top().mbListElementOpened.top() = true;
++ mWriterListStates.top().mbListElementParagraphOpened = true;
++ mWriterListStates.top().mbListContinueNumbering = false;
+ }
+
+ void DocumentCollector::closeListElement()
+@@ -746,69 +840,100 @@ void DocumentCollector::closeListElement()
+ // could contain another list level in OOo's implementation of lists). that is done in the closeListLevel
+ // code (or when we open another list element)
+
+- if (mbListElementParagraphOpened)
++ if (mWriterListStates.top().mbListElementParagraphOpened)
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:p")));
+- mbListElementParagraphOpened = false;
++ mpCurrentContentElements->push_back(new TagCloseElement("text:p"));
++ mWriterListStates.top().mbListElementParagraphOpened = false;
+ }
+ }
+
+ void DocumentCollector::openFootnote(const WPXPropertyList &propList)
+ {
+- TagOpenElement *pOpenFootNote = new TagOpenElement("text:footnote");
++ 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(static_cast<DocumentElement *>(pOpenFootNote));
++ mpCurrentContentElements->push_back(pOpenFootNote);
+
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:footnote-citation")));
++ mpCurrentContentElements->push_back(new TagOpenElement("text:note-citation"));
+ if (propList["libwpd:number"])
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new CharDataElement(propList["libwpd:number"]->getStr().cstr())));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote-citation")));
++ mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr()));
++ mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation"));
+
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:footnote-body")));
++ mpCurrentContentElements->push_back(new TagOpenElement("text:note-body"));
+
+- mWriterDocumentState.mbInNote = true;
++ mWriterDocumentStates.top().mbInNote = true;
+ }
+
+ void DocumentCollector::closeFootnote()
+ {
+- mWriterDocumentState.mbInNote = false;
++ mWriterDocumentStates.top().mbInNote = false;
++ if (mWriterListStates.size() > 1)
++ mWriterListStates.pop();
+
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote-body")));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:footnote")));
++ mpCurrentContentElements->push_back(new TagCloseElement("text:note-body"));
++ mpCurrentContentElements->push_back(new TagCloseElement("text:note"));
+ }
+
+ void DocumentCollector::openEndnote(const WPXPropertyList &propList)
+ {
+- TagOpenElement *pOpenEndNote = new TagOpenElement("text:endnote");
++ 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(static_cast<DocumentElement *>(pOpenEndNote));
++ mpCurrentContentElements->push_back(pOpenEndNote);
+
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:endnote-citation")));
++ mpCurrentContentElements->push_back(new TagOpenElement("text:note-citation"));
+ if (propList["libwpd:number"])
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new CharDataElement(propList["libwpd:number"]->getStr().cstr())));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote-citation")));
++ mpCurrentContentElements->push_back(new CharDataElement(propList["libwpd:number"]->getStr().cstr()));
++ mpCurrentContentElements->push_back(new TagCloseElement("text:note-citation"));
+
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:endnote-body")));
++ mpCurrentContentElements->push_back(new TagOpenElement("text:note-body"));
+
++ mWriterDocumentStates.top().mbInNote = true;
+ }
++
+ void DocumentCollector::closeEndnote()
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote-body")));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:endnote")));
++ 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());
+
+@@ -817,11 +942,11 @@ void DocumentCollector::openTable(const WPXPropertyList &propList, const WPXProp
+ // WLACH_REFACTORING: characterize this behaviour, probably should nip it at the bud within libwpd
+ TableStyle *pTableStyle = new TableStyle(propList, columns, sTableName.cstr());
+
+- if (mWriterDocumentState.mbFirstElement && mpCurrentContentElements == &mBodyElements)
++ if (mWriterDocumentStates.top().mbFirstElement && mpCurrentContentElements == &mBodyElements)
+ {
+- WPXString sMasterPageName("Page Style 1");
++ WPXString sMasterPageName("Page_Style_1");
+ pTableStyle->setMasterPageName(sMasterPageName);
+- mWriterDocumentState.mbFirstElement = false;
++ mWriterDocumentStates.top().mbFirstElement = false;
+ }
+
+ mTableStyles.push_back(pTableStyle);
+@@ -832,7 +957,7 @@ void DocumentCollector::openTable(const WPXPropertyList &propList, const WPXProp
+
+ pTableOpenElement->addAttribute("table:name", sTableName.cstr());
+ pTableOpenElement->addAttribute("table:style-name", sTableName.cstr());
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableOpenElement));
++ mpCurrentContentElements->push_back(pTableOpenElement);
+
+ for (int i=0; i<pTableStyle->getNumColumns(); i++)
+ {
+@@ -846,13 +971,16 @@ void DocumentCollector::openTable(const WPXPropertyList &propList, const WPXProp
+ 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(static_cast<DocumentElement *>(new TagOpenElement("table:table-header-rows")));
+- mWriterDocumentState.mbHeaderRow = true;
++ mpCurrentContentElements->push_back(new TagOpenElement("table:table-header-rows"));
++ mWriterDocumentStates.top().mbHeaderRow = true;
+ }
+
+ WPXString sTableRowStyleName;
+@@ -862,21 +990,27 @@ void DocumentCollector::openTableRow(const WPXPropertyList &propList)
+
+ TagOpenElement *pTableRowOpenElement = new TagOpenElement("table:table-row");
+ pTableRowOpenElement->addAttribute("table:style-name", sTableRowStyleName);
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableRowOpenElement));
++ mpCurrentContentElements->push_back(pTableRowOpenElement);
++ }
+ }
+
+ void DocumentCollector::closeTableRow()
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-row")));
+- if (mWriterDocumentState.mbHeaderRow)
++ if (!mWriterDocumentStates.top().mbInNote)
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-header-rows")));
+- mWriterDocumentState.mbHeaderRow = false;
++ 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());
+@@ -890,39 +1024,71 @@ void DocumentCollector::openTableCell(const WPXPropertyList &propList)
+ if (propList["table:number-rows-spanned"])
+ pTableCellOpenElement->addAttribute("table:number-rows-spanned",
+ propList["table:number-rows-spanned"]->getStr().cstr());
+- pTableCellOpenElement->addAttribute("table:value-type", "string");
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(pTableCellOpenElement));
++ mpCurrentContentElements->push_back(pTableCellOpenElement);
+
+- mWriterDocumentState.mbTableCellOpened = true;
++ mWriterDocumentStates.top().mbTableCellOpened = true;
++ }
+ }
+
+ void DocumentCollector::closeTableCell()
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table-cell")));
+- mWriterDocumentState.mbTableCellOpened = false;
++ if (!mWriterDocumentStates.top().mbInNote)
++ {
++ mpCurrentContentElements->push_back(new TagCloseElement("table:table-cell"));
++ mWriterDocumentStates.top().mbTableCellOpened = false;
++ }
+ }
+
+ void DocumentCollector::insertCoveredTableCell(const WPXPropertyList & /* propList */)
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("table:covered-table-cell")));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:covered-table-cell")));
++ 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()
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("table:table")));
++ if (!mWriterDocumentStates.top().mbInNote)
++ {
++ mpCurrentContentElements->push_back(new TagCloseElement("table:table"));
++ }
+ }
+
++
+ void DocumentCollector::insertTab()
+ {
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagOpenElement("text:tab-stop")));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:tab-stop")));
++ 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(static_cast<DocumentElement *>(new TagOpenElement("text:line-break")));
+- mpCurrentContentElements->push_back(static_cast<DocumentElement *>(new TagCloseElement("text:line-break")));
++ 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)
+@@ -931,4 +1097,221 @@ void DocumentCollector::insertText(const WPXString &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
+index 218cc68..6d0d353 100644
+--- a/writerperfect/source/filter/DocumentCollector.hxx
++++ b/writerperfect/source/filter/DocumentCollector.hxx
+@@ -46,8 +46,9 @@
+ #include <stack>
+ #include <string.h>
+
++#include "DocumentHandlerInterface.hxx"
++
+ class DocumentElement;
+-class DocumentHandler;
+ class TagOpenElement;
+ class FontStyle;
+ class ListStyle;
+@@ -64,11 +65,29 @@ 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 };
+@@ -81,20 +100,23 @@ struct ltstr
+ }
+ };
+
+-class DocumentCollector : public WPXHLListenerImpl
++class DocumentCollector : public WPXDocumentInterface
+ {
+ public:
+- DocumentCollector(WPSInputStream *pInput, DocumentHandler *pHandler);
++ DocumentCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler);
+ virtual ~DocumentCollector();
+ bool filter();
+
+- virtual void setDocumentMetaData(const WPXPropertyList & /* propList */) {}
++ // 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();
+
+@@ -103,16 +125,19 @@ public:
+ 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);
+@@ -127,6 +152,10 @@ public:
+ 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);
+@@ -135,25 +164,34 @@ public:
+ virtual void closeTableCell();
+ virtual void insertCoveredTableCell(const WPXPropertyList &propList);
+ virtual void closeTable();
+- virtual bool parseSourceDocument(WPSInputStream &input) = 0;
++
++ 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(DocumentHandler *pHandler);
+- void _writeDefaultStyles(DocumentHandler *pHandler);
+- void _writeMasterPages(DocumentHandler *pHandler);
+- void _writePageMasters(DocumentHandler *pHandler);
++ 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(const char *szListType);
++ void _closeListLevel();
+
+- WPSInputStream *mpInput;
+- DocumentHandler *mpHandler;
++ WPXInputStream *mpInput;
++ DocumentHandlerInterface *mpHandler;
+ bool mbUsed; // whether or not it has been before (you can only use me once!)
+
+- WriterDocumentState mWriterDocumentState;
++ std::stack<WriterDocumentState> mWriterDocumentStates;
++
++ std::stack<WriterListState> mWriterListStates;
+
+ // paragraph styles
+ std::map<WPXString, ParagraphStyle *, ltstr> mTextStyleHash;
+@@ -166,11 +204,19 @@ private:
+
+ // section styles
+ std::vector<SectionStyle *> mSectionStyles;
+- float mfSectionSpaceAfter;
++ double 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;
+
+@@ -186,18 +232,18 @@ private:
+ PageSpan *mpCurrentPageSpan;
+ int miNumPageStyles;
+
+- // list styles / state
+- ListStyle *mpCurrentListStyle;
+- unsigned int miCurrentListLevel;
+- unsigned int miLastListLevel;
+- unsigned int miLastListNumber;
++ // list styles
+ std::vector<ListStyle *> mListStyles;
+- bool mbListContinueNumbering;
+- bool mbListElementOpened;
+- bool mbListElementParagraphOpened;
++
++ // object state
++ unsigned miObjectNumber;
+
+ // table state
+ TableStyle *mpCurrentTableStyle;
++
++ const bool mbIsFlatXML;
++
++ const char * mpPassword;
+ };
+
+ #endif
+diff --git a/writerperfect/source/filter/DocumentElement.cxx b/writerperfect/source/filter/DocumentElement.cxx
+index 9948c38..18380e1 100644
+--- a/writerperfect/source/filter/DocumentElement.cxx
++++ b/writerperfect/source/filter/DocumentElement.cxx
+@@ -27,6 +27,7 @@
+ */
+
+ #include "DocumentElement.hxx"
++#include "DocumentHandler.hxx"
+ #include "FilterInternal.hxx"
+ #include <string.h>
+
+@@ -37,7 +38,7 @@ void TagElement::print() const
+ WRITER_DEBUG_MSG(("%s\n", msTagName.cstr()));
+ }
+
+-void TagOpenElement::write(DocumentHandler *pHandler) const
++void TagOpenElement::write(DocumentHandlerInterface *pHandler) const
+ {
+ pHandler->startElement(getTagName().cstr(), maAttrList);
+ }
+@@ -52,14 +53,14 @@ void TagOpenElement::addAttribute(const char *szAttributeName, const WPXString &
+ maAttrList.insert(szAttributeName, sAttributeValue);
+ }
+
+-void TagCloseElement::write(DocumentHandler *pHandler) const
++void TagCloseElement::write(DocumentHandlerInterface *pHandler) const
+ {
+ WRITER_DEBUG_MSG(("TagCloseElement: write (%s)\n", getTagName().cstr()));
+
+ pHandler->endElement(getTagName().cstr());
+ }
+
+-void CharDataElement::write(DocumentHandler *pHandler) const
++void CharDataElement::write(DocumentHandlerInterface *pHandler) const
+ {
+ WRITER_DEBUG_MSG(("TextElement: write\n"));
+ pHandler->characters(msData);
+@@ -72,8 +73,10 @@ TextElement::TextElement(const WPXString & sTextBuf) :
+
+ // write: writes a text run, appropriately converting spaces to <text:s>
+ // elements
+-void TextElement::write(DocumentHandler *pHandler) const
++void TextElement::write(DocumentHandlerInterface *pHandler) const
+ {
++ if (msTextBuf.len() <= 0)
++ return;
+ WPXPropertyList xBlankAttrList;
+
+ WPXString sTemp;
+diff --git a/writerperfect/source/filter/DocumentElement.hxx b/writerperfect/source/filter/DocumentElement.hxx
+index 3481359..cb84777 100644
+--- a/writerperfect/source/filter/DocumentElement.hxx
++++ b/writerperfect/source/filter/DocumentElement.hxx
+@@ -28,30 +28,25 @@
+
+ #ifndef _DOCUMENTELEMENT_H
+ #define _DOCUMENTELEMENT_H
+-#if defined _MSC_VER
+-#pragma warning( push, 1 )
+-#endif
+ #include <libwpd/libwpd.h>
+ #include <libwpd/WPXProperty.h>
+ #include <libwpd/WPXString.h>
+-#if defined _MSC_VER
+-#pragma warning( pop )
+-#endif
+ #include <vector>
+
+-#include "DocumentHandler.hxx"
++#include "DocumentHandlerInterface.hxx"
+
+ class DocumentElement
+ {
+ public:
+ virtual ~DocumentElement() {}
+- virtual void write(DocumentHandler *pHandler) const = 0;
++ 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;
+@@ -63,9 +58,9 @@ class TagOpenElement : public TagElement
+ {
+ public:
+ TagOpenElement(const char *szTagName) : TagElement(szTagName) {}
+- ~TagOpenElement() {}
++ virtual ~TagOpenElement() {}
+ void addAttribute(const char *szAttributeName, const WPXString &sAttributeValue);
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ virtual void print () const;
+ private:
+ WPXPropertyList maAttrList;
+@@ -75,14 +70,16 @@ class TagCloseElement : public TagElement
+ {
+ public:
+ TagCloseElement(const char *szTagName) : TagElement(szTagName) {}
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual ~TagCloseElement() {}
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ };
+
+ class CharDataElement : public DocumentElement
+ {
+ public:
+ CharDataElement(const char *sData) : DocumentElement(), msData(sData) {}
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual ~CharDataElement() {}
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ private:
+ WPXString msData;
+ };
+@@ -91,7 +88,8 @@ class TextElement : public DocumentElement
+ {
+ public:
+ TextElement(const WPXString & sTextBuf);
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual ~TextElement() {}
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+
+ private:
+ WPXString msTextBuf;
+diff --git a/writerperfect/source/filter/DocumentHandler.cxx b/writerperfect/source/filter/DocumentHandler.cxx
+index b3d247d..ab16391 100644
+--- a/writerperfect/source/filter/DocumentHandler.cxx
++++ b/writerperfect/source/filter/DocumentHandler.cxx
+@@ -29,6 +29,8 @@
+
+ #include <xmloff/attrlist.hxx>
+
++// #define DEBUG_XML 1
++
+ using namespace ::rtl;
+ using rtl::OUString;
+
+@@ -41,19 +43,19 @@ DocumentHandler::DocumentHandler(Reference < XDocumentHandler > &xHandler) :
+
+ void DocumentHandler::startDocument()
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::startDocument\n"));
+ mxHandler->startDocument();
+ }
+
+ void DocumentHandler::endDocument()
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::endDocument\n"));
+ mxHandler->endDocument();
+ }
+
+ void DocumentHandler::startElement(const char *psName, const WPXPropertyList &xPropList)
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::startElement\n"));
++#ifdef DEBUG_XML
++ printf("<%s", psName);
++#endif
+ SvXMLAttributeList *pAttrList = new SvXMLAttributeList();
+ Reference < XAttributeList > xAttrList(pAttrList);
+ WPXPropertyList::Iter i(xPropList);
+@@ -61,23 +63,36 @@ void DocumentHandler::startElement(const char *psName, const WPXPropertyList &xP
+ {
+ // 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)
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::endElement\n"));
++#ifdef DEBUG_XML
++ printf("</%s>", psName);
++#endif
+ mxHandler->endElement(OUString::createFromAscii(psName));
+ }
+
+ void DocumentHandler::characters(const WPXString &sCharacters)
+ {
+- WRITER_DEBUG_MSG(("DocumentHandler::characters\n"));
+ 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);
+ }
+
+diff --git a/writerperfect/source/filter/DocumentHandler.hxx b/writerperfect/source/filter/DocumentHandler.hxx
+index 82a8213..249f64f 100644
+--- a/writerperfect/source/filter/DocumentHandler.hxx
++++ b/writerperfect/source/filter/DocumentHandler.hxx
+@@ -12,10 +12,12 @@
+ #pragma warning( pop )
+ #endif
+
++#include "DocumentHandlerInterface.hxx"
++
+ using com::sun::star::uno::Reference;
+ using com::sun::star::xml::sax::XDocumentHandler;
+
+-class DocumentHandler
++class DocumentHandler: public DocumentHandlerInterface
+ {
+ public:
+ DocumentHandler(Reference < XDocumentHandler > &xHandler);
+diff --git a/writerperfect/source/filter/DocumentHandlerInterface.hxx b/writerperfect/source/filter/DocumentHandlerInterface.hxx
+new file mode 100644
+index 0000000..0e9ee56
+--- /dev/null
++++ b/writerperfect/source/filter/DocumentHandlerInterface.hxx
+@@ -0,0 +1,48 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/*
++ * Copyright (C) 2004 William Lachance (wlach at 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 at 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
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/FilterInternal.hxx b/writerperfect/source/filter/FilterInternal.hxx
+index 4239a57..fcac328 100644
+--- a/writerperfect/source/filter/FilterInternal.hxx
++++ b/writerperfect/source/filter/FilterInternal.hxx
+@@ -2,7 +2,7 @@
+ /* FilterInternal: Debugging information
+ *
+ * Copyright (C) 2002-2003 William Lachance (william.lachance at 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
+@@ -20,6 +20,10 @@
+ * 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
+@@ -27,8 +31,10 @@
+ #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
++const double fDefaultSideMargin = 1.0; // inches
++const double fDefaultPageWidth = 8.5; // inches (OOo required default: we will handle this later)
++const double fDefaultPageHeight = 11.0; // inches
++
++#endif
+
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/FontStyle.cxx b/writerperfect/source/filter/FontStyle.cxx
+index 6e1214a..c945407 100644
+--- a/writerperfect/source/filter/FontStyle.cxx
++++ b/writerperfect/source/filter/FontStyle.cxx
+@@ -30,7 +30,7 @@
+ #include "DocumentElement.hxx"
+
+ FontStyle::FontStyle(const char *psName, const char *psFontFamily) : Style(psName),
+- msFontFamily(psFontFamily),
++ msFontFamily(psFontFamily, true),
+ msFontPitch(IMP_DEFAULT_FONT_PITCH)
+ {
+ }
+@@ -39,14 +39,13 @@ FontStyle::~FontStyle()
+ {
+ }
+
+-void FontStyle::write(DocumentHandler *pHandler) const
++void FontStyle::write(DocumentHandlerInterface *pHandler) const
+ {
+- TagOpenElement styleOpen("style:font-decl");
++ TagOpenElement styleOpen("style:font-face");
+ styleOpen.addAttribute("style:name", getName());
+- styleOpen.addAttribute("fo:font-family", msFontFamily);
+- styleOpen.addAttribute("style:font-pitch", msFontPitch);
++ styleOpen.addAttribute("svg:font-family", msFontFamily);
+ styleOpen.write(pHandler);
+- TagCloseElement styleClose("style:font-decl");
++ TagCloseElement styleClose("style:font-face");
+ styleClose.write(pHandler);
+ }
+
+diff --git a/writerperfect/source/filter/FontStyle.hxx b/writerperfect/source/filter/FontStyle.hxx
+index 8d16b13..aec430d 100644
+--- a/writerperfect/source/filter/FontStyle.hxx
++++ b/writerperfect/source/filter/FontStyle.hxx
+@@ -27,23 +27,18 @@
+ */
+ #ifndef _FONTSTYLE_H
+ #define _FONTSTYLE_H
+-#if defined _MSC_VER
+-#pragma warning( push, 1 )
+-#endif
+ #include <libwpd/libwpd.h>
+-#if defined _MSC_VER
+-#pragma warning( pop )
+-#endif
+
+ #include "Style.hxx"
+ #include "WriterProperties.hxx"
++#include "DocumentHandlerInterface.hxx"
+
+ class FontStyle : public Style
+ {
+ public:
+ FontStyle(const char *psName, const char *psFontFamily);
+ ~FontStyle();
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ const WPXString &getFontFamily() const { return msFontFamily; }
+
+ private:
+diff --git a/writerperfect/source/filter/GraphicsStyle.cxx b/writerperfect/source/filter/GraphicsStyle.cxx
+new file mode 100644
+index 0000000..abca6a8
+--- /dev/null
++++ b/writerperfect/source/filter/GraphicsStyle.cxx
+@@ -0,0 +1,43 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* GraphicsStyle:
++ *
++ * Copyright (C) 2007 Fridrich Strba .strba at 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
++{
++}
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/GraphicsStyle.hxx b/writerperfect/source/filter/GraphicsStyle.hxx
+new file mode 100644
+index 0000000..bef9b54
+--- /dev/null
++++ b/writerperfect/source/filter/GraphicsStyle.hxx
+@@ -0,0 +1,43 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* GraphicsStyle:
++ *
++ * Copyright (C) 2007 Fridrich Strba .strba at 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
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/InternalHandler.cxx b/writerperfect/source/filter/InternalHandler.cxx
+new file mode 100644
+index 0000000..a020827
+--- /dev/null
++++ b/writerperfect/source/filter/InternalHandler.cxx
+@@ -0,0 +1,57 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/*
++ * Copyright (C) 2007 Fridrich Strba .strba at 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()));
++}
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/InternalHandler.hxx b/writerperfect/source/filter/InternalHandler.hxx
+new file mode 100644
+index 0000000..0869ad1
+--- /dev/null
++++ b/writerperfect/source/filter/InternalHandler.hxx
+@@ -0,0 +1,49 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/*
++ * Copyright (C) 2007 Fridrich Strba .strba at 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
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/ListStyle.cxx b/writerperfect/source/filter/ListStyle.cxx
+index 8a4aa1e..a5c1780 100644
+--- a/writerperfect/source/filter/ListStyle.cxx
++++ b/writerperfect/source/filter/ListStyle.cxx
+@@ -1,9 +1,9 @@
+ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/* ListStyle: Stores (and writes) list-based information that is
++/* 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 at 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
+@@ -22,54 +22,66 @@
+ *
+ */
+
+-/* "This product is not manufactured, approved, or supported by
++/* "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) :
++OrderedListLevelStyle::OrderedListLevelStyle(const WPXPropertyList &xPropList) :
+ mPropList(xPropList)
+ {
+ }
+
+-void OrderedListStyle::updateListLevel(const int iLevel, const WPXPropertyList &xPropList)
+-{
++void OrderedListStyle::updateListLevel(const int iLevel, const WPXPropertyList &xPropList)
++{
+ if (iLevel < 0)
+ return;
+ if (!isListLevelDefined(iLevel))
+ setListLevel(iLevel, new OrderedListLevelStyle(xPropList));
+ }
+
+-void OrderedListLevelStyle::write(DocumentHandler *pHandler, int iLevel) const
++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");
++ listLevelStyleOpen.addAttribute("text:style-name", "Numbering_Symbols");
+ if (mPropList["style:num-prefix"])
+- listLevelStyleOpen.addAttribute("style:num-prefix", mPropList["style:num-prefix"]->getStr());
++ {
++ WPXString sEscapedString(mPropList["style:num-prefix"]->getStr(), true);
++ listLevelStyleOpen.addAttribute("style:num-prefix", sEscapedString);
++ }
+ if (mPropList["style:num-suffix"])
+- listLevelStyleOpen.addAttribute("style:num-suffix", mPropList["style:num-suffix"]->getStr());
++ {
++ 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:properties");
+- if (mPropList["text:space-before"])
++ TagOpenElement stylePropertiesOpen("style:list-level-properties");
++ if (mPropList["text:space-before"] && mPropList["text:space-before"]->getDouble() > 0.0)
+ stylePropertiesOpen.addAttribute("text:space-before", mPropList["text:space-before"]->getStr());
+- if (mPropList["text:min-label-width"])
++ if (mPropList["text:min-label-width"] && mPropList["text:min-label-width"]->getDouble() > 0.0)
+ stylePropertiesOpen.addAttribute("text:min-label-width", mPropList["text:min-label-width"]->getStr());
+- if (mPropList["text:min-label-distance"])
++ if (mPropList["text:min-label-distance"] && mPropList["text:min-label-distance"]->getDouble() > 0.0)
+ stylePropertiesOpen.addAttribute("text:min-label-distance", mPropList["text:min-label-distance"]->getStr());
+ stylePropertiesOpen.write(pHandler);
+
+- pHandler->endElement("style:properties");
++ pHandler->endElement("style:list-level-properties");
+ pHandler->endElement("text:list-level-style-number");
+ }
+
+@@ -78,37 +90,46 @@ UnorderedListLevelStyle::UnorderedListLevelStyle(const WPXPropertyList &xPropLis
+ {
+ }
+
+-void UnorderedListStyle::updateListLevel(const int iLevel, const WPXPropertyList &xPropList)
+-{
++void UnorderedListStyle::updateListLevel(const int iLevel, const WPXPropertyList &xPropList)
++{
+ if (iLevel < 0)
+ return;
+ if (!isListLevelDefined(iLevel))
+ setListLevel(iLevel, new UnorderedListLevelStyle(xPropList));
+ }
+
+-void UnorderedListLevelStyle::write(DocumentHandler *pHandler, int iLevel) const
++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");
+- listLevelStyleOpen.addAttribute("style:num-suffice", ".");
+- if (mPropList["text:bullet-char"])
+- listLevelStyleOpen.addAttribute("text:bullet-char", mPropList["text:bullet-char"]->getStr());
++ 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:properties");
+- if (mPropList["text:space-before"])
++ TagOpenElement stylePropertiesOpen("style:list-level-properties");
++ if (mPropList["text:space-before"] && mPropList["text:space-before"]->getDouble() > 0.0)
+ stylePropertiesOpen.addAttribute("text:space-before", mPropList["text:space-before"]->getStr());
+- if (mPropList["text:min-label-width"])
++ if (mPropList["text:min-label-width"] && mPropList["text:min-label-width"]->getDouble() > 0.0)
+ stylePropertiesOpen.addAttribute("text:min-label-width", mPropList["text:min-label-width"]->getStr());
+- if (mPropList["text:min-label-distance"])
++ if (mPropList["text:min-label-distance"] && mPropList["text:min-label-distance"]->getDouble() > 0.0)
+ stylePropertiesOpen.addAttribute("text:min-label-distance", mPropList["text:min-label-distance"]->getStr());
+ stylePropertiesOpen.addAttribute("style:font-name", "OpenSymbol");
+ stylePropertiesOpen.write(pHandler);
+
+- pHandler->endElement("style:properties");
++ pHandler->endElement("style:list-level-properties");
+ pHandler->endElement("text:list-level-style-bullet");
+ }
+
+@@ -118,7 +139,7 @@ ListStyle::ListStyle(const char *psName, const int iListID) :
+ {
+ for (int i=0; i<WP6_NUM_LIST_LEVELS; i++)
+ mppListLevels[i] = NULL;
+-
++
+ }
+
+ ListStyle::~ListStyle()
+@@ -132,29 +153,29 @@ ListStyle::~ListStyle()
+
+ bool ListStyle::isListLevelDefined(int iLevel) const
+ {
+- if (mppListLevels[iLevel] == NULL)
++ 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.
++ // 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)
++ if (mppListLevels[iLevel] == NULL)
+ mppListLevels[iLevel] = iListLevelStyle;
+ }
+
+-void ListStyle::write(DocumentHandler *pHandler) const
++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)
++ if (mppListLevels[i] != NULL)
+ mppListLevels[i]->write(pHandler, i);
+ }
+
+diff --git a/writerperfect/source/filter/ListStyle.hxx b/writerperfect/source/filter/ListStyle.hxx
+index c354934..cbba20a 100644
+--- a/writerperfect/source/filter/ListStyle.hxx
++++ b/writerperfect/source/filter/ListStyle.hxx
+@@ -27,18 +27,13 @@
+ */
+ #ifndef _LISTSTYLE_H
+ #define _LISTSTYLE_H
+-#if defined _MSC_VER
+-#pragma warning( push, 1 )
+-#endif
+ #include <libwpd/libwpd.h>
+-#if defined _MSC_VER
+-#pragma warning( pop )
+-#endif
+
+ #define WP6_NUM_LIST_LEVELS 8 // see WP6FileStructure.h (we shouldn't need to reference this)
+
+ #include "Style.hxx"
+ #include "WriterProperties.hxx"
++#include "DocumentHandlerInterface.hxx"
+
+ class DocumentElement;
+
+@@ -46,14 +41,14 @@ class ListLevelStyle
+ {
+ public:
+ virtual ~ListLevelStyle() {};
+- virtual void write(DocumentHandler *pHandler, int iLevel) const = 0;
++ virtual void write(DocumentHandlerInterface *pHandler, int iLevel) const = 0;
+ };
+
+ class OrderedListLevelStyle : public ListLevelStyle
+ {
+ public:
+ OrderedListLevelStyle(const WPXPropertyList &xPropList);
+- void write(DocumentHandler *pHandler, int iLevel) const;
++ void write(DocumentHandlerInterface *pHandler, int iLevel) const;
+ private:
+ WPXPropertyList mPropList;
+ };
+@@ -62,7 +57,7 @@ class UnorderedListLevelStyle : public ListLevelStyle
+ {
+ public:
+ UnorderedListLevelStyle(const WPXPropertyList &xPropList);
+- void write(DocumentHandler *pHandler, int iLevel) const;
++ void write(DocumentHandlerInterface *pHandler, int iLevel) const;
+ private:
+ WPXPropertyList mPropList;
+ };
+@@ -73,7 +68,7 @@ public:
+ ListStyle(const char *psName, const int iListID);
+ virtual ~ListStyle();
+ virtual void updateListLevel(const int iLevel, const WPXPropertyList &xPropList) = 0;
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ int getListID() const { return miListID; }
+ bool isListLevelDefined(int iLevel) const;
+
+diff --git a/writerperfect/source/filter/OdgExporter.cxx b/writerperfect/source/filter/OdgExporter.cxx
+new file mode 100644
+index 0000000..c111cdb
+--- /dev/null
++++ b/writerperfect/source/filter/OdgExporter.cxx
+@@ -0,0 +1,650 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* libwpg
++ * Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
++ * Copyright (C) 2006 Fridrich Strba (fridrich.strba at 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: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());
++}
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/OdgExporter.hxx b/writerperfect/source/filter/OdgExporter.hxx
+new file mode 100644
+index 0000000..f3ff92b
+--- /dev/null
++++ b/writerperfect/source/filter/OdgExporter.hxx
+@@ -0,0 +1,93 @@
++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
++/* libwpg
++ * Copyright (C) 2006 Ariya Hidayat (ariya at 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__
++
++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/PageSpan.cxx b/writerperfect/source/filter/PageSpan.cxx
+index a75c95b..7ff4d1c 100644
+--- a/writerperfect/source/filter/PageSpan.cxx
++++ b/writerperfect/source/filter/PageSpan.cxx
+@@ -29,6 +29,7 @@
+ #include "FilterInternal.hxx"
+ #include "PageSpan.hxx"
+ #include "DocumentElement.hxx"
++#include "DocumentHandler.hxx"
+
+ PageSpan::PageSpan(const WPXPropertyList &xPropList) :
+ mxPropList(xPropList),
+@@ -39,10 +40,12 @@ PageSpan::PageSpan(const WPXPropertyList &xPropList) :
+ {
+ }
+
+-PageSpan::~PageSpan()
+-{
++namespace {
+ typedef std::vector<DocumentElement *>::iterator DEVIter;
++}
+
++PageSpan::~PageSpan()
++{
+ if (mpHeaderContent)
+ {
+ for (DEVIter iterHeaderContent = mpHeaderContent->begin();
+@@ -81,46 +84,117 @@ PageSpan::~PageSpan()
+ }
+
+ int PageSpan::getSpan() const
+-{
+- if (mxPropList["libwpd:num-pages"])
+- return mxPropList["libwpd:num-pages"]->getInt();
++{
++ if (mxPropList["libwpd:num-pages"])
++ return mxPropList["libwpd:num-pages"]->getInt();
+
+ return 0; // should never happen
+ }
+
+-void PageSpan::writePageMaster(const int iNum, DocumentHandler *pHandler) const
++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 sPageMasterName;
+- sPageMasterName.sprintf("PM%i", iNum /* +2 */);
+- propList.insert("style:name", sPageMasterName);
+
+- pHandler->startElement("style:page-master", 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("0inch"));
+- pHandler->startElement("style:properties", tempPropList);
+-
++ tempPropList.insert("style:footnote-max-height", WPXString("0in"));
++ pHandler->startElement("style:page-layout-properties", tempPropList);
++
+ WPXPropertyList footnoteSepPropList;
+- footnoteSepPropList.insert("style:width", WPXString("0.0071inch"));
+- footnoteSepPropList.insert("style:distance-before-sep", WPXString("0.0398inch"));
+- footnoteSepPropList.insert("style:distance-after-sep", WPXString("0.0398inch"));
++ footnoteSepPropList.insert("style: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:properties");
+- pHandler->endElement("style:page-master");
++ pHandler->endElement("style:page-layout-properties");
++ pHandler->endElement("style:page-layout");
+ }
+
+-void PageSpan::writeMasterPages(const int iStartingNum, const int iPageMasterNum, const bool bLastPageSpan,
+- DocumentHandler *pHandler) const
++void PageSpan::writeMasterPages(const int iStartingNum, const int iPageLayoutNum, const bool bLastPageSpan,
++ DocumentHandlerInterface *pHandler) const
+ {
+ int iSpan = 0;
+ (bLastPageSpan) ? iSpan = 1 : iSpan = getSpan();
+@@ -128,29 +202,58 @@ void PageSpan::writeMasterPages(const int iStartingNum, const int iPageMasterNum
+ for (int i=iStartingNum; i<(iStartingNum+iSpan); i++)
+ {
+ TagOpenElement masterPageOpen("style:master-page");
+- WPXString sMasterPageName;
+- sMasterPageName.sprintf("Page Style %i", i);
+- WPXString sPageMasterName;
+- sPageMasterName.sprintf("PM%i", iPageMasterNum /* +2 */);
++ 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:page-master-name", sPageMasterName);
++ propList.insert("style:display-name", sMasterPageDisplayName);
++ propList.insert("style:page-layout-name", sPageLayoutName);
+ if (!bLastPageSpan)
+ {
+ WPXString sNextMasterPageName;
+- sNextMasterPageName.sprintf("Page Style %i", (i+1));
++ 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");
+ }
+@@ -159,17 +262,15 @@ void PageSpan::writeMasterPages(const int iStartingNum, const int iPageMasterNum
+
+ void PageSpan::_writeHeaderFooter(const char *headerFooterTagName,
+ const std::vector<DocumentElement *> & headerFooterContent,
+- DocumentHandler *pHandler) const
++ DocumentHandlerInterface *pHandler) const
+ {
+ TagOpenElement headerFooterOpen(headerFooterTagName);
+ headerFooterOpen.write(pHandler);
+ for (std::vector<DocumentElement *>::const_iterator iter = headerFooterContent.begin();
+ iter != headerFooterContent.end();
+- iter++) {
++ ++iter) {
+ (*iter)->write(pHandler);
+ }
+- TagCloseElement headerFooterClose(headerFooterTagName);
+- headerFooterClose.write(pHandler);
+ }
+
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/PageSpan.hxx b/writerperfect/source/filter/PageSpan.hxx
+index f2165d4..92eba26 100644
+--- a/writerperfect/source/filter/PageSpan.hxx
++++ b/writerperfect/source/filter/PageSpan.hxx
+@@ -27,35 +27,30 @@
+ */
+ #ifndef _PAGESPAN_H
+ #define _PAGESPAN_H
+-#if defined _MSC_VER
+-#pragma warning( push, 1 )
+-#endif
+ #include <libwpd/libwpd.h>
+-#if defined _MSC_VER
+-#pragma warning( pop )
+-#endif
+ #include <vector>
+
+ class DocumentElement;
+-class DocumentHandler;
++class DocumentHandlerInterface;
+
+ class PageSpan
+ {
+ public:
+ PageSpan(const WPXPropertyList &xPropList);
+ virtual ~PageSpan();
+- void writePageMaster(const int iNum, DocumentHandler *pHandler) const;
+- void writeMasterPages(const int iStartingNum, const int iPageMasterNum, const bool bLastPageSpan, DocumentHandler *pHandler) const;
++ 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;
+
+- const std::vector<DocumentElement *> * getHeaderContent() const { return mpHeaderContent; }
+- void setHeaderContent(std::vector<DocumentElement *> * pHeaderContent) { mpHeaderContent = pHeaderContent; }
+- void setFooterContent(std::vector<DocumentElement *> * pFooterContent) { mpFooterContent = pFooterContent; }
+- void setHeaderLeftContent(std::vector<DocumentElement *> * pHeaderContent) { mpHeaderLeftContent = pHeaderContent; }
+- void setFooterLeftContent(std::vector<DocumentElement *> * pFooterContent) { mpFooterLeftContent = pFooterContent; }
++ 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,
+- DocumentHandler *pHandler) const;
++ DocumentHandlerInterface *pHandler) const;
+ private:
+ WPXPropertyList mxPropList;
+ std::vector<DocumentElement *> * mpHeaderContent;
+diff --git a/writerperfect/source/filter/SectionStyle.cxx b/writerperfect/source/filter/SectionStyle.cxx
+index a1050f4..f88b800 100644
+--- a/writerperfect/source/filter/SectionStyle.cxx
++++ b/writerperfect/source/filter/SectionStyle.cxx
+@@ -34,7 +34,7 @@
+
+ #ifdef _MSC_VER
+ double rint(double x);
+-#endif /* _MSC_VER */
++#endif /* _WIN32 */
+
+ SectionStyle::SectionStyle(const WPXPropertyList &xPropList,
+ const WPXPropertyListVector &xColumns,
+@@ -45,7 +45,7 @@ SectionStyle::SectionStyle(const WPXPropertyList &xPropList,
+ {
+ }
+
+-void SectionStyle::write(DocumentHandler *pHandler) const
++void SectionStyle::write(DocumentHandlerInterface *pHandler) const
+ {
+ TagOpenElement styleOpen("style:style");
+ styleOpen.addAttribute("style:name", getName());
+@@ -54,7 +54,7 @@ void SectionStyle::write(DocumentHandler *pHandler) const
+
+ // if the number of columns is <= 1, we will never come here. This is only an additional check
+ // style properties
+- pHandler->startElement("style:properties", mPropList);
++ pHandler->startElement("style:section-properties", mPropList);
+
+ // column properties
+ WPXPropertyList columnProps;
+@@ -74,14 +74,14 @@ void SectionStyle::write(DocumentHandler *pHandler) const
+ else
+ {
+ columnProps.insert("fo:column-count", 0);
+- columnProps.insert("fo:column-gap", 0.0f);
++ columnProps.insert("fo:column-gap", 0.0);
+ pHandler->startElement("style:columns", columnProps);
+ }
+
+ pHandler->endElement("style:columns");
+
+
+- pHandler->endElement("style:properties");
++ pHandler->endElement("style:section-properties");
+
+ pHandler->endElement("style:style");
+ }
+diff --git a/writerperfect/source/filter/SectionStyle.hxx b/writerperfect/source/filter/SectionStyle.hxx
+index eaf4410..ee7a003 100644
+--- a/writerperfect/source/filter/SectionStyle.hxx
++++ b/writerperfect/source/filter/SectionStyle.hxx
+@@ -27,14 +27,8 @@
+ */
+ #ifndef _SECTIONSTYLE_H
+ #define _SECTIONSTYLE_H
+-#if defined _MSC_VER
+-#pragma warning( push, 1 )
+-#endif
+ #include <libwpd/libwpd.h>
+ #include <libwpd/WPXPropertyListVector.h>
+-#if defined _MSC_VER
+-#pragma warning( pop )
+-#endif
+
+ #include "Style.hxx"
+ #include "WriterProperties.hxx"
+@@ -44,7 +38,7 @@ class SectionStyle : public Style
+ {
+ public:
+ SectionStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &xColumns, const char *psName);
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+
+ private:
+ WPXPropertyList mPropList;
+diff --git a/writerperfect/source/filter/Style.hxx b/writerperfect/source/filter/Style.hxx
+index 7232a02..d54f0c8 100644
+--- a/writerperfect/source/filter/Style.hxx
++++ b/writerperfect/source/filter/Style.hxx
+@@ -28,19 +28,13 @@
+
+ #ifndef _STYLE_H
+ #define _STYLE_H
+-#if defined _MSC_VER
+-#pragma warning( push, 1 )
+-#endif
+ #include <libwpd/libwpd.h>
+-#if defined _MSC_VER
+-#pragma warning( pop )
+-#endif
+ #include "DocumentElement.hxx"
+
+ class TopLevelElementStyle
+ {
+ public:
+- TopLevelElementStyle() : mpsMasterPageName(NULL) { }
++ TopLevelElementStyle() : mpsMasterPageName(0) { }
+ virtual ~TopLevelElementStyle() { if (mpsMasterPageName) delete mpsMasterPageName; }
+ void setMasterPageName(WPXString &sMasterPageName) { mpsMasterPageName = new WPXString(sMasterPageName); }
+ const WPXString * getMasterPageName() const { return mpsMasterPageName; }
+@@ -55,7 +49,7 @@ class Style
+ Style(const WPXString &psName) : msName(psName) {}
+ virtual ~Style() {}
+
+- virtual void write(DocumentHandler * /* pHandler */) const {};
++ virtual void write(DocumentHandlerInterface * /* pHandler */) const {};
+ const WPXString &getName() const { return msName; }
+
+ private:
+diff --git a/writerperfect/source/filter/TableStyle.cxx b/writerperfect/source/filter/TableStyle.cxx
+index e716d5b..1fdc1b0 100644
+--- a/writerperfect/source/filter/TableStyle.cxx
++++ b/writerperfect/source/filter/TableStyle.cxx
+@@ -28,7 +28,6 @@
+ * Corel Corporation or Corel Corporation Limited."
+ */
+ #include <math.h>
+-#include <string.h>
+ #include "FilterInternal.hxx"
+ #include "TableStyle.hxx"
+ #include "DocumentElement.hxx"
+@@ -37,13 +36,15 @@
+ #include <minmax.h>
+ #endif
+
++#include <string.h>
++
+ TableCellStyle::TableCellStyle(const WPXPropertyList &xPropList, const char *psName) :
+ Style(psName),
+ mPropList(xPropList)
+ {
+ }
+
+-void TableCellStyle::write(DocumentHandler *pHandler) const
++void TableCellStyle::write(DocumentHandlerInterface *pHandler) const
+ {
+ TagOpenElement styleOpen("style:style");
+ styleOpen.addAttribute("style:name", getName());
+@@ -59,9 +60,9 @@ void TableCellStyle::write(DocumentHandler *pHandler) const
+ if (strlen(i.key()) > 2 && strncmp(i.key(), "fo", 2) == 0)
+ stylePropList.insert(i.key(), i()->clone());
+ }
+- stylePropList.insert("fo:padding", "0.0382inch");
+- pHandler->startElement("style:properties", stylePropList);
+- pHandler->endElement("style:properties");
++ stylePropList.insert("fo:padding", "0.0382in");
++ pHandler->startElement("style:table-cell-properties", stylePropList);
++ pHandler->endElement("style:table-cell-properties");
+
+ pHandler->endElement("style:style");
+ }
+@@ -72,20 +73,21 @@ TableRowStyle::TableRowStyle(const WPXPropertyList &propList, const char *psName
+ {
+ }
+
+-void TableRowStyle::write(DocumentHandler *pHandler) const
++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:properties");
++ 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:properties");
++ pHandler->endElement("style:table-row-properties");
+
+ pHandler->endElement("style:style");
+ }
+@@ -102,14 +104,13 @@ TableStyle::~TableStyle()
+ {
+ typedef std::vector<TableCellStyle *>::iterator TCSVIter;
+ typedef std::vector<TableRowStyle *>::iterator TRSVIter;
+- for (TCSVIter iterTableCellStyles = mTableCellStyles.begin() ; iterTableCellStyles != mTableCellStyles.end(); iterTableCellStyles++)
++ for (TCSVIter iterTableCellStyles = mTableCellStyles.begin() ; iterTableCellStyles != mTableCellStyles.end(); ++iterTableCellStyles)
+ delete(*iterTableCellStyles);
+- for (TRSVIter iterTableRowStyles = mTableRowStyles.begin() ; iterTableRowStyles != mTableRowStyles.end(); iterTableRowStyles++)
++ for (TRSVIter iterTableRowStyles = mTableRowStyles.begin() ; iterTableRowStyles != mTableRowStyles.end(); ++iterTableRowStyles)
+ delete(*iterTableRowStyles);
+-
+ }
+
+-void TableStyle::write(DocumentHandler *pHandler) const
++void TableStyle::write(DocumentHandlerInterface *pHandler) const
+ {
+ TagOpenElement styleOpen("style:style");
+ styleOpen.addAttribute("style:name", getName());
+@@ -118,7 +119,7 @@ void TableStyle::write(DocumentHandler *pHandler) const
+ styleOpen.addAttribute("style:master-page-name", getMasterPageName()->cstr());
+ styleOpen.write(pHandler);
+
+- TagOpenElement stylePropertiesOpen("style:properties");
++ TagOpenElement stylePropertiesOpen("style:table-properties");
+ if (mPropList["table:align"])
+ stylePropertiesOpen.addAttribute("table:align", mPropList["table:align"]->getStr());
+ if (mPropList["fo:margin-left"])
+@@ -131,7 +132,7 @@ void TableStyle::write(DocumentHandler *pHandler) const
+ stylePropertiesOpen.addAttribute("fo:break-before", mPropList["fo:break-before"]->getStr());
+ stylePropertiesOpen.write(pHandler);
+
+- pHandler->endElement("style:properties");
++ pHandler->endElement("style:table-properties");
+
+ pHandler->endElement("style:style");
+
+@@ -139,15 +140,15 @@ void TableStyle::write(DocumentHandler *pHandler) const
+ WPXPropertyListVector::Iter j(mColumns);
+ for (j.rewind(); j.next();)
+ {
+- TagOpenElement styleNestedOpen("style:style");
++ TagOpenElement styleOpen2("style:style");
+ WPXString sColumnName;
+ sColumnName.sprintf("%s.Column%i", getName().cstr(), i);
+- styleNestedOpen.addAttribute("style:name", sColumnName);
+- styleNestedOpen.addAttribute("style:family", "table-column");
+- styleNestedOpen.write(pHandler);
++ styleOpen2.addAttribute("style:name", sColumnName);
++ styleOpen2.addAttribute("style:family", "table-column");
++ styleOpen2.write(pHandler);
+
+- pHandler->startElement("style:properties", j());
+- pHandler->endElement("style:properties");
++ pHandler->startElement("style:table-column-properties", j());
++ pHandler->endElement("style:table-column-properties");
+
+ pHandler->endElement("style:style");
+
+@@ -155,11 +156,11 @@ void TableStyle::write(DocumentHandler *pHandler) const
+ }
+
+ typedef std::vector<TableRowStyle *>::const_iterator TRSVIter;
+- for (TRSVIter iterTableRow = mTableRowStyles.begin() ; iterTableRow != mTableRowStyles.end(); iterTableRow++)
++ 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++)
++ for (TCSVIter iterTableCell = mTableCellStyles.begin() ; iterTableCell != mTableCellStyles.end(); ++iterTableCell)
+ (*iterTableCell)->write(pHandler);
+ }
+
+diff --git a/writerperfect/source/filter/TableStyle.hxx b/writerperfect/source/filter/TableStyle.hxx
+index eee0870..95c3089 100644
+--- a/writerperfect/source/filter/TableStyle.hxx
++++ b/writerperfect/source/filter/TableStyle.hxx
+@@ -39,15 +39,16 @@
+
+ #include "Style.hxx"
+ #include "WriterProperties.hxx"
++#include "DocumentHandlerInterface.hxx"
+
+ class DocumentElement;
+-class DocumentHandler;
+
+ class TableCellStyle : public Style
+ {
+ public:
++ virtual ~TableCellStyle() {};
+ TableCellStyle(const WPXPropertyList &xPropList, const char *psName);
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ private:
+ WPXPropertyList mPropList;
+ };
+@@ -55,8 +56,9 @@ private:
+ class TableRowStyle : public Style
+ {
+ public:
++ virtual ~TableRowStyle() {};
+ TableRowStyle(const WPXPropertyList &propList, const char *psName);
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ private:
+ WPXPropertyList mPropList;
+ };
+@@ -65,8 +67,8 @@ class TableStyle : public Style, public TopLevelElementStyle
+ {
+ public:
+ TableStyle(const WPXPropertyList &xPropList, const WPXPropertyListVector &columns, const char *psName);
+- ~TableStyle();
+- virtual void write(DocumentHandler *pHandler) const;
++ 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(); }
+diff --git a/writerperfect/source/filter/TextRunStyle.cxx b/writerperfect/source/filter/TextRunStyle.cxx
+index f74ff48..7ee21ff 100644
+--- a/writerperfect/source/filter/TextRunStyle.cxx
++++ b/writerperfect/source/filter/TextRunStyle.cxx
+@@ -51,7 +51,7 @@ ParagraphStyle::~ParagraphStyle()
+ delete mpPropList;
+ }
+
+-void ParagraphStyle::write(DocumentHandler *pHandler) const
++void ParagraphStyle::write(DocumentHandlerInterface *pHandler) const
+ {
+ WRITER_DEBUG_MSG(("Writing a paragraph style..\n"));
+
+@@ -64,49 +64,53 @@ void ParagraphStyle::write(DocumentHandler *pHandler) const
+ pHandler->startElement("style:style", propList);
+
+ propList.clear();
+- WPXPropertyList::Iter k((*mpPropList));
+- for (k.rewind(); k.next(); )
++ WPXPropertyList::Iter i((*mpPropList));
++ for (i.rewind(); i.next(); )
+ {
+- if (strcmp(k.key(), "style:list-style-name") == 0)
+- propList.insert("style:list-style-name", k()->getStr());
+- if (strcmp(k.key(), "fo:margin-left") == 0)
+- propList.insert("fo:margin-left", k()->getStr());
+- if (strcmp(k.key(), "fo:margin-right") == 0)
+- propList.insert("fo:margin-right", k()->getStr());
+- if (strcmp(k.key(), "fo:text-indent") == 0)
+- propList.insert("fo:text-indent", k()->getStr());
+- if (strcmp(k.key(), "fo:margin-top") == 0)
+- propList.insert("fo:margin-top", k()->getStr());
+- if (strcmp(k.key(), "fo:margin-bottom") == 0)
++#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 (k()->getFloat() > 0.0f)
+- propList.insert("fo:margin-bottom", k()->getStr());
++ if (i()->getDouble() > 0.0)
++ propList.insert("fo:margin-bottom", i()->getStr());
+ else
+- propList.insert("fo:margin-bottom", 0.0f);
++ propList.insert("fo:margin-bottom", 0.0);
+ }
+- if (strcmp(k.key(), "fo:line-height") == 0)
+- propList.insert("fo:line-height", k()->getStr());
+- if (strcmp(k.key(), "fo:break-before") == 0)
+- propList.insert("fo:break-before", k()->getStr());
+- if (strcmp(k.key(), "fo:text-align") == 0)
+- propList.insert("fo:text-align", k()->getStr());
+- if (strcmp(k.key(), "fo:text-align-last") == 0)
+- propList.insert("fo:text-align-last", k()->getStr());
++ 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:properties", propList);
++ pHandler->startElement("style:paragraph-properties", propList);
+
+- if (mxTabStops.count() > 0)
++ if (mxTabStops.count() > 0)
+ {
+ TagOpenElement tabListOpen("style:tab-stops");
+ tabListOpen.write(pHandler);
+- WPXPropertyListVector::Iter i(mxTabStops);
+- for (i.rewind(); i.next();)
++ 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(i());
++
++ WPXPropertyList::Iter j(i2());
+ for (j.rewind(); j.next(); )
+ {
+ tabStopOpen.addAttribute(j.key(), j()->getStr().cstr());
+@@ -117,7 +121,7 @@ void ParagraphStyle::write(DocumentHandler *pHandler) const
+ pHandler->endElement("style:tab-stops");
+ }
+
+- pHandler->endElement("style:properties");
++ pHandler->endElement("style:paragraph-properties");
+ pHandler->endElement("style:style");
+ }
+
+@@ -127,15 +131,15 @@ SpanStyle::SpanStyle(const char *psName, const WPXPropertyList &xPropList) :
+ {
+ }
+
+-void SpanStyle::write(DocumentHandler *pHandler) const
++void SpanStyle::write(DocumentHandlerInterface *pHandler) const
+ {
+ WRITER_DEBUG_MSG(("Writing a span style..\n"));
+- WPXPropertyList styleOpenList;
++ WPXPropertyList styleOpenList;
+ styleOpenList.insert("style:name", getName());
+ styleOpenList.insert("style:family", "text");
+ pHandler->startElement("style:style", styleOpenList);
+
+- WPXPropertyList propList(mPropList);
++ WPXPropertyList propList(mPropList);
+
+ if (mPropList["style:font-name"])
+ {
+@@ -145,10 +149,15 @@ void SpanStyle::write(DocumentHandler *pHandler) const
+
+ if (mPropList["fo:font-size"])
+ {
++ if (mPropList["fo:font-size"]->getDouble() > 0.0)
++ {
+ 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());
+@@ -161,9 +170,9 @@ void SpanStyle::write(DocumentHandler *pHandler) const
+ propList.insert("style:font-style-complex", mPropList["fo:font-style"]->getStr());
+ }
+
+- pHandler->startElement("style:properties", propList);
++ pHandler->startElement("style:text-properties", propList);
+
+- pHandler->endElement("style:properties");
++ pHandler->endElement("style:text-properties");
+ pHandler->endElement("style:style");
+ }
+
+diff --git a/writerperfect/source/filter/TextRunStyle.hxx b/writerperfect/source/filter/TextRunStyle.hxx
+index 2bc29ed..492132c 100644
+--- a/writerperfect/source/filter/TextRunStyle.hxx
++++ b/writerperfect/source/filter/TextRunStyle.hxx
+@@ -30,26 +30,19 @@
+
+ #ifndef _TEXTRUNSTYLE_H
+ #define _TEXTRUNSTYLE_H
+-#if defined _MSC_VER
+-#pragma warning( push, 1 )
+-#endif
+ #include <libwpd/libwpd.h>
+-#if defined _MSC_VER
+-#pragma warning( pop )
+-#endif
+
+ #include "Style.hxx"
+
+ class TagOpenElement;
+ class DocumentElement;
+-class DocumentHandler;
+
+ class ParagraphStyle
+ {
+ public:
+ ParagraphStyle(WPXPropertyList *propList, const WPXPropertyListVector &tabStops, const WPXString &sName);
+ virtual ~ParagraphStyle();
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+ WPXString getName() const { return msName; }
+ private:
+ WPXPropertyList *mpPropList;
+@@ -62,7 +55,7 @@ class SpanStyle : public Style
+ {
+ public:
+ SpanStyle(const char *psName, const WPXPropertyList &xPropList);
+- virtual void write(DocumentHandler *pHandler) const;
++ virtual void write(DocumentHandlerInterface *pHandler) const;
+
+ private:
+ WPXPropertyList mPropList;
+diff --git a/writerperfect/source/filter/WriterProperties.hxx b/writerperfect/source/filter/WriterProperties.hxx
+index ea53912..3889b21 100644
+--- a/writerperfect/source/filter/WriterProperties.hxx
++++ b/writerperfect/source/filter/WriterProperties.hxx
+@@ -29,11 +29,10 @@
+ #define _WRITER_PROPERTIES_H
+
+ #define IMP_DEFAULT_SUPER_SUB_SCRIPT "58%"
+-#define IMP_NUM_CENTIMETERES_PER_INCH 2.54f
++#define IMP_NUM_CENTIMETERES_PER_INCH 2.54
+ #define IMP_DEFAULT_FONT_NAME "Times New Roman"
+-#define IMP_DEFAULT_FONT_SIZE 12.0f
++#define IMP_DEFAULT_FONT_SIZE 12.0
+ #define IMP_DEFAULT_FONT_PITCH "variable"
+-#define IMP_DEFAULT_FONT_COLOR (new RGBSColor(0x00,0x00,0x00,0x64))
+ #endif
+
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/filter/makefile.mk b/writerperfect/source/filter/makefile.mk
+index a092ce2..f211101 100644
+--- a/writerperfect/source/filter/makefile.mk
++++ b/writerperfect/source/filter/makefile.mk
+@@ -10,6 +10,10 @@ ENABLE_EXCEPTIONS=true
+ INCPRE+=$(LIBWPD_CFLAGS)
+ .ENDIF
+
++.IF "$(SYSTEM_LIBWPG)" == "YES"
++INCPRE+=$(LIBWPG_CFLAGS)
++.ENDIF
++
+ .IF "$(SYSTEM_LIBWPS)" == "YES"
+ INCPRE+=$(LIBWPS_CFLAGS)
+ .ENDIF
+@@ -18,14 +22,17 @@ INCPRE+=$(LIBWPS_CFLAGS)
+ 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)$/DocumentHandler.obj \
++ $(SLO)$/OdgExporter.obj \
+ $(SLO)$/PageSpan.obj \
+ $(SLO)$/SectionStyle.obj \
+ $(SLO)$/TableStyle.obj \
+- $(SLO)$/TextRunStyle.obj \
+- $(SLO)$/DocumentCollector.obj
++ $(SLO)$/TextRunStyle.obj
+
+ .INCLUDE : target.mk
+diff --git a/writerperfect/source/stream/WPXSvStream.cxx b/writerperfect/source/stream/WPXSvStream.cxx
+index 0e721ae..52e063d 100644
+--- a/writerperfect/source/stream/WPXSvStream.cxx
++++ b/writerperfect/source/stream/WPXSvStream.cxx
+@@ -10,7 +10,7 @@ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::io;
+
+ WPXSvInputStream::WPXSvInputStream( Reference< XInputStream > xStream ) :
+- WPSInputStream(),
++ WPXInputStream(),
+ mxChildStorage(),
+ mxChildStream(),
+ mxStream(xStream),
+@@ -42,7 +42,7 @@ WPXSvInputStream::~WPXSvInputStream()
+ {
+ }
+
+-const uint8_t * WPXSvInputStream::read(size_t numBytes, size_t &numBytesRead)
++const unsigned char * WPXSvInputStream::read(unsigned long numBytes, unsigned long &numBytesRead)
+ {
+ numBytesRead = 0;
+
+@@ -53,7 +53,7 @@ const uint8_t * WPXSvInputStream::read(size_t numBytes, size_t &numBytesRead)
+ if (numBytesRead == 0)
+ return 0;
+
+- return (const uint8_t *)maData.getConstArray();
++ return (const unsigned char *)maData.getConstArray();
+ }
+
+ long WPXSvInputStream::tell()
+@@ -147,7 +147,7 @@ WPXInputStream * WPXSvInputStream::getDocumentOLEStream(const char * name)
+ return 0;
+ }
+
+- mxChildStorage = new SotStorage( pStream, TRUE );
++ mxChildStorage = new SotStorage( pStream, sal_True );
+
+ mxChildStream = mxChildStorage->OpenSotStream(
+ rtl::OUString::createFromAscii( name ),
+@@ -169,9 +169,4 @@ WPXInputStream * WPXSvInputStream::getDocumentOLEStream(const char * name)
+ return 0;
+ }
+
+-WPXInputStream * WPXSvInputStream::getDocumentOLEStream()
+-{
+- return getDocumentOLEStream( "PerfectOffice_MAIN" );
+-}
+-
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/stream/WPXSvStream.h b/writerperfect/source/stream/WPXSvStream.h
+index edc010d..37d905a 100644
+--- a/writerperfect/source/stream/WPXSvStream.h
++++ b/writerperfect/source/stream/WPXSvStream.h
+@@ -13,13 +13,12 @@
+ #if defined _MSC_VER
+ #pragma warning( push, 1 )
+ #endif
+-#include <libwps/WPSStream.h>
+-#include <libwpd/WPXStream.h>
++#include <libwpd-stream/WPXStream.h>
+ #if defined _MSC_VER
+ #pragma warning( pop )
+ #endif
+
+-class WPXSvInputStream : public WPSInputStream
++class WPXSvInputStream : public WPXInputStream
+ {
+ public:
+ WPXSvInputStream( ::com::sun::star::uno::Reference<
+@@ -27,10 +26,9 @@ public:
+ virtual ~WPXSvInputStream();
+
+ virtual bool isOLEStream();
+- virtual WPXInputStream * getDocumentOLEStream();
+ virtual WPXInputStream * getDocumentOLEStream(const char *name);
+
+- virtual const uint8_t *read(size_t numBytes, size_t &numBytesRead);
++ 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();
+diff --git a/writerperfect/source/wpdimp/WordPerfectCollector.cxx b/writerperfect/source/wpdimp/WordPerfectCollector.cxx
+index a5b5718..83fdec5 100644
+--- a/writerperfect/source/wpdimp/WordPerfectCollector.cxx
++++ b/writerperfect/source/wpdimp/WordPerfectCollector.cxx
+@@ -36,8 +36,9 @@
+ #pragma warning( pop )
+ #endif
+
+-WordPerfectCollector::WordPerfectCollector(WPSInputStream *pInput, DocumentHandler *pHandler) :
+- DocumentCollector(pInput, pHandler)
++WordPerfectCollector::WordPerfectCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler, const rtl::OString& password) :
++ DocumentCollector(pInput, pHandler),
++ maUtf8Password(password)
+ {
+ }
+
+@@ -45,9 +46,13 @@ WordPerfectCollector::~WordPerfectCollector()
+ {
+ }
+
+-bool WordPerfectCollector::parseSourceDocument(WPSInputStream &input)
++bool WordPerfectCollector::parseSourceDocument(WPXInputStream &input)
+ {
+- WPDResult result = WPDocument::parse(&input, static_cast<WPXHLListenerImpl *>(this));
++ 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;
+
+diff --git a/writerperfect/source/wpdimp/WordPerfectCollector.hxx b/writerperfect/source/wpdimp/WordPerfectCollector.hxx
+index b38cba0..fce2569 100644
+--- a/writerperfect/source/wpdimp/WordPerfectCollector.hxx
++++ b/writerperfect/source/wpdimp/WordPerfectCollector.hxx
+@@ -31,13 +31,17 @@
+ #define _WORDPERFECTCOLLECTOR_HXX
+
+ #include "filter/DocumentCollector.hxx"
++#include "filter/DocumentHandlerInterface.hxx"
++#include <rtl/ustring.hxx>
+
+ class WordPerfectCollector : public DocumentCollector
+ {
+ public:
+- WordPerfectCollector(WPSInputStream *pInput, DocumentHandler *pHandler);
++ WordPerfectCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler, const rtl::OString& password);
+ virtual ~WordPerfectCollector();
+- bool parseSourceDocument(WPSInputStream &pInput);
++ bool parseSourceDocument(WPXInputStream &pInput);
++private:
++ rtl::OString maUtf8Password;
+ };
+ #endif
+
+diff --git a/writerperfect/source/wpdimp/WordPerfectImportFilter.cxx b/writerperfect/source/wpdimp/WordPerfectImportFilter.cxx
+index e0d42e9..85929ce 100644
+--- a/writerperfect/source/wpdimp/WordPerfectImportFilter.cxx
++++ b/writerperfect/source/wpdimp/WordPerfectImportFilter.cxx
+@@ -1,7 +1,5 @@
+ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/* WordPerfectImportFilter: 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 at interlog.com)
+ * Copyright (C) 2004 Net Integration Technologies (http://www.net-itech.com)
+@@ -32,16 +30,16 @@
+ #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/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"
+@@ -107,11 +105,38 @@ sal_Bool SAL_CALL WordPerfectImportFilter::importImpl( const Sequence< ::com::su
+ OSL_ASSERT( 0 );
+ return sal_False;
+ }
+- OString sFileName;
+- sFileName = OUStringToOString(sURL, RTL_TEXTENCODING_INFO_ASCII);
++
++ 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.XMLImporter" ) );
++ 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..
+@@ -122,9 +147,7 @@ sal_Bool SAL_CALL WordPerfectImportFilter::importImpl( const Sequence< ::com::su
+ // writes to in-memory target doc
+ DocumentHandler xHandler(xInternalHandler);
+
+- WPXSvInputStream input( xInputStream );
+-
+- WordPerfectCollector collector(&input, &xHandler);
++ WordPerfectCollector collector(&input, &xHandler, aUtf8Passwd);
+ collector.filter();
+
+ return true;
+@@ -196,9 +219,9 @@ OUString SAL_CALL WordPerfectImportFilter::detect( com::sun::star::uno::Sequence
+ if (input.atEOS())
+ return ::rtl::OUString();
+
+- confidence = WPDocument::isFileFormatSupported(&input, false);
++ confidence = WPDocument::isFileFormatSupported(&input);
+
+- if (confidence == WPD_CONFIDENCE_EXCELLENT)
++ if (confidence == WPD_CONFIDENCE_EXCELLENT || confidence == WPD_CONFIDENCE_SUPPORTED_ENCRYPTION)
+ sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "writer_WordPerfect_Document" ) );
+
+ if (sTypeName.getLength())
+@@ -206,7 +229,7 @@ OUString SAL_CALL WordPerfectImportFilter::detect( com::sun::star::uno::Sequence
+ if ( location == Descriptor.getLength() )
+ {
+ Descriptor.realloc(nLength+1);
+- Descriptor[location].Name = ::rtl::OUString::createFromAscii( "TypeName" );
++ Descriptor[location].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
+ }
+
+ Descriptor[location].Value <<=sTypeName;
+@@ -255,7 +278,6 @@ Sequence< OUString > SAL_CALL WordPerfectImportFilter_getSupportedServiceNames(
+ throw (RuntimeException)
+ {
+ Sequence < OUString > aRet(2);
+-// Sequence < OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
+ pArray[1] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME2 ) );
+@@ -287,4 +309,126 @@ Sequence< OUString > SAL_CALL WordPerfectImportFilter::getSupportedServiceNames(
+ 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.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "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
+index 411ef1c..2e8a2d5 100644
+--- a/writerperfect/source/wpdimp/WordPerfectImportFilter.hxx
++++ b/writerperfect/source/wpdimp/WordPerfectImportFilter.hxx
+@@ -33,9 +33,13 @@
+ #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
+@@ -113,6 +117,62 @@ sal_Bool SAL_CALL WordPerfectImportFilter_supportsService( const ::rtl::OUString
+ 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
+index 745887e..e2dd8d7 100644
+--- a/writerperfect/source/wpdimp/makefile.mk
++++ b/writerperfect/source/wpdimp/makefile.mk
+@@ -10,6 +10,10 @@ ENABLE_EXCEPTIONS=true
+ INCPRE+=$(LIBWPD_CFLAGS)
+ .ENDIF
+
++.IF "$(SYSTEM_LIBWPG)" == "YES"
++INCPRE+=$(LIBWPG_CFLAGS)
++.ENDIF
++
+ .IF "$(SYSTEM_LIBWPS)" == "YES"
+ INCPRE+=$(LIBWPS_CFLAGS)
+ .ENDIF
+diff --git a/writerperfect/source/wpdimp/wpft_genericfilter.cxx b/writerperfect/source/wpdimp/wpft_genericfilter.cxx
+index 2d619c8..c7080f7 100644
+--- a/writerperfect/source/wpdimp/wpft_genericfilter.cxx
++++ b/writerperfect/source/wpdimp/wpft_genericfilter.cxx
+@@ -47,33 +47,6 @@ void SAL_CALL component_getImplementationEnvironment(
+ *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::createFromAscii( "/UNO/SERVICES" ) );
+-
+- const Sequence< OUString > & rSNL = WordPerfectImportFilter_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 */ )
+ {
+diff --git a/writerperfect/source/wpgimp/OdgExporter.cxx b/writerperfect/source/wpgimp/OdgExporter.cxx
+deleted file mode 100644
+index 36d1394..0000000
+--- a/writerperfect/source/wpgimp/OdgExporter.cxx
++++ /dev/null
+@@ -1,513 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/* libwpg
+- * Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
+- * Copyright (C) 2006-2007 Fridrich Strba (fridrich.strba at 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 "filter/DocumentElement.hxx"
+-#include "filter/DocumentHandler.hxx"
+-#include <rtl/math.hxx>
+-
+-
+-OdgExporter::OdgExporter(DocumentHandler *pHandler):
+- mpHandler(pHandler),
+- m_fillRule(AlternatingFill),
+- m_gradientIndex(1),
+- m_dashIndex(1),
+- m_styleIndex(1)
+-{
+-}
+-
+-OdgExporter::~OdgExporter()
+-{
+-}
+-
+-void OdgExporter::startDocument(double width, double height)
+-{
+- m_gradientIndex = 1;
+- m_dashIndex = 1;
+- m_styleIndex = 1;
+-
+- 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("office:version", "1.0");
+- tmpOfficeDocumentContent.write(mpHandler);
+-
+- TagOpenElement("office:styles").write(mpHandler);
+- TagCloseElement("office:styles").write(mpHandler);
+-
+- TagOpenElement("office:automatic-styles").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", "0cm");
+- tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-bottom", "0cm");
+- tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-left", "0cm");
+- tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:margin-right", "0cm");
+- WPXString sValue;
+- sValue = doubleToString(2.54 * width); sValue.append("cm");
+- tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-width", sValue);
+- sValue = doubleToString(2.54 * height); sValue.append("cm");
+- tmpStylePageLayoutPropertiesOpenElement.addAttribute("fo:page-height", sValue);
+- tmpStylePageLayoutPropertiesOpenElement.addAttribute("style:print-orientation", "portrait");
+- tmpStylePageLayoutPropertiesOpenElement.write(mpHandler);
+-
+- TagCloseElement("style:page-layout-properties").write(mpHandler);
+-
+- TagCloseElement("style:page-layout").write(mpHandler);
+-
+- 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);
+-
+- TagCloseElement("style:drawing-page-properties").write(mpHandler);
+-
+- TagCloseElement("style:style").write(mpHandler);
+-}
+-
+-void OdgExporter::endDocument()
+-{
+- TagCloseElement("office:automatic-styles").write(mpHandler);
+-
+- 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);
+-
+- TagCloseElement("style:master-page").write(mpHandler);
+-
+- TagCloseElement("office:master-styles").write(mpHandler);
+-
+- 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 = mpBodyElements.begin();
+- bodyIter != mpBodyElements.end(); bodyIter++)
+- {
+- (*bodyIter)->write(mpHandler);
+- }
+-
+- TagCloseElement("draw:page").write(mpHandler);
+- TagCloseElement("office:drawing").write(mpHandler);
+- TagCloseElement("office:body").write(mpHandler);
+- TagCloseElement("office:document").write(mpHandler);
+-
+- mpHandler->endDocument();
+-}
+-
+-void OdgExporter::setPen(const libwpg::WPGPen& pen)
+-{
+- m_pen = pen;
+-}
+-
+-void OdgExporter::setBrush(const libwpg::WPGBrush& brush)
+-{
+- m_brush = brush;
+-}
+-
+-void OdgExporter::setFillRule(FillRule rule)
+-{
+- m_fillRule = rule;
+-}
+-
+-void OdgExporter::startLayer(unsigned int /* id */)
+-{
+-}
+-
+-void OdgExporter::endLayer(unsigned int)
+-{
+-}
+-
+-void OdgExporter::drawRectangle(const libwpg::WPGRect& rect, double rx, double /* ry */)
+-{
+- writeStyle();
+- TagOpenElement *pDrawRectElement = new TagOpenElement("draw:rect");
+- WPXString sValue;
+- sValue.sprintf("gr%i", m_styleIndex-1);
+- pDrawRectElement->addAttribute("draw:style-name", sValue);
+- sValue = doubleToString(2.54 * rect.x1); sValue.append("cm");
+- pDrawRectElement->addAttribute("svg:x", sValue);
+- sValue = doubleToString(2.54 * rect.y1); sValue.append("cm");
+- pDrawRectElement->addAttribute("svg:y", sValue);
+- sValue = doubleToString(2.54 * (rect.x2-rect.x1)); sValue.append("cm");
+- pDrawRectElement->addAttribute("svg:width", sValue);
+- sValue = doubleToString(2.54 * (rect.y2-rect.y1)); sValue.append("cm");
+- pDrawRectElement->addAttribute("svg:height", sValue);
+- sValue = doubleToString(2.54 * rx); sValue.append("cm");
+- // FIXME: what to do when rx != ry ?
+- pDrawRectElement->addAttribute("draw:corner-radius", sValue);
+- mpBodyElements.push_back(static_cast<DocumentElement *>(pDrawRectElement));
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:rect")));
+-}
+-
+-void OdgExporter::drawEllipse(const libwpg::WPGPoint& center, double rx, double ry)
+-{
+- writeStyle();
+- TagOpenElement *pDrawEllipseElement = new TagOpenElement("draw:ellipse");
+- WPXString sValue;
+- sValue.sprintf("gr%i", m_styleIndex-1);
+- pDrawEllipseElement->addAttribute("draw:style-name", sValue);
+- sValue = doubleToString(2.54 * (center.x-rx)); sValue.append("cm");
+- pDrawEllipseElement->addAttribute("svg:x", sValue);
+- sValue = doubleToString(2.54 * (center.y-ry)); sValue.append("cm");
+- pDrawEllipseElement->addAttribute("svg:y", sValue);
+- sValue = doubleToString(2 * 2.54 * rx); sValue.append("cm");
+- pDrawEllipseElement->addAttribute("svg:width", sValue);
+- sValue = doubleToString(2 * 2.54 * ry); sValue.append("cm");
+- pDrawEllipseElement->addAttribute("svg:height", sValue);
+- mpBodyElements.push_back(static_cast<DocumentElement *>(pDrawEllipseElement));
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:ellipse")));
+-}
+-
+-void OdgExporter::drawPolygon(const libwpg::WPGPointArray& vertices)
+-{
+- if(vertices.count() < 2)
+- return;
+-
+- if(vertices.count() == 2)
+- {
+- const libwpg::WPGPoint& p1 = vertices[0];
+- const libwpg::WPGPoint& p2 = vertices[1];
+-
+- writeStyle();
+- TagOpenElement *pDrawLineElement = new TagOpenElement("draw:line");
+- WPXString sValue;
+- sValue.sprintf("gr%i", m_styleIndex-1);
+- pDrawLineElement->addAttribute("draw:style-name", sValue);
+- pDrawLineElement->addAttribute("draw:text-style-name", "P1");
+- pDrawLineElement->addAttribute("draw:layer", "layout");
+- sValue = doubleToString(2.54 * p1.x); sValue.append("cm");
+- pDrawLineElement->addAttribute("svg:x1", sValue);
+- sValue = doubleToString(2.54 * p1.y); sValue.append("cm");
+- pDrawLineElement->addAttribute("svg:y1", sValue);
+- sValue = doubleToString(2.54 * p2.x); sValue.append("cm");
+- pDrawLineElement->addAttribute("svg:x2", sValue);
+- sValue = doubleToString(2.54 * p2.y); sValue.append("cm");
+- pDrawLineElement->addAttribute("svg:y2", sValue);
+- mpBodyElements.push_back(static_cast<DocumentElement *>(pDrawLineElement));
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:line")));
+- }
+- else
+- {
+- // draw as path
+- libwpg::WPGPath path;
+- path.moveTo(vertices[0]);
+- for(unsigned long ii = 1; ii < vertices.count(); ii++)
+- path.lineTo(vertices[ii]);
+- path.closed = true;
+- drawPath(path);
+- }
+-}
+-
+-void OdgExporter::drawPath(const libwpg::WPGPath& 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
+- libwpg::WPGPoint p = path.element(0).point;
+- libwpg::WPGPoint q = path.element(0).point;
+- for(unsigned k = 0; k < path.count(); k++)
+- {
+- libwpg::WPGPathElement element = path.element(k);
+- p.x = (p.x > element.point.x) ? element.point.x : p.x;
+- p.y = (p.y > element.point.y) ? element.point.y : p.y;
+- q.x = (q.x < element.point.x) ? element.point.x : q.x;
+- q.y = (q.y < element.point.y) ? element.point.y : q.y;
+- if(element.type == libwpg::WPGPathElement::CurveToElement)
+- {
+- p.x = (p.x > element.extra1.x) ? element.extra1.x : p.x;
+- p.y = (p.y > element.extra1.y) ? element.extra1.y : p.y;
+- q.x = (q.x < element.extra1.x) ? element.extra1.x : q.x;
+- q.y = (q.y < element.extra1.y) ? element.extra1.y : q.y;
+- p.x = (p.x > element.extra2.x) ? element.extra2.x : p.x;
+- p.y = (p.y > element.extra2.y) ? element.extra2.y : p.y;
+- q.x = (q.x < element.extra2.x) ? element.extra2.x : q.x;
+- q.y = (q.y < element.extra2.y) ? element.extra2.y : q.y;
+- }
+- }
+- double vw = q.x - p.x;
+- double vh = q.y - p.y;
+-
+- writeStyle();
+-
+- TagOpenElement *pDrawPathElement = new TagOpenElement("draw:path");
+- WPXString sValue;
+- sValue.sprintf("gr%i", m_styleIndex-1);
+- pDrawPathElement->addAttribute("draw:style-name", sValue);
+- pDrawPathElement->addAttribute("draw:text-style-name", "P1");
+- pDrawPathElement->addAttribute("draw:layer", "layout");
+- sValue = doubleToString(2.54 * p.x); sValue.append("cm");
+- pDrawPathElement->addAttribute("svg:x", sValue);
+- sValue = doubleToString(2.54 * p.y); sValue.append("cm");
+- pDrawPathElement->addAttribute("svg:y", sValue);
+- sValue = doubleToString(2.54 * vw); sValue.append("cm");
+- pDrawPathElement->addAttribute("svg:width", sValue);
+- sValue = doubleToString(2.54 * vh); sValue.append("cm");
+- pDrawPathElement->addAttribute("svg:height", sValue);
+- sValue.sprintf("%i %i %i %i", 0, 0, (int)(vw*2540), (int)(vh*2540));
+- pDrawPathElement->addAttribute("svg:viewBox", sValue);
+-
+- sValue.clear();
+- for(unsigned i = 0; i < path.count(); i++)
+- {
+- libwpg::WPGPathElement element = path.element(i);
+- libwpg::WPGPoint point = element.point;
+- WPXString sElement;
+- switch(element.type)
+- {
+- // 2540 is 2.54*1000, 2.54 cm = 1 inch
+- case libwpg::WPGPathElement::MoveToElement:
+- sElement.sprintf("M%i %i", (int)((point.x-p.x)*2540), (int)((point.y-p.y)*2540));
+- break;
+-
+- case libwpg::WPGPathElement::LineToElement:
+- sElement.sprintf("L%i %i", (int)((point.x-p.x)*2540), (int)((point.y-p.y)*2540));
+- break;
+-
+- case libwpg::WPGPathElement::CurveToElement:
+- sElement.sprintf("C%i %i %i %i %i %i", (int)((element.extra1.x-p.x)*2540),
+- (int)((element.extra1.y-p.y)*2540), (int)((element.extra2.x-p.x)*2540),
+- (int)((element.extra2.y-p.y)*2540), (int)((point.x-p.x)*2540), (int)((point.y-p.y)*2540));
+- break;
+-
+- default:
+- break;
+- }
+- sValue.append(sElement);
+- }
+- if(path.closed)
+- sValue.append(" Z");
+- pDrawPathElement->addAttribute("svg:d", sValue);
+- mpBodyElements.push_back(static_cast<DocumentElement *>(pDrawPathElement));
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:path")));
+-}
+-
+-void OdgExporter::drawBitmap(const libwpg::WPGBitmap& bitmap)
+-{
+- TagOpenElement *pDrawFrameElement = new TagOpenElement("draw:frame");
+- WPXString sValue;
+- sValue = doubleToString(2.54 * bitmap.rect.x1); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:x", sValue);
+- sValue = doubleToString(2.54 * bitmap.rect.y1); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:y", sValue);
+- sValue = doubleToString(2.54 * bitmap.rect.height()); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:height", sValue);
+- sValue = doubleToString(2.54 * bitmap.rect.width()); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:width", sValue);
+- mpBodyElements.push_back(static_cast<DocumentElement *>(pDrawFrameElement));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagOpenElement("draw:image")));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagOpenElement("office:binary-data")));
+-
+- libwpg::WPGString base64Binary;
+- bitmap.generateBase64DIB(base64Binary);
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new CharDataElement(base64Binary.cstr())));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("office:binary-data")));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:image")));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:frame")));
+-}
+-
+-void OdgExporter::drawImageObject(const libwpg::WPGBinaryData& binaryData)
+-{
+- if (binaryData.mimeType.length() <= 0)
+- return;
+-
+- TagOpenElement *pDrawFrameElement = new TagOpenElement("draw:frame");
+- WPXString sValue;
+- sValue = doubleToString(2.54 * binaryData.rect.x1); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:x", sValue);
+- sValue = doubleToString(2.54 * binaryData.rect.y1); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:y", sValue);
+- sValue = doubleToString(2.54 * binaryData.rect.height()); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:height", sValue);
+- sValue = doubleToString(2.54 * binaryData.rect.width()); sValue.append("cm");
+- pDrawFrameElement->addAttribute("svg:width", sValue);
+- mpBodyElements.push_back(static_cast<DocumentElement *>(pDrawFrameElement));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagOpenElement("draw:image")));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagOpenElement("office:binary-data")));
+-
+- libwpg::WPGString base64Binary = binaryData.getBase64Data();;
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new CharDataElement(base64Binary.cstr())));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("office:binary-data")));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:image")));
+-
+- mpBodyElements.push_back(static_cast<DocumentElement *>(new TagCloseElement("draw:frame")));
+-}
+-
+-void OdgExporter::writeStyle()
+-{
+- if(!m_pen.solid && (m_pen.dashArray.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 = m_pen.dashArray.at(1);
+- TagOpenElement tmpDrawStrokeDashElement("draw:stroke-dash");
+- tmpDrawStrokeDashElement.addAttribute("draw:style", "rect");
+- WPXString sValue;
+- sValue.sprintf("Dash_%i", m_dashIndex++);
+- tmpDrawStrokeDashElement.addAttribute("draw:name", sValue);
+- sValue.sprintf("%i \%", distance*100);
+- tmpDrawStrokeDashElement.addAttribute("draw:distance", sValue);
+- WPXString sName;
+- for(unsigned i = 0; i < m_pen.dashArray.count()/2; i++)
+- {
+- sName.sprintf("draw:dots%i", i+1);
+- tmpDrawStrokeDashElement.addAttribute(sName.cstr(), "1");
+- sName.sprintf("draw:dots%i-length", i+1);
+- sValue.sprintf("%i\%", 100*m_pen.dashArray.at(i*2));
+- tmpDrawStrokeDashElement.addAttribute(sName.cstr(), sValue);
+- }
+- tmpDrawStrokeDashElement.write(mpHandler);
+- TagCloseElement("draw:stroke-dash").write(mpHandler);
+- }
+-
+- if(m_brush.style == libwpg::WPGBrush::Gradient)
+- {
+- TagOpenElement tmpDrawGradientElement("draw:gradient");
+- tmpDrawGradientElement.addAttribute("draw:style", "linear");
+- WPXString sValue;
+- sValue.sprintf("Gradient_%i", m_gradientIndex++);
+- tmpDrawGradientElement.addAttribute("draw:name", sValue);
+-
+- // ODG angle unit is 0.1 degree
+- double angle = -m_brush.gradient.angle();
+- while(angle < 0)
+- angle += 360;
+- while(angle > 360)
+- angle -= 360;
+-
+- sValue.sprintf("%i", angle*10);
+- tmpDrawGradientElement.addAttribute("draw:angle", sValue);
+-
+- libwpg::WPGColor startColor = m_brush.gradient.stopColor(0);
+- libwpg::WPGColor stopColor = m_brush.gradient.stopColor(1);
+- sValue.sprintf("#%.2x%.2x%.2x", (startColor.red & 0xff), (startColor.green & 0xff), (startColor.blue & 0xff));
+- tmpDrawGradientElement.addAttribute("draw:start-color", sValue);
+- sValue.sprintf("#%.2x%.2x%.2x", (stopColor.red & 0xff), (stopColor.green & 0xff), (stopColor.blue & 0xff));
+- tmpDrawGradientElement.addAttribute("draw:end-color", sValue);
+- tmpDrawGradientElement.addAttribute("draw:start-intensity", "100%");
+- tmpDrawGradientElement.addAttribute("draw:end-intensity", "100%");
+- tmpDrawGradientElement.addAttribute("draw:border", "0%");
+- tmpDrawGradientElement.write(mpHandler);
+- TagCloseElement("draw:gradient").write(mpHandler);
+- }
+-
+- TagOpenElement tmpStyleStyleElement("style:style");
+- WPXString sValue;
+- sValue.sprintf("gr%i", m_styleIndex);
+- tmpStyleStyleElement.addAttribute("style:name", sValue);
+- tmpStyleStyleElement.addAttribute("style:family", "graphic");
+- tmpStyleStyleElement.addAttribute("style:parent-style-name", "standard");
+- tmpStyleStyleElement.write(mpHandler);
+-
+- TagOpenElement tmpStyleGraphicPropertiesElement("style:graphic-properties");
+-
+- if(m_pen.width > 0.0)
+- {
+- sValue = doubleToString(2.54 * m_pen.width); sValue.append("cm");
+- tmpStyleGraphicPropertiesElement.addAttribute("svg:stroke-width", sValue);
+- sValue.sprintf("#%.2x%.2x%.2x", (m_pen.foreColor.red & 0xff),
+- (m_pen.foreColor.green & 0xff), (m_pen.foreColor.blue & 0xff));
+- tmpStyleGraphicPropertiesElement.addAttribute("svg:stroke-color", sValue);
+-
+- if(!m_pen.solid)
+- {
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:stroke", "dash");
+- sValue.sprintf("Dash_%i", m_dashIndex-1);
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:stroke-dash", sValue);
+- }
+- }
+- else
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:stroke", "none");
+-
+- if(m_brush.style == libwpg::WPGBrush::NoBrush)
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:fill", "none");
+-
+- if(m_brush.style == libwpg::WPGBrush::Solid)
+- {
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:fill", "solid");
+- sValue.sprintf("#%.2x%.2x%.2x", (m_brush.foreColor.red & 0xff),
+- (m_brush.foreColor.green & 0xff), (m_brush.foreColor.blue & 0xff));
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:fill-color", sValue);
+- }
+-
+- if(m_brush.style == libwpg::WPGBrush::Gradient)
+- {
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:fill", "gradient");
+- sValue.sprintf("Gradient_%i", m_gradientIndex-1);
+- tmpStyleGraphicPropertiesElement.addAttribute("draw:fill-gradient-name", sValue);
+- }
+-
+- tmpStyleGraphicPropertiesElement.write(mpHandler);
+- TagCloseElement("style:graphic-properties").write(mpHandler);
+-
+- TagCloseElement("style:style").write(mpHandler);
+- m_styleIndex++;
+-}
+-
+-WPXString OdgExporter::doubleToString(const double value)
+-{
+- return WPXString((char *)::rtl::math::doubleToString(value, rtl_math_StringFormat_F, 4, '.').getStr());
+-}
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/wpgimp/OdgExporter.hxx b/writerperfect/source/wpgimp/OdgExporter.hxx
+deleted file mode 100644
+index 2bfa6b8..0000000
+--- a/writerperfect/source/wpgimp/OdgExporter.hxx
++++ /dev/null
+@@ -1,81 +0,0 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+-/* libwpg
+- * Copyright (C) 2006 Ariya Hidayat (ariya at kde.org)
+- * Copyright (C) 2007 Fridrich Strba (fridrich_strba at 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."
+- */
+-
+-#ifndef __ODGEXPORTER_HXX__
+-#define __ODGEXPORTER_HXX__
+-
+-#include <iostream>
+-#include <sstream>
+-#include <string>
+-
+-#include <libwpd/WPXString.h>
+-#include <libwpg/libwpg.h>
+-#include <libwpg/WPGBinaryData.h>
+-#include "filter/DocumentElement.hxx"
+-#include "filter/DocumentHandler.hxx"
+-
+-class OdgExporter : public libwpg::WPGPaintInterface {
+-public:
+- OdgExporter(DocumentHandler *pHandler);
+- ~OdgExporter();
+-
+- void startDocument(double width, double height);
+- void startGraphics(double width, double height) { startDocument(width, height); }
+- void endDocument();
+- void endGraphics() { endDocument(); };
+- void startLayer(unsigned int id);
+- void endLayer(unsigned int id);
+-
+- void setPen(const libwpg::WPGPen& pen);
+- void setBrush(const libwpg::WPGBrush& brush);
+- void setFillRule(FillRule rule);
+-
+- void drawRectangle(const libwpg::WPGRect& rect, double rx, double ry);
+- void drawEllipse(const libwpg::WPGPoint& center, double rx, double ry);
+- void drawPolygon(const libwpg::WPGPointArray& vertices);
+- void drawPath(const libwpg::WPGPath& path);
+- void drawBitmap(const libwpg::WPGBitmap& bitmap);
+- void drawImageObject(const libwpg::WPGBinaryData& binaryData);
+-
+-private:
+- std::vector <DocumentElement *> mpBodyElements;
+- std::vector <DocumentElement *> mpStylesElements;
+- DocumentHandler *mpHandler;
+-
+- libwpg::WPGPen m_pen;
+- libwpg::WPGBrush m_brush;
+- FillRule m_fillRule;
+- int m_gradientIndex;
+- int m_dashIndex;
+- int m_styleIndex;
+- void writeStyle();
+- WPXString doubleToString(const double value);
+-};
+-
+-#endif // __ODGEXPORTER_HXX__
+-
+-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+diff --git a/writerperfect/source/wpgimp/WPGImportFilter.cxx b/writerperfect/source/wpgimp/WPGImportFilter.cxx
+index 75283cf..1d68590 100644
+--- a/writerperfect/source/wpgimp/WPGImportFilter.cxx
++++ b/writerperfect/source/wpgimp/WPGImportFilter.cxx
+@@ -47,7 +47,7 @@
+ #include <xmloff/attrlist.hxx>
+
+ #include "filter/DocumentHandler.hxx"
+-#include "OdgExporter.hxx"
++#include "filter/OdgExporter.hxx"
+ #include "WPGImportFilter.hxx"
+ #include "stream/WPXSvStream.h"
+
+@@ -120,16 +120,6 @@ sal_Bool SAL_CALL WPGImportFilter::filter( const Sequence< ::com::sun::star::bea
+
+ WPXInputStream* input = new WPXSvInputStream( xInputStream );
+
+- if (input->isOLEStream())
+- {
+- WPXInputStream* olestream = input->getDocumentOLEStream();
+- if (olestream)
+- {
+- delete input;
+- input = olestream;
+- }
+- }
+-
+ OdgExporter exporter(&xHandler);
+ bool tmpParseResult = libwpg::WPGraphics::parse(input, &exporter);
+ if (input)
+@@ -179,28 +169,18 @@ OUString SAL_CALL WPGImportFilter::detect( com::sun::star::uno::Sequence< Proper
+
+ WPXInputStream* input = new WPXSvInputStream( xInputStream );
+
+- if (input->isOLEStream())
+- {
+- WPXInputStream* olestream = input->getDocumentOLEStream();
+- if (olestream)
+- {
+- delete input;
+- input = olestream;
+- }
+- }
+-
+ if (libwpg::WPGraphics::isSupported(input))
+ sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "draw_WordPerfect_Graphics" ) );
+
+ if (input)
+ delete input;
+
+- if (!sTypeName.equalsAscii(""))
++ if (sTypeName.getLength())
+ {
+ if ( location == Descriptor.getLength() )
+ {
+ Descriptor.realloc(nLength+1);
+- Descriptor[location].Name = ::rtl::OUString::createFromAscii( "TypeName" );
++ Descriptor[location].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
+ }
+
+ Descriptor[location].Value <<=sTypeName;
+diff --git a/writerperfect/source/wpgimp/makefile.mk b/writerperfect/source/wpgimp/makefile.mk
+index 3bb58c1..ccf1d7d 100644
+--- a/writerperfect/source/wpgimp/makefile.mk
++++ b/writerperfect/source/wpgimp/makefile.mk
+@@ -8,27 +8,16 @@ ENABLE_EXCEPTIONS=true
+
+ .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
+
+ .IF "$(SYSTEM_LIBWPG)" == "YES"
+ INCPRE+=$(LIBWPG_CFLAGS)
+-.ELSE
+-INCPRE+=$(SOLARVER)$/$(UPD)$/$(INPATH)$/inc$/libwpg
+ .ENDIF
+
+ # broken but ... necessary, internal include shafted ...
+ INCPRE+= -I..
+
+ SLOFILES= \
+- $(SLO)$/OdgExporter.obj \
+ $(SLO)$/WPGImportFilter.obj \
+ $(SLO)$/wpgimport_genericfilter.obj
+
+diff --git a/writerperfect/source/wpgimp/wpgimport_genericfilter.cxx b/writerperfect/source/wpgimp/wpgimport_genericfilter.cxx
+index 16fd6e8..2ab4fae 100644
+--- a/writerperfect/source/wpgimp/wpgimport_genericfilter.cxx
++++ b/writerperfect/source/wpgimp/wpgimport_genericfilter.cxx
+@@ -41,40 +41,11 @@ 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::createFromAscii( "/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 */ )
+ {
+diff --git a/writerperfect/source/wpsimp/MSWorksCollector.cxx b/writerperfect/source/wpsimp/MSWorksCollector.cxx
+index 20934c2..bed21d8 100644
+--- a/writerperfect/source/wpsimp/MSWorksCollector.cxx
++++ b/writerperfect/source/wpsimp/MSWorksCollector.cxx
+@@ -30,7 +30,7 @@
+ #include "MSWorksCollector.hxx"
+ #include <libwps/WPSDocument.h>
+
+-MSWorksCollector::MSWorksCollector(WPSInputStream *pInput, DocumentHandler *pHandler) :
++MSWorksCollector::MSWorksCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler) :
+ DocumentCollector(pInput, pHandler)
+ {
+ }
+@@ -39,9 +39,9 @@ MSWorksCollector::~MSWorksCollector()
+ {
+ }
+
+-bool MSWorksCollector::parseSourceDocument(WPSInputStream &input)
++bool MSWorksCollector::parseSourceDocument(WPXInputStream &input)
+ {
+- WPSResult result = WPSDocument::parse(&input, static_cast<WPXHLListenerImpl *>(this));
++ WPSResult result = WPSDocument::parse(&input, static_cast<WPXDocumentInterface *>(this));
+ if (result != WPS_OK)
+ return false;
+
+diff --git a/writerperfect/source/wpsimp/MSWorksCollector.hxx b/writerperfect/source/wpsimp/MSWorksCollector.hxx
+index b2a767b..9db0253 100644
+--- a/writerperfect/source/wpsimp/MSWorksCollector.hxx
++++ b/writerperfect/source/wpsimp/MSWorksCollector.hxx
+@@ -31,13 +31,14 @@
+ #define _MSWORKSCOLLECTOR_HXX
+
+ #include "filter/DocumentCollector.hxx"
++#include "filter/DocumentHandlerInterface.hxx"
+
+ class MSWorksCollector : public DocumentCollector
+ {
+ public:
+- MSWorksCollector(WPSInputStream *pInput, DocumentHandler *pHandler);
++ MSWorksCollector(WPXInputStream *pInput, DocumentHandlerInterface *pHandler);
+ virtual ~MSWorksCollector();
+- bool parseSourceDocument(WPSInputStream &input);
++ bool parseSourceDocument(WPXInputStream &input);
+ };
+ #endif
+
+diff --git a/writerperfect/source/wpsimp/MSWorksImportFilter.cxx b/writerperfect/source/wpsimp/MSWorksImportFilter.cxx
+index b8818dc..211d3ae 100644
+--- a/writerperfect/source/wpsimp/MSWorksImportFilter.cxx
++++ b/writerperfect/source/wpsimp/MSWorksImportFilter.cxx
+@@ -102,7 +102,7 @@ sal_Bool SAL_CALL MSWorksImportFilter::importImpl( const Sequence< ::com::sun::s
+ 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.XMLImporter" ) );
++ 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..
+@@ -187,7 +187,7 @@ OUString SAL_CALL MSWorksImportFilter::detect( com::sun::star::uno::Sequence< Pr
+ if (input.atEOS())
+ return ::rtl::OUString();
+
+- confidence = WPSDocument::isFileFormatSupported(&input, false);
++ confidence = WPSDocument::isFileFormatSupported(&input);
+
+ if ((confidence == WPS_CONFIDENCE_EXCELLENT) || (confidence == WPS_CONFIDENCE_GOOD))
+ sTypeName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "writer_MS_Works_Document" ) );
+@@ -197,7 +197,7 @@ OUString SAL_CALL MSWorksImportFilter::detect( com::sun::star::uno::Sequence< Pr
+ if ( location == Descriptor.getLength() )
+ {
+ Descriptor.realloc(nLength+1);
+- Descriptor[location].Name = ::rtl::OUString::createFromAscii( "TypeName" );
++ Descriptor[location].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName"));
+ }
+
+ Descriptor[location].Value <<=sTypeName;
+diff --git a/writerperfect/source/wpsimp/MSWorksImportFilter.hxx b/writerperfect/source/wpsimp/MSWorksImportFilter.hxx
+index bb876d8..71e6212 100644
+--- a/writerperfect/source/wpsimp/MSWorksImportFilter.hxx
++++ b/writerperfect/source/wpsimp/MSWorksImportFilter.hxx
+@@ -69,7 +69,9 @@ protected:
+
+ public:
+ MSWorksImportFilter( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > &rxMSF)
+- : mxMSF( rxMSF ) {}
++ : mxMSF( rxMSF )
++ , meType( FILTER_IMPORT )
++ {}
+ virtual ~MSWorksImportFilter() {}
+
+ // XFilter
+diff --git a/writerperfect/source/wpsimp/makefile.mk b/writerperfect/source/wpsimp/makefile.mk
+index da17e80..c3dfe20 100644
+--- a/writerperfect/source/wpsimp/makefile.mk
++++ b/writerperfect/source/wpsimp/makefile.mk
+@@ -27,3 +27,4 @@ SLOFILES= \
+ $(SLO)$/msworks_genericfilter.obj
+
+ .INCLUDE : target.mk
++
+diff --git a/writerperfect/source/wpsimp/msworks_genericfilter.cxx b/writerperfect/source/wpsimp/msworks_genericfilter.cxx
+index 8d6e7c6..8b37d45 100644
+--- a/writerperfect/source/wpsimp/msworks_genericfilter.cxx
++++ b/writerperfect/source/wpsimp/msworks_genericfilter.cxx
+@@ -41,40 +41,11 @@ 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::createFromAscii( "/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 */ )
+ {
+diff --git a/writerperfect/util/msworksfilter.component b/writerperfect/util/msworksfilter.component
+new file mode 100644
+index 0000000..769eaf3
+--- /dev/null
++++ b/writerperfect/util/msworksfilter.component
+@@ -0,0 +1,8 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<component loader="com.sun.star.loader.SharedLibrary"
++ xmlns="http://openoffice.org/2010/uno-components">
++ <implementation name="com.sun.star.comp.Writer.MSWorksImportFilter">
++ <service name="com.sun.star.document.ImportFilter"/>
++ <service name="com.sun.star.document.ExtendedTypeDetection"/>
++ </implementation>
++</component>
+diff --git a/writerperfect/util/wpgfilter.component b/writerperfect/util/wpgfilter.component
+new file mode 100644
+index 0000000..f571959
+--- /dev/null
++++ b/writerperfect/util/wpgfilter.component
+@@ -0,0 +1,8 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<component loader="com.sun.star.loader.SharedLibrary"
++ xmlns="http://openoffice.org/2010/uno-components">
++ <implementation name="com.sun.star.comp.Draw.WPGImportFilter">
++ <service name="com.sun.star.document.ImportFilter"/>
++ <service name="com.sun.star.document.ExtendedTypeDetection"/>
++ </implementation>
++</component>
diff --git a/libreoffice-rhel6poppler.patch b/libreoffice-rhel6poppler.patch
new file mode 100644
index 0000000..0353017
--- /dev/null
+++ b/libreoffice-rhel6poppler.patch
@@ -0,0 +1,38 @@
+--- configure.in 2011-11-10 13:22:02.062474990 +0000
++++ configure.in 2011-11-10 13:22:35.072472880 +0000
+@@ -6354,16 +6354,6 @@
+ AC_MSG_RESULT([external])
+ SYSTEM_POPPLER=YES
+ PKG_CHECK_MODULES( POPPLER, poppler >= 0.8.0 )
+- AC_LANG_PUSH([C++])
+- save_CXXFLAGS=$CXXFLAGS
+- save_CPPFLAGS=$CPPFLAGS
+- CXXFLAGS="$CXXFLAGS $POPPLER_CFLAGS"
+- CPPFLAGS="$CPPFLAGS $POPPLER_CFLAGS"
+- AC_CHECK_HEADER([cpp/poppler-version.h], [],
+- [AC_MSG_ERROR([cpp/poppler-version.h not found. Install poppler])], [])
+- CXXFLAGS=$save_CXXFLAGS
+- CPPFLAGS=$save_CPPFLAGS
+- AC_LANG_POP([C++])
+ else
+ AC_MSG_RESULT([internal])
+ SYSTEM_POPPLER=NO
+--- sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx 2011-11-10 13:22:11.949473646 +0000
++++ sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.hxx 2011-11-10 13:23:24.889473889 +0000
+@@ -64,16 +64,7 @@
+ class GfxPath;
+ class GfxFont;
+ class PDFDoc;
+-#ifndef SYSTEM_POPPLER
+ #define POPPLER_CHECK_VERSION(major,minor,micro) (0)
+-typedef GString GooString;
+-#else
+-#include <cpp/poppler-version.h>
+-#define POPPLER_CHECK_VERSION(major,minor,micro) \
+- (POPPLER_VERSION_MAJOR > (major) || \
+- (POPPLER_VERSION_MAJOR == (major) && POPPLER_VERSION_MINOR > (minor)) || \
+- (POPPLER_VERSION_MAJOR == (major) && POPPLER_VERSION_MINOR == (minor) && POPPLER_VERSION_MICRO >= (micro)))
+-#endif
+
+ namespace pdfi
+ {
diff --git a/libreoffice.spec b/libreoffice.spec
index c064e89..ca5be59 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -67,8 +67,12 @@ Source29: http://hg.services.openoffice.org/binaries/18f577b374d60b3c760a3
#backwards compatability.
Source30: http://hg.services.openoffice.org/binaries/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip
Source31: http://download.go-oo.org/extern/b4cae0700aa1c2aef7eb7f345365e6f1-translate-toolkit-1.8.1.tar.bz2
+%if %{defined rhel} && 0%{?rhel} < 7
+Source32: http://dev-www.libreoffice.org/src/0ff7d225d087793c8c2c680d77aac3e7-mdds_0.5.3.tar.bz2
+Source33: http://hg.services.openoffice.org/binaries/067201ea8b126597670b5eff72e1f66c-mythes-1.2.0.tar.gz
+%endif
BuildRequires: zip, findutils, autoconf, flex, bison, icu, gperf, gcc-c++
-BuildRequires: binutils, java-1.6.0-devel, boost-devel, zlib-devel
+BuildRequires: binutils, java-devel <= 1.6.0, boost-devel, zlib-devel
BuildRequires: python-devel, expat-devel, libxml2-devel, libxslt-devel, bc
BuildRequires: neon-devel, libcurl-devel, libidn-devel, pam-devel, cups-devel
BuildRequires: libXext-devel, libXt-devel, libICE-devel, libjpeg-devel, make
@@ -77,13 +81,19 @@ BuildRequires: db4-devel, sane-backends-devel, libicu-devel, perl-Archive-Zip
BuildRequires: freetype-devel, gtk2-devel, desktop-file-utils, hyphen-devel
BuildRequires: evolution-data-server-devel, libtextcat-devel, nss-devel
BuildRequires: gstreamer-devel, gstreamer-plugins-base-devel, openssl-devel
-BuildRequires: mdds-devel, lpsolve-devel, bsh, lucene, lucene-contrib
+BuildRequires: lpsolve-devel, bsh, lucene, lucene-contrib
BuildRequires: mesa-libGLU-devel, redland-devel, ant, ant-apache-regexp, rsync
BuildRequires: jakarta-commons-codec, jakarta-commons-httpclient, cppunit-devel
-BuildRequires: jakarta-commons-lang, poppler-devel, fontpackages-devel, junit4
-BuildRequires: pentaho-reporting-flow-engine, libXinerama-devel, mythes-devel
-BuildRequires: graphite2-devel, libwpg-devel, libwps-devel, vigra-devel
+BuildRequires: jakarta-commons-lang, poppler-devel, fontpackages-devel
+BuildRequires: pentaho-reporting-flow-engine, libXinerama-devel
+BuildRequires: vigra-devel
BuildRequires: font(:lang=en)
+%if %{defined rhel} && 0%{?rhel} < 7
+BuildRequires: hsqldb
+%else
+BuildRequires: mdds-devel, mythes-devel, graphite2-devel, libwpg-devel
+BuildRequires: libwps-devel, junit4, perl-Digest-MD5
+%endif
%if %{undefined rhel}
BuildRequires: kdelibs4-devel
%endif
@@ -136,6 +146,13 @@ Patch37: 0001-sw-fdo-39159-fdo-40482-temp-selection-print-doc.patch
Patch38: 0001-smath-does-not-handle-accents-in-MathML.patch
Patch39: 0001-fix-writing-of-strings-from-the-first-module.patch
Patch40: 0001-Confine-JDBC-driver-to-thread-affine-apartment-for-J.patch
+%if %{defined rhel} && 0%{?rhel} < 7
+Patch41: libreoffice-libwpd08-1.patch
+Patch42: libreoffice-libwpd08-2.patch
+Patch43: 0001-wpsimport-writerperfect.diff-WPS-Import-filter-core-.patch
+Patch44: libreoffice-gcj.patch
+Patch45: libreoffice-rhel6poppler.patch
+%endif
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
%define instdir %{_libdir}
@@ -820,6 +837,13 @@ mv -f redhat.soc extras/source/palettes/standard.soc
%patch38 -p1 -b .smath-does-not-handle-accents-in-MathML.patch
%patch39 -p1 -b .fix-writing-of-strings-from-the-first-module.patch
%patch40 -p1 -b .Confine-JDBC-driver-to-thread-affine-apartment-for-J.patch
+%if %{defined rhel} && 0%{?rhel} < 7
+%patch41 -p1 -b .libwpd08-1.patch
+%patch42 -p1 -R -b .libreoffice-libwpd08-2.patch
+%patch43 -p1 -R -b .wpsimport
+%patch44 -p1 -b .gcj.patch
+%patch45 -p0 -b .rhel6poppler.patch
+%endif
# these are horribly incomplete--empty translations and copied english
# strings with spattering of translated strings
@@ -857,8 +881,14 @@ export ARCH_FLAGS
export CFLAGS=$ARCH_FLAGS
export CXXFLAGS=$ARCH_FLAGS
-%if %{undefined rhel}
-%define distrooptions --enable-kde4
+%if %{defined rhel}
+%if 0%{?rhel} < 7
+%define distrooptions --disable-graphite --without-system-mythes --without-system-mdds --without-junit
+%else
+%define distrooptions --without-system-hsqldb
+%endif
+%else
+%define distrooptions --without-system-hsqldb --enable-kde4
%endif
autoconf
@@ -880,8 +910,7 @@ autoconf
--without-myspell-dicts --without-fonts --without-ppds --without-afms \
%{with_lang} --with-poor-help-localizations="$POORHELPS" \
--with-external-tar=`pwd`/ext_sources --with-java-target-version=1.5 \
- --with-external-libtextcat-data \
- --without-system-translate-toolkit --without-system-hsqldb \
+ --with-external-libtextcat-data --without-system-translate-toolkit \
%{distrooptions}
mkdir -p ext_sources
@@ -895,33 +924,15 @@ cp %{SOURCE28} ext_sources
cp %{SOURCE29} ext_sources
cp %{SOURCE30} ext_sources
cp %{SOURCE31} ext_sources
+%if %{defined rhel} && 0%{?rhel} < 7
+cp %{SOURCE32} ext_sources
+cp %{SOURCE33} ext_sources
+%endif
touch src.downloaded
. ./*[Ee]nv.[Ss]et.sh
./bootstrap
-#HANGING JAVA HACK
-cat << \EOF > solenv/bin/java
-#!/bin/sh
-status=1
-count=1
-while [ $status -ne 0 -a $count -lt 10 ]
-do
- timeout -k 5m 5m $REALJAVA $*
- status=$?
- if [ $status -ne 0 ]; then
- echo $REALJAVA hung, trying again, attempt $count
- fi
- count=$[count+1]
-done
-exit $status
-EOF
-chmod +x solenv/bin/java
-export REALJAVA=`which java`
-export PATH=solenv/bin:$PATH
-which java
-#HANGING JAVA HACK
-
cd instsetoo_native
if ! VERBOSE=true build --dlv_switch -link -P$NBUILDS --all -- -P$NDMAKES -s; then
build --dlv_switch -link --all
@@ -1345,7 +1356,12 @@ cd ../smoketestoo_native
unset WITH_LANG
#JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY="1" works around flawed accessibility check
#SAL_USE_VCLPLUGIN="svp" uses the headless plugin for these tests
+%if %{defined rhel} && 0%{?rhel} < 7
+unset SOLAR_JAVA
+JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY="1" SAL_USE_VCLPLUGIN="svp" timeout 2h build.pl
+%else
JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY="1" SAL_USE_VCLPLUGIN="svp" timeout -k 2m 2h build.pl
+%endif
%clean
rm -rf $RPM_BUILD_ROOT
@@ -1546,7 +1562,9 @@ rm -rf $RPM_BUILD_ROOT
%{basisinstdir}/program/libvbahelper%{SOPOST}.so
%{basisinstdir}/program/libvclplug_gen%{SOPOST}.so
%{basisinstdir}/program/libvclplug_gtk%{SOPOST}.so
+%if %{undefined rhel} || 0%{?rhel} >= 7
%{basisinstdir}/program/libwpgimport%{SOPOST}.so
+%endif
%{basisinstdir}/program/libxmlfa%{SOPOST}.so
%{basisinstdir}/program/libxmlfd%{SOPOST}.so
%{basisinstdir}/program/libxmx%{SOPOST}.so
@@ -1809,7 +1827,9 @@ done
%{basisinstdir}/help/en/sdatabase.*
%dir %{basisinstdir}/program
%dir %{basisinstdir}/program/classes
+%if %{undefined rhel} || 0%{?rhel} >= 7
%{basisinstdir}/program/classes/hsqldb.jar
+%endif
%{basisinstdir}/program/classes/sdbc_hsqldb.jar
%{basisinstdir}/program/libabp%{SOPOST}.so
%{basisinstdir}/program/libadabasui%{SOPOST}.so
@@ -1960,7 +1980,9 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
%{basisinstdir}/program/libhwp.so
%{basisinstdir}/program/liblwpft%{SOPOST}.so
%{basisinstdir}/program/libmsword%{SOPOST}.so
+%if %{undefined rhel} || 0%{?rhel} >= 7
%{basisinstdir}/program/libmsworks%{SOPOST}.so
+%endif
%{basisinstdir}/program/libswd%{SOPOST}.so
%{basisinstdir}/program/libswui%{SOPOST}.so
%{basisinstdir}/program/libt602filter%{SOPOST}.so
More information about the scm-commits
mailing list