summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@frugalware.org>2010-09-17 12:22:16 +0200
committerCĂ©dric Bosdonnat <cedricbosdo@openoffice.org>2010-09-17 13:16:36 +0200
commitdb6af6a208ed578625ef2df23f50ec982b562ca6 (patch)
tree399b57b0481df281ca92b5e74ec863c2ec462fb1
parent8793553ce119b16f521a324cb961e070132ba7ef (diff)
cws-vmiklos01.diff: Better RTF export filter
-rw-r--r--sw/source/filter/rtf/makefile.mk9
-rw-r--r--sw/source/filter/rtf/rtfnum.cxx3
-rw-r--r--sw/source/filter/rtf/swparrtf.cxx6
-rw-r--r--sw/source/filter/rtf/swparrtf.hxx2
-rw-r--r--sw/source/filter/ww8/README-rtf.txt226
-rw-r--r--sw/source/filter/ww8/docxexport.cxx125
-rw-r--r--sw/source/filter/ww8/docxexport.hxx22
-rw-r--r--sw/source/filter/ww8/docxexportfilter.cxx53
-rw-r--r--sw/source/filter/ww8/makefile.mk14
-rw-r--r--sw/source/filter/ww8/rtfattributeoutput.cxx3356
-rw-r--r--sw/source/filter/ww8/rtfattributeoutput.hxx573
-rw-r--r--sw/source/filter/ww8/rtfexport.cxx1240
-rw-r--r--sw/source/filter/ww8/rtfexport.hxx211
-rw-r--r--sw/source/filter/ww8/rtfexportfilter.cxx136
-rw-r--r--sw/source/filter/ww8/rtfexportfilter.hxx84
-rw-r--r--sw/source/filter/ww8/rtfimportfilter.cxx134
-rw-r--r--sw/source/filter/ww8/rtfimportfilter.hxx74
-rw-r--r--sw/source/filter/ww8/rtfsdrexport.cxx577
-rw-r--r--sw/source/filter/ww8/rtfsdrexport.hxx111
-rw-r--r--sw/source/filter/ww8/wrtw8esh.cxx66
-rw-r--r--sw/source/filter/ww8/wrtw8nds.cxx147
-rw-r--r--sw/source/filter/ww8/wrtw8num.cxx3
-rw-r--r--sw/source/filter/ww8/wrtw8sty.cxx36
-rwxr-xr-xsw/source/filter/ww8/wrtww8.cxx2
-rw-r--r--sw/source/filter/ww8/wrtww8.hxx93
-rw-r--r--sw/source/filter/ww8/ww8atr.cxx2
-rwxr-xr-xsw/util/msword.map3
27 files changed, 7062 insertions, 246 deletions
diff --git a/sw/source/filter/rtf/makefile.mk b/sw/source/filter/rtf/makefile.mk
index 2ff764d730..e7310f2d0f 100644
--- a/sw/source/filter/rtf/makefile.mk
+++ b/sw/source/filter/rtf/makefile.mk
@@ -46,18 +46,15 @@ CDEFS=$(CDEFS) -Dmydebug
EXCEPTIONSFILES= \
$(SLO)$/rtffly.obj \
$(SLO)$/rtfnum.obj \
- $(SLO)$/swparrtf.obj \
- $(SLO)$/wrtrtf.obj
+ $(SLO)$/swparrtf.obj
-SLOFILES = \
- $(SLO)$/rtfatr.obj \
+SLOFILES = \
$(SLO)$/rtffld.obj \
$(SLO)$/rtffly.obj \
$(SLO)$/rtfnum.obj \
$(SLO)$/rtftbl.obj \
- $(SLO)$/swparrtf.obj \
- $(SLO)$/wrtrtf.obj
+ $(SLO)$/swparrtf.obj
# --- Tagets -------------------------------------------------------
diff --git a/sw/source/filter/rtf/rtfnum.cxx b/sw/source/filter/rtf/rtfnum.cxx
index c8aa3987c3..07b2076c95 100644
--- a/sw/source/filter/rtf/rtfnum.cxx
+++ b/sw/source/filter/rtf/rtfnum.cxx
@@ -22,7 +22,6 @@
#include <fltini.hxx>
#include <swtypes.hxx>
#include <swparrtf.hxx>
-#include <wrtrtf.hxx>
#include <ndtxt.hxx>
#include <doc.hxx>
#include <docary.hxx>
@@ -1102,6 +1101,7 @@ BOOL lcl_IsExportNumRule( const SwNumRule& rRule, BYTE* pEnd = 0 )
return nLvl != nEnd;
}
+#if 0
void SwRTFWriter::OutRTFListTab()
{
ByteString sOverrideList;
@@ -1430,3 +1430,4 @@ BOOL SwRTFWriter::OutListNum( const SwTxtNode& rNd )
}
return bRet;
}
+#endif
diff --git a/sw/source/filter/rtf/swparrtf.cxx b/sw/source/filter/rtf/swparrtf.cxx
index fccac64848..196ac0406a 100644
--- a/sw/source/filter/rtf/swparrtf.cxx
+++ b/sw/source/filter/rtf/swparrtf.cxx
@@ -179,6 +179,12 @@ ULONG RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const S
return nRet;
}
+ULONG RtfReader::Read(SvStream* pStream, SwDoc& rDoc, const String& rBaseURL, SwPaM& rPam)
+{
+ pStrm = pStream;
+ return Read(rDoc, rBaseURL, rPam, rBaseURL);
+}
+
SwRTFParser::SwRTFParser(SwDoc* pD,
uno::Reference<document::XDocumentProperties> i_xDocProps,
const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL,
diff --git a/sw/source/filter/rtf/swparrtf.hxx b/sw/source/filter/rtf/swparrtf.hxx
index a5a943fa46..8ff6878d3f 100644
--- a/sw/source/filter/rtf/swparrtf.hxx
+++ b/sw/source/filter/rtf/swparrtf.hxx
@@ -81,6 +81,8 @@ struct SvxRTFPictureType;
class RtfReader: public Reader
{
virtual ULONG Read( SwDoc &, const String& rBaseURL, SwPaM &,const String &);
+public:
+ virtual ULONG Read( SvStream* pStrm, SwDoc &, const String& rBaseURL, SwPaM &);
};
class SwNodeIdx : public SvxNodeIdx
diff --git a/sw/source/filter/ww8/README-rtf.txt b/sw/source/filter/ww8/README-rtf.txt
new file mode 100644
index 0000000000..661813abc9
--- /dev/null
+++ b/sw/source/filter/ww8/README-rtf.txt
@@ -0,0 +1,226 @@
+
+---------------------------------------------------------------------
+
+Summary of new features in RtfExport
+
+---------------------------------------------------------------------
+
+Miklos Vajna
+
+<vmiklos@frugalware.org>
+---------------------------------------------------------------------
+
+Table of Contents
+
+1. Introduction
+
+ 1.1. Terminology
+ 1.2. General
+
+2. List if fixed bugs
+3. List of new features
+
+ 3.1. Nested tables
+ 3.2. Character properties
+ 3.3. Sections
+ 3.4. Graphics
+ 3.5. Bookmarks
+ 3.6. Fields
+ 3.7. Drawing
+ 3.8. Form fields
+ 3.9. OLE objects
+
+4. Changes in the source code outside RTF
+
+
+---------------------------------------------------------------------
+
+1. Introduction
+
+---------------------------------------------------------------------
+
+The biggest difference is that the new exporter is an UNO component,
+and it?s based on the MSWord base classes, the vision here is that
+this way much less code can achieve the same set of features,
+reducing the amount of duplicated code.
+
+
+1.1. Terminology
+
+--------------
+
+ * The "MSO OK, OOo KO" and similar abbreviations describe if the
+ given new feature is supported by the OOo RTF importer or it can
+ be tested using Microsoft Office.
+ * RtfExport refers to the new UNO-based exporter, RtfWriter refers
+ to the old built-in one.
+
+
+1.2. General
+
+--------------
+
+RtfWriter sometimes created documents where the first { is closed in
+the middle of the document. MSO ignores this problem, but OOo stops
+parsing the rest of the document if this happens, in other words
+everything after such a bug is ignored. This can be reproduced by for
+example parprops.odt, but it?s triggered in several other cases as
+well. RtfExport has no automatic prevention for this, either - but
+during development I primarily test the output with OOo, so hopefully
+the bug will pop up less frequently.
+
+
+---------------------------------------------------------------------
+
+2. List if fixed bugs
+
+---------------------------------------------------------------------
+
+ * http://www.openoffice.org/issues/show_bug.cgi?id=51469 postit
+ fields
+ * http://www.openoffice.org/issues/show_bug.cgi?id=66619 page
+ margins
+ * http://www.openoffice.org/issues/show_bug.cgi?id=69856 page
+ numbers
+ * http://www.openoffice.org/issues/show_bug.cgi?id=81569 { and } in
+ document title
+ * http://www.openoffice.org/issues/show_bug.cgi?id=84703 redlines
+ * http://www.openoffice.org/issues/show_bug.cgi?id=91166 russian
+ chars
+ * http://www.openoffice.org/issues/show_bug.cgi?id=92673 bookmarks
+ across tables
+ * http://www.openoffice.org/issues/show_bug.cgi?id=100507 ole
+ object export
+ * http://www.openoffice.org/issues/show_bug.cgi?id=103993 same as #
+ 81569 just for doc comments
+ * http://www.openoffice.org/issues/show_bug.cgi?id=106677
+ listoverride index starts at zero
+ * http://www.openoffice.org/issues/show_bug.cgi?id=38344 enhanced
+ character space
+
+
+---------------------------------------------------------------------
+
+3. List of new features
+
+---------------------------------------------------------------------
+
+
+3.1. Nested tables
+
+--------------
+
+This was new in Word2000 and it?s now supported by RtfExport (MSO OK,
+OOo KO)
+
+
+3.2. Character properties
+
+--------------
+
+The followings are now supported:
+
+ * blinking (MSO OK, OOo KO)
+ * expanded spacing (MSO OK, OOo OK)
+ * pair kerning (MSO OK, OOo OK)
+
+
+3.3. Sections
+
+--------------
+
+RtfExport writes:
+
+ * column breaks (MSO OK, OOo OK)
+ * special breaks (when the next page should be an odd or an even
+ page; MSO OK, OOo KO)
+ * the write-protected property of sections is experted properly
+ (MSO OK, OOo KO)
+ * better page numbers (inherited type from page styles, restarts;
+ MSO OK, OOo KO)
+ * line numbering (MSO OK, OOo KO)
+
+
+3.4. Graphics
+
+--------------
+
+PNG graphics are exported in WMF format as well, so that not only MSO
+and OOo can display graphics from the output document, but Wordpad as
+well.
+
+
+3.5. Bookmarks
+
+--------------
+
+Implicit bookmarks like reference to a footnote did not work in OOo
+(one got an Error: Reference source not found message when opening
+the result), this now works as expected. (MSO OK - the importer
+previously autocorrected this as well, OO OK)
+
+
+3.6. Fields
+
+--------------
+
+ * Table of contents is now written as a field, so it?s properly
+ read-only (MSO OK, OOo KO)
+ * Postit comments are now exported. (MSO OK, OOo KO)
+
+
+3.7. Drawing
+
+--------------
+
+Drawing objects for Word 97 through Word 2007 (shapes) are now
+implemented:
+
+ * basic shapes (rectangle, ellipse, etc.)
+ * lines, including free-form ones
+ * texts, including vertical ones and their (paragraph and
+ character) formatting
+
+(MSO OK, OOo KO)
+
+
+3.8. Form fields
+
+--------------
+
+All types supported by the RTF format are exported, namely:
+
+ * text boxes
+ * check boxes
+ * list boxes
+
+(MSO OK, OOo KO)
+
+
+3.9. OLE objects
+
+--------------
+
+Their result is exported as a picture - RtfWriter did not export
+anything. (MSO OK, OOo OK)
+
+For math, the native data is written as well, so you can edit the
+object, too. (MSO OK, OOo KO)
+
+
+---------------------------------------------------------------------
+
+4. Changes in the source code outside RTF
+
+---------------------------------------------------------------------
+
+These are refactorings I needed for RTF. To my best knowledge they do
+not change the output of other filters from a user?s point of view.
+
+ * The code that splits runs according to bookmarks is moved from
+ DocxExport to MSWordExportBase
+ * WW8_SdrAttrIter has been refactored to MSWord_SdrAttrIter
+ * MSWordExportBase::SubstituteBullet can avoid replacing bullets
+ * wwFontHelper::InitFontTable can really load all fonts
+ * An obvious typo in WW8AttributeOutput::CharTwoLines has been
+ fixed
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 07e2b54f63..1bb810c608 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -116,131 +116,6 @@ bool DocxExport::CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich )
return true;
}
-bool DocxExport::GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt,
- xub_StrLen nEnd, IMarkVector& rArr )
-{
- IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
- ULONG nNd = rNd.GetIndex( );
-
- const sal_Int32 nMarks = pMarkAccess->getMarksCount();
- for ( sal_Int32 i = 0; i < nMarks; i++ )
- {
- IMark* pMark = ( pMarkAccess->getMarksBegin() + i )->get();
-
- // Only keep the bookmarks starting or ending in this node
- if ( pMark->GetMarkStart().nNode == nNd ||
- pMark->GetMarkEnd().nNode == nNd )
- {
- xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex();
- xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
-
- // Keep only the bookmars starting or ending in the snippet
- bool bIsStartOk = ( nBStart >= nStt ) && ( nBStart <= nEnd );
- bool bIsEndOk = ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
-
- if ( bIsStartOk || bIsEndOk )
- rArr.push_back( pMark );
- }
- }
- return ( rArr.size() > 0 );
-}
-
-class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool >
-{
-public:
- inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
- {
- xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
- xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
-
- return nOEnd < nTEnd;
- }
-};
-
-bool DocxExport::NearestBookmark( xub_StrLen& rNearest )
-{
- bool bHasBookmark = false;
-
- if ( m_rSortedMarksStart.size( ) > 0 )
- {
- IMark* pMarkStart = m_rSortedMarksStart.front();
- rNearest = pMarkStart->GetMarkStart().nContent.GetIndex();
- bHasBookmark = true;
- }
-
- if ( m_rSortedMarksEnd.size( ) > 0 )
- {
- IMark* pMarkEnd = m_rSortedMarksEnd[0];
- if ( !bHasBookmark )
- rNearest = pMarkEnd->GetMarkEnd().nContent.GetIndex();
- else
- rNearest = std::min( rNearest, pMarkEnd->GetMarkEnd().nContent.GetIndex() );
- bHasBookmark = true;
- }
-
- return bHasBookmark;
-}
-
-xub_StrLen DocxExport::GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos )
-{
- // Get the bookmarks for the normal run
- xub_StrLen nNextPos = MSWordExportBase::GetNextPos( pAttrIter, rNode, nAktPos );
-
- GetSortedBookmarks( rNode, nAktPos, nNextPos - nAktPos );
-
- xub_StrLen nNextBookmark = nNextPos;
- NearestBookmark( nNextPos );
-
- return std::min( nNextPos, nNextBookmark );
-}
-
-void DocxExport::UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd )
-{
- xub_StrLen nNextPos;
-
- // either no bookmark, or it is not at the current position
- if ( !NearestBookmark( nNextPos ) || nNextPos > nAktPos )
- {
- MSWordExportBase::UpdatePosition( pAttrIter, nAktPos, nEnd );
- }
-}
-
-void DocxExport::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
-{
- IMarkVector aMarksStart;
- if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) )
- {
- IMarkVector aSortedEnd;
- IMarkVector aSortedStart;
- for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end();
- it < end; ++it )
- {
- IMark* pMark = (*it);
-
- // Remove the positions egals to the current pos
- xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
- xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
-
- if ( nStart > nAktPos )
- aSortedStart.push_back( pMark );
-
- if ( nEnd > nAktPos )
- aSortedEnd.push_back( pMark );
- }
-
- // Sort the bookmarks by end position
- std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
-
- m_rSortedMarksStart.swap( aSortedStart );
- m_rSortedMarksEnd.swap( aSortedEnd );
- }
- else
- {
- m_rSortedMarksStart.clear( );
- m_rSortedMarksEnd.clear( );
- }
-}
-
void DocxExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
{
std::vector< OUString > aStarts;
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 5873f955d3..1bf9e22fbc 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -76,11 +76,6 @@ class DocxExport : public MSWordExportBase
/// Footer counter.
sal_Int32 m_nFooters;
- /// Used to split the runs according to the bookmarks start and ends
- typedef std::vector< ::sw::mark::IMark* > IMarkVector;
- IMarkVector m_rSortedMarksStart;
- IMarkVector m_rSortedMarksEnd;
-
/// Exporter of the VML shapes.
oox::vml::VMLExport *m_pVMLExport;
@@ -163,24 +158,7 @@ protected:
const SwFmtPageDesc* pNewPgDescFmt = 0,
const SwPageDesc* pNewPgDesc = 0 );
- /// Get the next position in the text node to output
- virtual xub_StrLen GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos );
-
- /// Update the information for GetNextPos().
- virtual void UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd );
-
private:
- /// Find the nearest bookmark from the current position.
- ///
- /// Returns false when there is no bookmark.
- bool NearestBookmark( xub_StrLen& rNearest );
-
- void GetSortedBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos,
- xub_StrLen nLen );
-
- bool GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt, xub_StrLen nEnd,
- IMarkVector& rArr );
-
/// Setup pStyles and write styles.xml
void InitStyles();
diff --git a/sw/source/filter/ww8/docxexportfilter.cxx b/sw/source/filter/ww8/docxexportfilter.cxx
index 7004f0853e..bdf6616a0b 100644
--- a/sw/source/filter/ww8/docxexportfilter.cxx
+++ b/sw/source/filter/ww8/docxexportfilter.cxx
@@ -1,7 +1,7 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ *
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
@@ -26,6 +26,8 @@
************************************************************************/
#include "docxexportfilter.hxx"
+#include "rtfexportfilter.hxx"
+#include "rtfimportfilter.hxx"
#include "docxexport.hxx"
#include <docsh.hxx>
@@ -136,7 +138,7 @@ SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceMan
try
{
uno::Reference< registry::XRegistryKey > xNewKey1(
- static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(
+ static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(
OUString::createFromAscii( IMPL_NAME "/UNO/SERVICES/" ) ) );
xNewKey1->createKey( DocxExport_getSupportedServiceNames().getConstArray()[0] );
@@ -144,7 +146,35 @@ SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceMan
}
catch( registry::InvalidRegistryException& )
{
- OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+ OSL_ENSURE( sal_False, "### InvalidRegistryException (docx)!" );
+ }
+
+ try
+ {
+ uno::Reference< registry::XRegistryKey > xNewKey1(
+ static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(
+ OUString::createFromAscii( IMPL_NAME_RTFEXPORT "/UNO/SERVICES/" ) ) );
+ xNewKey1->createKey( RtfExport_getSupportedServiceNames().getConstArray()[0] );
+
+ bRet = sal_True;
+ }
+ catch( registry::InvalidRegistryException& )
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException (rtfexport)!" );
+ }
+
+ try
+ {
+ uno::Reference< registry::XRegistryKey > xNewKey1(
+ static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(
+ OUString::createFromAscii( IMPL_NAME_RTFIMPORT "/UNO/SERVICES/" ) ) );
+ xNewKey1->createKey( RtfExport_getSupportedServiceNames().getConstArray()[0] );
+
+ bRet = sal_True;
+ }
+ catch( registry::InvalidRegistryException& )
+ {
+ OSL_ENSURE( sal_False, "### InvalidRegistryException (rtfimport)!" );
}
}
@@ -157,6 +187,7 @@ SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceMan
SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /* pRegistryKey */ )
{
+ OSL_TRACE("%s, pImplName is '%s'", OSL_THIS_FUNC, pImplName);
uno::Reference< lang::XSingleServiceFactory > xFactory;
void* pRet = 0;
@@ -169,6 +200,22 @@ SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplN
DocxExport_getImplementationName(),
DocxExport_createInstance,
DocxExport_getSupportedServiceNames() ) );
+ } else if ( rtl_str_compare( pImplName, IMPL_NAME_RTFEXPORT ) == 0 ) {
+ const OUString aServiceName( OUString::createFromAscii( IMPL_NAME_RTFEXPORT ) );
+
+ xFactory = uno::Reference< lang::XSingleServiceFactory >( ::cppu::createSingleFactory(
+ reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
+ RtfExport_getImplementationName(),
+ RtfExport_createInstance,
+ RtfExport_getSupportedServiceNames() ) );
+ } else if ( rtl_str_compare( pImplName, IMPL_NAME_RTFIMPORT ) == 0 ) {
+ const OUString aServiceName( OUString::createFromAscii( IMPL_NAME_RTFIMPORT ) );
+
+ xFactory = uno::Reference< lang::XSingleServiceFactory >( ::cppu::createSingleFactory(
+ reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
+ RtfImport_getImplementationName(),
+ RtfImport_createInstance,
+ RtfImport_getSupportedServiceNames() ) );
}
if ( xFactory.is() )
diff --git a/sw/source/filter/ww8/makefile.mk b/sw/source/filter/ww8/makefile.mk
index 653c36fbef..f3638e28a9 100644
--- a/sw/source/filter/ww8/makefile.mk
+++ b/sw/source/filter/ww8/makefile.mk
@@ -68,7 +68,12 @@ EXCEPTIONSFILES = \
$(SLO)$/WW8TableInfo.obj \
$(SLO)$/WW8FFData.obj \
$(SLO)$/WW8Sttbf.obj \
- $(SLO)$/WW8FibData.obj
+ $(SLO)$/WW8FibData.obj \
+ $(SLO)$/rtfexportfilter.obj \
+ $(SLO)$/rtfimportfilter.obj \
+ $(SLO)$/rtfattributeoutput.obj \
+ $(SLO)$/rtfsdrexport.obj \
+ $(SLO)$/rtfexport.obj
SLOFILES = \
@@ -100,7 +105,12 @@ SLOFILES = \
$(SLO)$/WW8TableInfo.obj \
$(SLO)$/WW8FFData.obj \
$(SLO)$/WW8Sttbf.obj \
- $(SLO)$/WW8FibData.obj
+ $(SLO)$/WW8FibData.obj \
+ $(SLO)$/rtfexportfilter.obj \
+ $(SLO)$/rtfimportfilter.obj \
+ $(SLO)$/rtfattributeoutput.obj \
+ $(SLO)$/rtfsdrexport.obj \
+ $(SLO)$/rtfexport.obj
# --- Tagets -------------------------------------------------------
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
new file mode 100644
index 0000000000..c5ac3b15f0
--- /dev/null
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -0,0 +1,3356 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtfattributeoutput.hxx"
+#include "rtfexport.hxx"
+#include "rtfsdrexport.hxx"
+#include "writerwordglue.hxx"
+#include "wrtww8.hxx"
+#include "ww8par.hxx"
+#include "fmtcntnt.hxx"
+#include "fmtsrnd.hxx"
+#include "fchrfmt.hxx"
+#include "tgrditem.hxx"
+#include "fmtruby.hxx"
+#include "charfmt.hxx"
+#include "breakit.hxx"
+
+#include <i18npool/mslangid.hxx>
+
+#include <hintids.hxx>
+
+#include <svl/poolitem.hxx>
+#include <svtools/rtfkeywd.hxx>
+
+#include <editeng/fontitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/hyznitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <editeng/pgrditem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svdouno.hxx>
+#include <filter/msfilter/msoleexp.hxx>
+
+#include <docufld.hxx>
+#include <flddropdown.hxx>
+#include <format.hxx>
+#include <fmtclds.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtfld.hxx>
+#include <fmtfsize.hxx>
+#include <fmtftn.hxx>
+#include <fmtrowsplt.hxx>
+#include <fmtline.hxx>
+#include <fmtanchr.hxx>
+#include <frmfmt.hxx>
+#include <frmatr.hxx>
+#include <ftninfo.hxx>
+#include <htmltbl.hxx>
+#include <ndgrf.hxx>
+#include <ndtxt.hxx>
+#include <node.hxx>
+#include <pagedesc.hxx>
+#include <paratr.hxx>
+#include <swmodule.hxx>
+#include <swtable.hxx>
+#include <txtftn.hxx>
+#include <txtinet.hxx>
+#include <numrule.hxx>
+#include <grfatr.hxx>
+#include <ndole.hxx>
+#include <lineinfo.hxx>
+#include <rtf.hxx>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+
+#include <tools/color.hxx>
+
+#include <vcl/cvtgrf.hxx>
+
+#include <com/sun/star/i18n/ScriptType.hdl>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include <osl/diagnose.h>
+
+using rtl::OString;
+using rtl::OStringBuffer;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using rtl::OUStringToOString;
+
+using namespace nsSwDocInfoSubType;
+using namespace nsFieldFlags;
+using namespace sw::util;
+using namespace ::com::sun::star;
+
+static OString OutTBLBorderLine(RtfExport &rExport, const SvxBorderLine* pLine, const sal_Char* pStr)
+{
+ OStringBuffer aRet;
+ aRet.append(pStr);
+ if( pLine->GetInWidth() )
+ {
+ // double line
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDB);
+ switch( pLine->GetInWidth() )
+ {
+ case DEF_LINE_WIDTH_0:
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW "15");
+ break;
+ case DEF_LINE_WIDTH_1:
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW "30");
+ break;
+ case DEF_LINE_WIDTH_2:
+ case DEF_LINE_WIDTH_3:
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW "45");
+ break;
+ }
+ }
+ else
+ {
+ // single line
+ if( DEF_LINE_WIDTH_1 >= pLine->GetOutWidth() )
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRS OOO_STRING_SVTOOLS_RTF_BRDRW).append((sal_Int32)pLine->GetOutWidth());
+ else
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTH OOO_STRING_SVTOOLS_RTF_BRDRW).append((sal_Int32)pLine->GetOutWidth() / 2);
+ }
+
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRCF);
+ aRet.append((sal_Int32)rExport.GetColor(pLine->GetColor()));
+ return aRet.makeStringAndClear();
+}
+
+static OString OutBorderLine(RtfExport &rExport, const SvxBorderLine* pLine,
+ const sal_Char* pStr, USHORT nDist)
+{
+ OStringBuffer aRet;
+ aRet.append(OutTBLBorderLine(rExport, pLine, pStr));
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRSP);
+ aRet.append((sal_Int32)nDist);
+ return aRet.makeStringAndClear();
+}
+
+static OString OutBorderLine( RtfExport &rExport, const SvxBorderLine* pLine,
+ const char* pStr )
+{
+ OStringBuffer aRet;
+ aRet.append(pStr);
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNCOL);
+ aRet.append((sal_Int32)rExport.GetColor( pLine->GetColor() ) );
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNIN);
+ aRet.append((sal_Int32)pLine->GetInWidth());
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNOUT);
+ aRet.append((sal_Int32)pLine->GetOutWidth());
+ aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNDIST);
+ aRet.append((sal_Int32)pLine->GetDistance());
+ return aRet.makeStringAndClear();
+}
+
+void RtfAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ /*
+ You would have thought that
+ m_rExport.Strm() << (bIsRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficent here ,
+ but looks like word needs to see the other directional token to be
+ satisified that all is kosher, otherwise it seems in ver 2003 to go and
+ semi-randomlyly stick strike through about the place. Perhaps
+ strikethrough is some ms developers "something is wrong signal" debugging
+ code that we're triggering ?
+ */
+ if (bIsRTL) {
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
+ m_aStylesEnd.append(' ');
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
+ } else {
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
+ m_aStylesEnd.append(' ');
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
+ }
+
+ switch (nScript) {
+ case i18n::ScriptType::LATIN:
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
+ break;
+ case i18n::ScriptType::ASIAN:
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_DBCH);
+ break;
+ case i18n::ScriptType::COMPLEX:
+ /* noop */
+ break;
+ default:
+ /* should not happen? */
+ break;
+ }
+}
+
+void RtfAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // Output table/table row/table cell starts if needed
+ if ( pTextNodeInfo.get() )
+ {
+ sal_uInt32 nRow = pTextNodeInfo->getRow();
+ sal_uInt32 nCell = pTextNodeInfo->getCell();
+
+ // New cell/row?
+ if ( m_nTableDepth > 0 && !m_bTableCellOpen )
+ {
+ ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
+ if ( pDeepInner->getCell() == 0 )
+ StartTableRow( pDeepInner );
+
+ StartTableCell( pDeepInner );
+ }
+
+ if ( nRow == 0 && nCell == 0 )
+ {
+ // Do we have to start the table?
+ // [If we are at the rigth depth already, it means that we
+ // continue the table cell]
+ sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
+
+ if ( nCurrentDepth > m_nTableDepth )
+ {
+ // Start all the tables that begin here
+ for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
+ {
+ ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
+
+ StartTable( pInner );
+ StartTableRow( pInner );
+ StartTableCell( pInner );
+ }
+
+ m_nTableDepth = nCurrentDepth;
+ }
+ }
+ }
+
+ OSL_ENSURE(m_aRun.getLength() == 0, "m_aRun is not empty");
+}
+
+void RtfAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ FinishTableRowCell( pTextNodeInfoInner );
+
+ OStringBuffer aParagraph;
+
+ aParagraph.append(m_aRun.makeStringAndClear());
+ aParagraph.append(m_aAfterRuns.makeStringAndClear());
+ if (m_bTblAfterCell)
+ m_bTblAfterCell = false;
+ else
+ {
+ aParagraph.append(m_rExport.sNewLine);
+ aParagraph.append(OOO_STRING_SVTOOLS_RTF_PAR);
+ aParagraph.append(' ');
+ }
+ if (m_nColBreakNeeded)
+ {
+ aParagraph.append(OOO_STRING_SVTOOLS_RTF_COLUMN);
+ m_nColBreakNeeded = false;
+ }
+
+ if (!m_bBufferSectionHeaders)
+ m_rExport.Strm() << aParagraph.makeStringAndClear();
+ else
+ m_aSectionHeaders.append(aParagraph.makeStringAndClear());
+}
+
+void RtfAttributeOutput::EmptyParagraph()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << m_rExport.sNewLine << OOO_STRING_SVTOOLS_RTF_PAR << ' ';
+}
+
+void RtfAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
+
+ // output page/section breaks
+ SwNodeIndex aNextIndex( rNode, 1 );
+ m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
+ m_bBufferSectionBreaks = true;
+
+ // output section headers / footers
+ if (!m_bBufferSectionHeaders)
+ m_rExport.Strm() << m_aSectionHeaders.makeStringAndClear();
+
+ if ( aNextIndex.GetNode().IsTxtNode() )
+ {
+ const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
+ m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode );
+ }
+ else if ( aNextIndex.GetNode().IsTableNode() )
+ {
+ const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
+ const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
+ m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
+ }
+ m_bBufferSectionBreaks = false;
+
+ OStringBuffer aPar;
+ if (!m_rExport.bRTFFlySyntax)
+ {
+ aPar.append(OOO_STRING_SVTOOLS_RTF_PARD);
+ aPar.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
+ aPar.append(' ');
+ }
+ if (!m_bBufferSectionHeaders)
+ m_rExport.Strm() << aPar.makeStringAndClear();
+ else
+ m_aSectionHeaders.append(aPar.makeStringAndClear());
+}
+
+void RtfAttributeOutput::EndParagraphProperties()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ m_aStyles.append(m_aStylesEnd.makeStringAndClear());
+ m_rExport.Strm() << m_aStyles.makeStringAndClear();
+}
+
+void RtfAttributeOutput::StartRun( const SwRedlineData* pRedlineData )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aRun.append('{');
+
+ // if there is some redlining in the document, output it
+ Redline( pRedlineData );
+
+ OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
+}
+
+void RtfAttributeOutput::EndRun()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ m_aRun.append(m_rExport.sNewLine);
+ m_aRun.append(m_aRunText.makeStringAndClear());
+ m_aRun.append('}');
+}
+
+void RtfAttributeOutput::StartRunProperties()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
+}
+
+void RtfAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ m_aStyles.append(m_aStylesEnd.makeStringAndClear());
+ m_aRun.append(m_aStyles.makeStringAndClear());
+}
+
+void RtfAttributeOutput::RunText( const String& rText, rtl_TextEncoding eCharSet )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ RawText( rText, 0, eCharSet );
+}
+
+OStringBuffer& RtfAttributeOutput::RunText()
+{
+ return m_aRunText;
+}
+
+OStringBuffer& RtfAttributeOutput::Styles()
+{
+ return m_aStyles;
+}
+
+void RtfAttributeOutput::RawText( const String& rText, bool /*bForceUnicode*/, rtl_TextEncoding eCharSet )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ m_aRunText.append(m_rExport.OutString(rText, eCharSet));
+}
+
+void RtfAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, const SwFmtRuby& /*rRuby*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::EndRuby()
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+bool RtfAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append('{');
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FIELD);
+ m_aStyles.append('{');
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FLDINST);
+ m_aStyles.append(" HYPERLINK ");
+
+ String sURL( rUrl );
+ if( sURL.Len() )
+ {
+ m_aStyles.append("\"");
+ m_aStyles.append(m_rExport.OutString( sURL, m_rExport.eCurrentEncoding));
+ m_aStyles.append("\" ");
+ }
+
+ if( rTarget.Len() )
+ {
+ m_aStyles.append("\\\\t \"");
+ m_aStyles.append(m_rExport.OutString( rTarget, m_rExport.eCurrentEncoding));
+ m_aStyles.append("\" ");
+ }
+
+ m_aStyles.append("}");
+ return true;
+}
+
+bool RtfAttributeOutput::EndURL()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // close the fldrslt group
+ m_aRunText.append('}');
+ // close the field group
+ m_aRunText.append('}');
+ return true;
+}
+
+void RtfAttributeOutput::FieldVanish( const String& /*rTxt*/, ww::eField /*eType*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::Redline( const SwRedlineData* pRedline )
+{
+ if (!pRedline)
+ return;
+
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if (pRedline->GetType() == nsRedlineType_t::REDLINE_INSERT)
+ {
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVISED);
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVAUTH);
+ m_aRun.append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVDTTM);
+ }
+ else if(pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
+ {
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_DELETED);
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL);
+ m_aRun.append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL);
+ }
+ m_aRun.append((sal_Int32)sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()));
+ m_aRun.append(' ');
+}
+
+void RtfAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, USHORT /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t /*pTextNodeInfoInner*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::ParagraphStyle( USHORT nStyle )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ OString *pStyle = m_rExport.GetStyle(nStyle);
+ OStringBuffer aStyle;
+ aStyle.append(OOO_STRING_SVTOOLS_RTF_S);
+ aStyle.append((sal_Int32)nStyle);
+ if (pStyle)
+ aStyle.append(pStyle->getStr());
+ if (!m_bBufferSectionHeaders)
+ m_rExport.Strm() << aStyle.makeStringAndClear();
+ else
+ m_aSectionHeaders.append(aStyle.makeStringAndClear());
+}
+
+void RtfAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_INTBL);
+ if ( m_nTableDepth > 1 )
+ {
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ITAP);
+ m_aStyles.append((sal_Int32)m_nTableDepth);
+ }
+}
+
+void RtfAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop */
+}
+
+void RtfAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( !m_pTableWrt )
+ InitTableHelper( pTableTextNodeInfoInner );
+
+ const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
+ SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
+
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TROWD);
+ TableOrientation( pTableTextNodeInfoInner );
+ TableBidi( pTableTextNodeInfoInner );
+ TableHeight( pTableTextNodeInfoInner );
+ TableCanSplit( pTableTextNodeInfoInner );
+
+ // Cell margins
+ const SvxBoxItem& rBox = pFmt->GetBox( );
+ static const USHORT aBorders[] =
+ {
+ BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
+ };
+
+ static const char* aRowPadNames[] =
+ {
+ OOO_STRING_SVTOOLS_RTF_TRPADDT, OOO_STRING_SVTOOLS_RTF_TRPADDL, OOO_STRING_SVTOOLS_RTF_TRPADDB, OOO_STRING_SVTOOLS_RTF_TRPADDR
+ };
+
+ static const char* aRowPadUnits[] =
+ {
+ OOO_STRING_SVTOOLS_RTF_TRPADDFT, OOO_STRING_SVTOOLS_RTF_TRPADDFL, OOO_STRING_SVTOOLS_RTF_TRPADDFB, OOO_STRING_SVTOOLS_RTF_TRPADDFR
+ };
+
+ for (int i = 0; i < 4; ++i)
+ {
+ m_aRowDefs.append(aRowPadUnits[i]);
+ m_aRowDefs.append((sal_Int32)3);
+ m_aRowDefs.append(aRowPadNames[i]);
+ m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
+ }
+
+ // The cell-dependent properties
+ const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
+ SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
+ SwTwips nSz = 0;
+ Point aPt;
+ SwRect aRect( pFmt->FindLayoutRect( false, &aPt ));
+ SwTwips nPageSize = aRect.Width();
+ SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
+ for( USHORT i = 0; i < pRow->GetCells().Count(); i++ )
+ {
+ SwWriteTableCell *pCell = pRow->GetCells( )[ i ];
+ const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
+
+ pTableTextNodeInfoInner->setCell( i );
+ TableCellProperties(pTableTextNodeInfoInner);
+
+ // Right boundary: this can't be in TableCellProperties as the old
+ // value of nSz is needed.
+ nSz += pCellFmt->GetFrmSize().GetWidth();
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CELLX);
+ SwTwips nCalc = nSz;
+ nCalc *= nPageSize;
+ nCalc /= nTblSz;
+ m_aRowDefs.append( (sal_Int32)(pFmt->GetLRSpace().GetLeft() + nCalc) );
+ }
+}
+
+void RtfAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /*
+ * The function name is a bit misleading: given that we write borders
+ * before each row, we just have borders, not default ones. Additionally,
+ * this function actually writes borders for a specific cell only and is
+ * called for each cell.
+ */
+
+ const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
+ SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
+ const SvxBoxItem& rDefault = pFmt->GetBox( );
+ const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
+ SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
+ SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
+ const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
+ const SfxPoolItem* pItem;
+ if (SFX_ITEM_SET == pCellFmt->GetAttrSet().GetItemState(RES_BOX, TRUE, &pItem))
+ {
+ const SvxBoxItem& rBox = (SvxBoxItem&)*pItem;
+ static const USHORT aBorders[] =
+ {
+ BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
+ };
+ static const char* aBorderNames[] =
+ {
+ OOO_STRING_SVTOOLS_RTF_CLBRDRT, OOO_STRING_SVTOOLS_RTF_CLBRDRL, OOO_STRING_SVTOOLS_RTF_CLBRDRB, OOO_STRING_SVTOOLS_RTF_CLBRDRR
+ };
+ //Yes left and top are swapped with eachother for cell padding! Because
+ //that's what the thunderingly annoying rtf export/import word xp does.
+ static const char* aCellPadNames[] =
+ {
+ OOO_STRING_SVTOOLS_RTF_CLPADL, OOO_STRING_SVTOOLS_RTF_CLPADT, OOO_STRING_SVTOOLS_RTF_CLPADB, OOO_STRING_SVTOOLS_RTF_CLPADR
+ };
+ static const char* aCellPadUnits[] =
+ {
+ OOO_STRING_SVTOOLS_RTF_CLPADFL, OOO_STRING_SVTOOLS_RTF_CLPADFT, OOO_STRING_SVTOOLS_RTF_CLPADFB, OOO_STRING_SVTOOLS_RTF_CLPADFR
+ };
+ for (int i = 0; i < 4; ++i)
+ {
+ if (const SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
+ m_aRowDefs.append(OutTBLBorderLine(m_rExport, pLn, aBorderNames[i]));
+ if (rDefault.GetDistance(aBorders[i]) !=
+ rBox.GetDistance(aBorders[i]))
+ {
+ m_aRowDefs.append(aCellPadUnits[i]);
+ m_aRowDefs.append((sal_Int32)3);
+ m_aRowDefs.append(aCellPadNames[i]);
+ m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
+ }
+ }
+ }
+}
+
+void RtfAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
+ SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
+ SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
+ const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
+ const SfxPoolItem* pItem;
+ if( SFX_ITEM_SET == pCellFmt->GetAttrSet().GetItemState(
+ RES_BACKGROUND, TRUE, &pItem ))
+ {
+ const SvxBrushItem& rBack = (SvxBrushItem&)*pItem;
+ if( !rBack.GetColor().GetTransparency() )
+ {
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLCBPAT);
+ m_aRowDefs.append((sal_Int32)m_rExport.GetColor(rBack.GetColor()));
+ }
+ }
+}
+
+void RtfAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
+ const SwTableLine * pTabLine = pTabBox->GetUpper();
+ const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
+ const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
+
+ if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
+ {
+ sal_Int32 nHeight = 0;
+
+ switch ( rLSz.GetHeightSizeType() )
+ {
+ case ATT_FIX_SIZE: nHeight = -rLSz.GetHeight(); break;
+ case ATT_MIN_SIZE: nHeight = rLSz.GetHeight(); break;
+ default: break;
+ }
+
+ if ( nHeight )
+ {
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRRH);
+ m_aRowDefs.append(nHeight);
+ }
+ }
+}
+
+void RtfAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
+ const SwTableLine * pTabLine = pTabBox->GetUpper();
+ const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
+ const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
+
+ // The rtf default is to allow a row to break
+ if (rSplittable.GetValue() == 0)
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRKEEP);
+}
+
+void RtfAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwTable * pTable = pTableTextNodeInfoInner->getTable();
+ const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
+
+ if ( m_rExport.TrueFrameDirection( *pFrmFmt ) != FRMDIR_HORI_RIGHT_TOP )
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_LTRROW);
+ else
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_RTLROW);
+}
+
+void RtfAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
+ SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
+ SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
+ const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
+ const SfxPoolItem* pItem;
+
+ // vertical merges
+ if (pCell->GetRowSpan() > 1)
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMGF);
+ else if (pCell->GetRowSpan() == 0)
+ m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMRG);
+
+ // vertical alignment
+ if( SFX_ITEM_SET == pCellFmt->GetAttrSet().GetItemState(
+ RES_VERT_ORIENT, TRUE, &pItem ) )
+ switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
+ {
+ case text::VertOrientation::CENTER: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALC); break;
+ case text::VertOrientation::BOTTOM: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALB); break;
+ default: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALT); break;
+ }
+}
+
+void RtfAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop */
+}
+
+void RtfAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // This is called when the nested table ends in a cell, and there's no
+ // paragraph benhind that; so we must check for the ends of cell, rows,
+ // and tables
+ // ['true' to write an empty paragraph, MS Word insists on that]
+ FinishTableRowCell( pNodeInfoInner, true );
+}
+
+void RtfAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwTable *pTable = pTableTextNodeInfoInner->getTable();
+ SwFrmFmt *pFmt = pTable->GetFrmFmt( );
+
+ OStringBuffer aTblAdjust( OOO_STRING_SVTOOLS_RTF_TRQL );
+ switch (pFmt->GetHoriOrient().GetHoriOrient())
+ {
+ case text::HoriOrientation::CENTER:
+ aTblAdjust.setLength(0);
+ aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQC);
+ break;
+ case text::HoriOrientation::RIGHT:
+ aTblAdjust.setLength(0);
+ aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQR);
+ break;
+ case text::HoriOrientation::NONE:
+ case text::HoriOrientation::LEFT_AND_WIDTH:
+ aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRLEFT);
+ aTblAdjust.append((sal_Int32)pFmt->GetLRSpace().GetLeft());
+ break;
+ default:
+ break;
+ }
+
+ m_aRowDefs.append(aTblAdjust.makeStringAndClear());
+}
+
+void RtfAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop, see EndTableRow() */
+}
+
+/*
+ * Our private table methods.
+ */
+
+void RtfAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ sal_uInt32 nPageSize = 0;
+ bool bRelBoxSize = false;
+
+ // Create the SwWriteTable instance to use col spans
+ GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
+
+ const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
+ const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
+ SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
+
+ const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
+ if( pLayout && pLayout->IsExportable() )
+ m_pTableWrt = new SwWriteTable( pLayout );
+ else
+ m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (USHORT)nPageSize,
+ (USHORT)nTblSz, false);
+}
+
+void RtfAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop */
+}
+
+void RtfAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
+ OSL_TRACE("%s, (depth is %d)", OSL_THIS_FUNC, (int)nCurrentDepth);
+
+ TableDefinition(pTableTextNodeInfoInner);
+
+ // We'll write the table definition for nested tables later
+ if ( nCurrentDepth > 1 )
+ return;
+ m_rExport.Strm() << m_aRowDefs.makeStringAndClear();
+}
+
+void RtfAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_bTableCellOpen = true;
+}
+
+void RtfAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ TableDefaultBorders(pTableTextNodeInfoInner);
+ TableBackgrounds(pTableTextNodeInfoInner);
+ TableVerticalCell(pTableTextNodeInfoInner);
+}
+
+void RtfAttributeOutput::EndTableCell( )
+{
+ OSL_TRACE("%s, (depth is %d)", OSL_THIS_FUNC, (int)m_nTableDepth);
+
+ if ( m_nTableDepth > 1 )
+ m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTCELL);
+ else
+ m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
+
+ m_bTableCellOpen = false;
+ m_bTblAfterCell = true;
+}
+
+void RtfAttributeOutput::EndTableRow( )
+{
+ OSL_TRACE("%s, (depth is %d)", OSL_THIS_FUNC, (int)m_nTableDepth);
+
+ if ( m_nTableDepth > 1 )
+ {
+ m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS);
+ m_aAfterRuns.append(m_aRowDefs.makeStringAndClear());
+ m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTROW "}" "{" OOO_STRING_SVTOOLS_RTF_NONESTTABLES OOO_STRING_SVTOOLS_RTF_PAR "}");
+ }
+ else
+ m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW);
+}
+
+void RtfAttributeOutput::EndTable()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( m_nTableDepth > 0 )
+ m_nTableDepth--;
+
+ // We closed the table; if it is a nested table, the cell that contains it
+ // still continues
+ m_bTableCellOpen = true;
+
+ // Cleans the table helper
+ delete m_pTableWrt, m_pTableWrt = NULL;
+}
+
+void RtfAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool /*bForceEmptyParagraph*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( pInner.get() )
+ {
+ // Where are we in the table
+ sal_uInt32 nRow = pInner->getRow( );
+
+ const SwTable *pTable = pInner->getTable( );
+ const SwTableLines& rLines = pTable->GetTabLines( );
+ USHORT nLinesCount = rLines.Count( );
+
+ if ( pInner->isEndOfCell() )
+ EndTableCell();
+
+ // This is a line end
+ if ( pInner->isEndOfLine() )
+ EndTableRow();
+
+ // This is the end of the table
+ if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
+ EndTable();
+ }
+}
+
+void RtfAttributeOutput::StartStyles()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ m_rExport.Strm() << m_rExport.sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_COLORTBL;
+ m_rExport.OutColorTable();
+ OSL_ENSURE(m_aStylesheet.getLength() == 0, "m_aStylesheet is not empty");
+ m_aStylesheet.append(m_rExport.sNewLine);
+ m_aStylesheet.append('{');
+ m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_STYLESHEET);
+}
+
+void RtfAttributeOutput::EndStyles( USHORT /*nNumberOfStyles*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ m_rExport.Strm() << '}';
+ m_rExport.Strm() << m_aStylesheet.makeStringAndClear();
+ m_rExport.Strm() << '}';
+}
+
+void RtfAttributeOutput::DefaultStyle( USHORT /*nStyle*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop, the default style is always 0 in RTF */
+}
+
+void RtfAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
+ USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId )
+{
+ OSL_TRACE("%s, rName = '%s'", OSL_THIS_FUNC,
+ OUStringToOString( OUString( rName ), m_rExport.eCurrentEncoding ).getStr());
+
+ m_aStylesheet.append('{');
+ if (bPapFmt)
+ m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
+ else
+ m_aStylesheet.append( OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_CS);
+ m_aStylesheet.append( (sal_Int32)nId );
+
+ if ( nBase != 0x0FFF )
+ {
+ m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SBASEDON);
+ m_aStylesheet.append((sal_Int32)nBase);
+ }
+
+ m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SNEXT);
+ m_aStylesheet.append((sal_Int32)nNext);
+
+ m_rStyleName = rName;
+ m_nStyleId = nId;
+}
+
+void RtfAttributeOutput::EndStyle()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ m_aStyles.append(m_aStylesEnd.makeStringAndClear());
+ OString aStyles = m_aStyles.makeStringAndClear();
+ m_rExport.InsStyle(m_nStyleId, aStyles);
+ m_aStylesheet.append(aStyles);
+ m_aStylesheet.append(' ');
+ m_aStylesheet.append(OUStringToOString( OUString( m_rStyleName ), m_rExport.eCurrentEncoding ));
+ m_aStylesheet.append(";}");
+ m_aStylesheet.append(m_rExport.sNewLine);
+}
+
+void RtfAttributeOutput::StartStyleProperties( bool /*bParProp*/, USHORT /*nStyle*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ /* noop */
+}
+
+void RtfAttributeOutput::EndStyleProperties( bool /*bParProp*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ /* noop */
+}
+
+void RtfAttributeOutput::OutlineNumbering( BYTE nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( nLvl >= WW8ListManager::nMaxLevel )
+ nLvl = WW8ListManager::nMaxLevel - 1;
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
+ m_aStyles.append((sal_Int32)nLvl);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL);
+ m_aStyles.append((sal_Int32)nLvl);
+}
+
+void RtfAttributeOutput::PageBreakBefore( bool bBreak )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if (bBreak)
+ {
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_PAGEBB;
+ }
+}
+
+void RtfAttributeOutput::SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ switch (nC)
+ {
+ case msword::ColumnBreak:
+ m_nColBreakNeeded = true;
+ break;
+ case msword::PageBreak:
+ if ( pSectionInfo )
+ m_rExport.SectionProperties( *pSectionInfo );
+ break;
+ }
+}
+
+void RtfAttributeOutput::StartSection()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECT OOO_STRING_SVTOOLS_RTF_SECTD);
+ if (!m_bBufferSectionBreaks)
+ m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
+}
+
+void RtfAttributeOutput::EndSection()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /*
+ * noop, \sect must go to StartSection or Word won't notice multiple
+ * columns...
+ */
+}
+
+void RtfAttributeOutput::SectionFormProtection( bool bProtected )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED);
+ m_aSectionBreaks.append((sal_Int32)!bProtected);
+}
+
+void RtfAttributeOutput::SectionLineNumbering( ULONG /*nRestartNo*/, const SwLineNumberInfo& rLnNumInfo )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINEMOD;
+ m_rExport.OutLong(rLnNumInfo.GetCountBy());
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINEX;
+ m_rExport.OutLong(rLnNumInfo.GetPosFromLeft());
+ if (!rLnNumInfo.IsRestartEachPage())
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINECONT;
+}
+
+void RtfAttributeOutput::SectionTitlePage()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /*
+ * noop, handled in RtfExport::WriteHeaderFooter()
+ */
+}
+
+void RtfAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SvxBoxItem& rBox = pFmt->GetBox();
+ const SvxBorderLine *pLine = rBox.GetTop();
+ if(pLine)
+ m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
+ OOO_STRING_SVTOOLS_RTF_PGBRDRT,
+ rBox.GetDistance(BOX_LINE_TOP) ));
+ pLine = rBox.GetBottom();
+ if(pLine)
+ m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
+ OOO_STRING_SVTOOLS_RTF_PGBRDRB,
+ rBox.GetDistance(BOX_LINE_BOTTOM) ));
+ pLine = rBox.GetLeft();
+ if(pLine)
+ m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
+ OOO_STRING_SVTOOLS_RTF_PGBRDRL,
+ rBox.GetDistance(BOX_LINE_LEFT) ));
+ pLine = rBox.GetRight();
+ if(pLine)
+ m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
+ OOO_STRING_SVTOOLS_RTF_PGBRDRR,
+ rBox.GetDistance(BOX_LINE_RIGHT) ));
+}
+
+void RtfAttributeOutput::SectionBiDi( bool bBiDi )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << (bBiDi ? OOO_STRING_SVTOOLS_RTF_RTLSECT : OOO_STRING_SVTOOLS_RTF_LTRSECT);
+}
+
+void RtfAttributeOutput::SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if (nPageRestartNumber > 0)
+ {
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNSTARTS);
+ m_aSectionBreaks.append((sal_Int32)nPageRestartNumber);
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNRESTART);
+ }
+
+ const char* pStr = 0;
+ switch ( nNumType )
+ {
+ case SVX_NUM_CHARS_UPPER_LETTER:
+ case SVX_NUM_CHARS_UPPER_LETTER_N: pStr = OOO_STRING_SVTOOLS_RTF_PGNUCLTR; break;
+ case SVX_NUM_CHARS_LOWER_LETTER:
+ case SVX_NUM_CHARS_LOWER_LETTER_N: pStr = OOO_STRING_SVTOOLS_RTF_PGNLCLTR; break;
+ case SVX_NUM_ROMAN_UPPER: pStr = OOO_STRING_SVTOOLS_RTF_PGNUCRM; break;
+ case SVX_NUM_ROMAN_LOWER: pStr = OOO_STRING_SVTOOLS_RTF_PGNLCRM; break;
+
+ case SVX_NUM_ARABIC: pStr = OOO_STRING_SVTOOLS_RTF_PGNDEC; break;
+ }
+ if (pStr)
+ m_aSectionBreaks.append(pStr);
+}
+
+void RtfAttributeOutput::SectionType( BYTE nBreakCode )
+{
+ OSL_TRACE("%s, nBreakCode = %d", OSL_THIS_FUNC, nBreakCode);
+
+ /*
+ * break code: 0 No break, 1 New column
+ * 2 New page, 3 Even page, 4 Odd page
+ */
+ const char* sType = NULL;
+ switch ( nBreakCode )
+ {
+ case 1: sType = OOO_STRING_SVTOOLS_RTF_SBKCOL; break;
+ case 2: sType = OOO_STRING_SVTOOLS_RTF_SBKPAGE; break;
+ case 3: sType = OOO_STRING_SVTOOLS_RTF_SBKEVEN; break;
+ case 4: sType = OOO_STRING_SVTOOLS_RTF_SBKODD; break;
+ default: sType = OOO_STRING_SVTOOLS_RTF_SBKNONE; break;
+ }
+ m_aSectionBreaks.append(sType);
+ if (!m_bBufferSectionBreaks)
+ m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
+}
+
+void RtfAttributeOutput::NumberingDefinition( USHORT nId, const SwNumRule &/*rRule*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE;
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTID;
+ m_rExport.OutULong(nId);
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT << '0';
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LS;
+ m_rExport.OutULong(nId) << '}';
+}
+
+void RtfAttributeOutput::StartAbstractNumbering( USHORT nId )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LIST << OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID;
+ m_rExport.OutULong( nId );
+ m_nListId = nId;
+}
+
+void RtfAttributeOutput::EndAbstractNumbering()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTID;
+ m_rExport.OutULong( m_nListId ) << '}' << m_rExport.sNewLine;
+}
+
+void RtfAttributeOutput::NumberingLevel( BYTE nLevel,
+ USHORT nStart,
+ USHORT nNumberingType,
+ SvxAdjust eAdjust,
+ const BYTE * pNumLvlPos,
+ BYTE /*nFollow*/,
+ const wwFont * pFont,
+ const SfxItemSet * pOutSet,
+ sal_Int16 nIndentAt,
+ sal_Int16 nFirstLineIndex,
+ sal_Int16 /*nListTabPos*/,
+ const String &rNumberingString )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << m_rExport.sNewLine;
+ if( nLevel > 8 ) // RTF knows only 9 levels
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_SOUTLVL;
+
+ m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTLEVEL;
+
+ USHORT nVal = 0;
+ switch( nNumberingType )
+ {
+ case SVX_NUM_ROMAN_UPPER: nVal = 1; break;
+ case SVX_NUM_ROMAN_LOWER: nVal = 2; break;
+ case SVX_NUM_CHARS_UPPER_LETTER:
+ case SVX_NUM_CHARS_UPPER_LETTER_N: nVal = 3; break;
+ case SVX_NUM_CHARS_LOWER_LETTER:
+ case SVX_NUM_CHARS_LOWER_LETTER_N: nVal = 4; break;
+
+ case SVX_NUM_BITMAP:
+ case SVX_NUM_CHAR_SPECIAL: nVal = 23; break;
+ }
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELNFC;
+ m_rExport.OutULong( nVal );
+
+ switch( eAdjust )
+ {
+ case SVX_ADJUST_CENTER: nVal = 1; break;
+ case SVX_ADJUST_RIGHT: nVal = 2; break;
+ default: nVal = 0; break;
+ }
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELJC;
+ m_rExport.OutULong( nVal );
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT;
+ m_rExport.OutULong( nStart );
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW << "0";
+
+ // leveltext group
+ m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LEVELTEXT << ' ';
+
+ if( SVX_NUM_CHAR_SPECIAL == nNumberingType ||
+ SVX_NUM_BITMAP == nNumberingType )
+ {
+ m_rExport.Strm() << "\\'01";
+ sal_Unicode cChar = rNumberingString.GetChar(0);
+ m_rExport.Strm() << "\\u";
+ m_rExport.OutULong(cChar);
+ m_rExport.Strm() << " ?";
+ }
+ else
+ {
+ m_rExport.Strm() << "\\'" << m_rExport.OutHex( rNumberingString.Len(), 2 );
+ m_rExport.Strm() << m_rExport.OutString( rNumberingString, m_rExport.eDefaultEncoding );
+ }
+
+ m_rExport.Strm() << ";}";
+
+ // write the levelnumbers
+ m_rExport.Strm() << "{" << OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS;
+ for( BYTE i = 0; i <= nLevel && pNumLvlPos[ i ]; ++i )
+ {
+ m_rExport.Strm() << "\\'" << m_rExport.OutHex(pNumLvlPos[ i ], 2).getStr();
+ }
+ m_rExport.Strm() << ";}";
+
+ if( pOutSet )
+ {
+ if (pFont)
+ {
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_F;
+ m_rExport.OutULong(m_rExport.maFontHelper.GetId(*pFont));
+ }
+ m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN );
+ m_rExport.Strm() << m_aStyles.makeStringAndClear();
+ }
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_FI;
+ m_rExport.OutLong( nFirstLineIndex ) << OOO_STRING_SVTOOLS_RTF_LI;
+ m_rExport.OutLong( nIndentAt );
+
+ m_rExport.Strm() << '}';
+ if( nLevel > 8 )
+ m_rExport.Strm() << '}';
+}
+
+void RtfAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField /*eType*/, const String& rFldCmd, BYTE /*nMode*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // NEEDSWORK this has beeen tested only with page numbers
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " ");
+ m_aRunText.append(m_rExport.OutString(rFldCmd, m_rExport.eCurrentEncoding));
+ m_aRunText.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
+ if (pFld)
+ m_aRunText.append(m_rExport.OutString(pFld->GetCntnt(), m_rExport.eDefaultEncoding));
+ m_aRunText.append("}}");
+}
+
+void RtfAttributeOutput::WriteBookmarks_Impl( std::vector< rtl::OUString >& rStarts, std::vector< rtl::OUString >& rEnds )
+{
+ for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it < end; ++it )
+ {
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKSTART " ");
+ m_aRun.append(m_rExport.OutString(*it, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+ rStarts.clear();
+
+ for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it < end; ++it )
+ {
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKEND " ");
+ m_aRun.append(m_rExport.OutString(*it, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+ rEnds.clear();
+}
+
+void RtfAttributeOutput::WriteHeaderFooter_Impl( const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr )
+{
+ OStringBuffer aSectionBreaks = m_aSectionBreaks;
+ m_aSectionBreaks.setLength(0);
+ OStringBuffer aRun = m_aRun;
+ m_aRun.setLength(0);
+
+ m_aSectionHeaders.append(bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY : OOO_STRING_SVTOOLS_RTF_FOOTERY);
+ m_aSectionHeaders.append((sal_Int32)m_rExport.pAktPageDesc->GetMaster().GetULSpace().GetUpper());
+ m_aSectionHeaders.append('{');
+ m_aSectionHeaders.append(pStr);
+ m_bBufferSectionHeaders = true;
+ m_rExport.WriteHeaderFooterText(rFmt, bHeader);
+ m_bBufferSectionHeaders = false;
+ m_aSectionHeaders.append('}');
+
+ m_aSectionBreaks = aSectionBreaks;
+ m_aRun = aRun;
+}
+
+void RtfAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& /*rNdTopLeft*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwNode *pNode = rFrame.GetContent();
+ const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
+
+ switch ( rFrame.GetWriterType() )
+ {
+ case sw::Frame::eTxtBox:
+ OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
+ m_rExport.mpParentFrame = &rFrame;
+ m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = true;
+ m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
+ m_rExport.Strm() << m_aRunText.makeStringAndClear();
+ m_rExport.Strm() << m_aStyles.makeStringAndClear();
+ m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = false;
+ m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_IGNORE;
+ m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
+ m_rExport.Strm() << m_aRunText.makeStringAndClear();
+ m_rExport.Strm() << m_aStyles.makeStringAndClear();
+ m_rExport.Strm() << '}';
+
+ {
+ /*
+ * Save m_aRun as we should not loose the opening brace.
+ * OTOH, just drop the contents of m_aRunText in case something
+ * would be there, causing a problem later.
+ */
+ OString aSave = m_aRun.makeStringAndClear();
+ m_rExport.bRTFFlySyntax = true;
+ m_rExport.OutContent(*rFrame.GetContent());
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_PARD;
+ m_rExport.bRTFFlySyntax = false;
+ m_aRun.append(aSave);
+ m_aRunText.setLength(0);
+ }
+
+ m_rExport.mpParentFrame = NULL;
+ m_rExport.Strm() << RtfExport::sNewLine;
+ break;
+ case sw::Frame::eGraphic:
+ if (!rFrame.IsInline())
+ {
+ m_rExport.mpParentFrame = &rFrame;
+ m_rExport.bRTFFlySyntax = true;
+ m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
+ m_rExport.bRTFFlySyntax = false;
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
+ m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
+ m_aRunText.append('}');
+ m_rExport.mpParentFrame = NULL;
+ }
+
+ if ( pGrfNode )
+ FlyFrameGraphic( *pGrfNode, rFrame.GetLayoutSize() );
+ break;
+ case sw::Frame::eDrawing:
+ {
+ const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
+ if ( pSdrObj )
+ {
+ bool bSwapInPage = false;
+ if ( !pSdrObj->GetPage() )
+ {
+ if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() )
+ {
+ if ( SdrPage *pPage = pModel->GetPage( 0 ) )
+ {
+ bSwapInPage = true;
+ const_cast< SdrObject* >( pSdrObj )->SetPage( pPage );
+ }
+ }
+ }
+
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{");
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLDINST);
+ m_aRunText.append(" SHAPE ");
+ m_aRunText.append("}" "{" OOO_STRING_SVTOOLS_RTF_FLDRSLT);
+
+ m_rExport.SdrExporter().AddSdrObject( *pSdrObj );
+
+ m_aRunText.append('}');
+ m_aRunText.append('}');
+
+ if ( bSwapInPage )
+ const_cast< SdrObject* >( pSdrObj )->SetPage( 0 );
+ }
+ }
+ break;
+ case sw::Frame::eFormControl:
+ {
+ const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
+ const SdrObject *pObject = rFrmFmt.FindRealSdrObject();
+
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST);
+
+ if (pObject && pObject->GetObjInventor() == FmFormInventor)
+ {
+ if (SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObject))
+ {
+ uno::Reference< awt::XControlModel > xControlModel =
+ pFormObj->GetUnoControlModel();
+ uno::Reference< lang::XServiceInfo > xInfo(xControlModel, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropSet(xControlModel, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySetInfo> xPropSetInfo = xPropSet->getPropertySetInfo();
+ OUString sName;
+ if (xInfo->supportsService(C2U("com.sun.star.form.component.CheckBox")))
+ {
+
+ m_aRun.append(OUStringToOString(OUString(FieldString(ww::eFORMCHECKBOX)), m_rExport.eCurrentEncoding));
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFTYPE "1"); // 1 = checkbox
+ // checkbox size in half points, this seems to be always 20, see WW8Export::DoCheckBox()
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFHPS "20");
+
+ OUString aStr;
+ sName = C2U("Name");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aStr;
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
+ m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+
+ sName = C2U("HelpText");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aStr;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
+ m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+
+ sName = C2U("HelpF1Text");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aStr;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
+ m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+
+ sal_Int16 nTemp = 0;
+ xPropSet->getPropertyValue(C2U("DefaultState")) >>= nTemp;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
+ m_aRun.append((sal_Int32)nTemp);
+ xPropSet->getPropertyValue(C2U("State")) >>= nTemp;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFRES);
+ m_aRun.append((sal_Int32)nTemp);
+
+ m_aRun.append("}}");
+
+ // field result is empty, ffres already contains the form result
+ m_aRun.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
+ }
+ else if (xInfo->supportsService(C2U("com.sun.star.form.component.TextField")))
+ {
+ OStringBuffer aBuf;
+ OString aStr;
+ OUString aTmp;
+ const sal_Char* pStr;
+
+ m_aRun.append(OUStringToOString(OUString(FieldString(ww::eFORMTEXT)), m_rExport.eCurrentEncoding));
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_DATAFIELD " ");
+ for (int i = 0; i < 8; i++) aBuf.append((sal_Char)0x00);
+ xPropSet->getPropertyValue(C2U("Name")) >>= aTmp;
+ aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
+ aBuf.append((sal_Char)aStr.getLength());
+ aBuf.append(aStr);
+ aBuf.append((sal_Char)0x00);
+ xPropSet->getPropertyValue(C2U("DefaultText")) >>= aTmp;
+ aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
+ aBuf.append((sal_Char)aStr.getLength());
+ aBuf.append(aStr);
+ for (int i = 0; i < 11; i++) aBuf.append((sal_Char)0x00);
+ aStr = aBuf.makeStringAndClear();
+ pStr = aStr.getStr();
+ for (int i = 0; i < aStr.getLength(); i++, pStr++)
+ m_aRun.append(m_rExport.OutHex(*pStr, 2));
+ m_aRun.append('}');
+ m_aRun.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
+ xPropSet->getPropertyValue(C2U("Text")) >>= aTmp;
+ m_aRun.append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
+ sName = C2U("HelpText");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aTmp;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
+ m_aRun.append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+
+ sName = C2U("HelpF1Text");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aTmp;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
+ m_aRun.append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+ m_aRun.append("}");
+ }
+ else if (xInfo->supportsService(C2U("com.sun.star.form.component.ListBox")))
+ {
+ OUString aStr;
+ uno::Sequence<sal_Int16> aIntSeq;
+ uno::Sequence<OUString> aStrSeq;
+
+ m_aRun.append(OUStringToOString(OUString(FieldString(ww::eFORMDROPDOWN)), m_rExport.eCurrentEncoding));
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFTYPE "2"); // 2 = list
+
+ xPropSet->getPropertyValue(C2U("DefaultSelection")) >>= aIntSeq;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
+ // a dropdown list can have only one 'selected item by default'
+ m_aRun.append((sal_Int32)aIntSeq[0]);
+
+ xPropSet->getPropertyValue(C2U("SelectedItems")) >>= aIntSeq;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFRES);
+ // a dropdown list can have only one 'currently selected item'
+ m_aRun.append((sal_Int32)aIntSeq[0]);
+
+ sName = C2U("Name");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aStr;
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
+ m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+
+ sName = C2U("HelpText");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aStr;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
+ m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+
+ sName = C2U("HelpF1Text");
+ if (xPropSetInfo->hasPropertyByName(sName))
+ {
+ xPropSet->getPropertyValue(sName) >>= aStr;
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
+ m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
+ m_aRun.append('}');
+ }
+
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX);
+
+ xPropSet->getPropertyValue(C2U("StringItemList")) >>= aStrSeq;
+ sal_uInt32 nListItems = aStrSeq.getLength();
+ for (sal_uInt32 i = 0; i < nListItems; i++)
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFL " ")
+ .append(OUStringToOString(aStrSeq[i], m_rExport.eCurrentEncoding)).append('}');
+
+ m_aRun.append("}}");
+
+ // field result is empty, ffres already contains the form result
+ m_aRun.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
+ }
+ else
+ OSL_TRACE("%s unhandled form control: '%s'", OSL_THIS_FUNC,
+ OUStringToOString(xInfo->getImplementationName(), m_rExport.eCurrentEncoding).getStr());
+ m_aRun.append('}');
+ }
+ }
+
+ m_aRun.append('}');
+ }
+ break;
+ case sw::Frame::eOle:
+ {
+ const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
+ const SdrObject *pSdrObj = rFrmFmt.FindRealSdrObject();
+ if ( pSdrObj )
+ {
+ SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
+ SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
+ FlyFrameOLE(rOLENd, rFrame.GetLayoutSize());
+ }
+ }
+ break;
+ default:
+ OSL_TRACE("%s: unknown type (%d)", OSL_THIS_FUNC, rFrame.GetWriterType());
+ break;
+ }
+}
+
+void RtfAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ switch ( rCaseMap.GetValue() )
+ {
+ case SVX_CASEMAP_KAPITAELCHEN:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
+ break;
+ case SVX_CASEMAP_VERSALIEN:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
+ break;
+ default: // Something that rtf does not support
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
+ m_aStyles.append((sal_Int32)0);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
+ m_aStyles.append((sal_Int32)0);
+ break;
+ }
+}
+
+void RtfAttributeOutput::CharColor( const SvxColorItem& rColor )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const Color aColor( rColor.GetValue() );
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CF);
+ m_aStyles.append( (sal_Int32)m_rExport.GetColor( aColor ));
+}
+
+void RtfAttributeOutput::CharContour( const SvxContourItem& rContour )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTL);
+ if ( !rContour.GetValue() )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ switch ( rCrossedOut.GetStrikeout() )
+ {
+ case STRIKEOUT_NONE:
+ if (!m_bStrikeDouble)
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
+ else
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
+ m_aStyles.append((sal_Int32)0);
+ break;
+ case STRIKEOUT_DOUBLE:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
+ m_aStyles.append((sal_Int32)1);
+ break;
+ default:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
+ break;
+ }
+}
+
+void RtfAttributeOutput::CharEscapement( const SvxEscapementItem& rEsc )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const char * pUpDn;
+
+ SwTwips nH = ((SvxFontHeightItem&)m_rExport.GetItem( RES_CHRATR_FONTSIZE )).GetHeight();
+
+ if( 0 < rEsc.GetEsc() )
+ pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
+ else if( 0 > rEsc.GetEsc() )
+ {
+ pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
+ nH = -nH;
+ }
+ else
+ return;
+
+ short nEsc = rEsc.GetEsc();
+ short nProp = rEsc.GetProp() * 100;
+ if( DFLT_ESC_AUTO_SUPER == nEsc )
+ {
+ nEsc = 100 - rEsc.GetProp();
+ ++nProp;
+ }
+ else if( DFLT_ESC_AUTO_SUB == nEsc )
+ {
+ nEsc = - 100 + rEsc.GetProp();
+ ++nProp;
+ }
+
+ m_aStyles.append('{');
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_UPDNPROP);
+ m_aStyles.append( (sal_Int32)nProp );
+ m_aStyles.append('}');
+ m_aStyles.append(pUpDn);
+
+ /*
+ * Calculate the act. FontSize and the percentage of the displacement;
+ * RTF file expects half points, while internally it's in twips.
+ * Formally : (FontSize * 1/20 ) pts x * 2
+ * ----------------------- = ------------
+ * 100% Escapement
+ */
+
+ m_aStyles.append( (sal_Int32) ( (long( nEsc ) * nH) + 500L ) / 1000L );
+ // 500L to round !!
+}
+
+void RtfAttributeOutput::CharFont( const SvxFontItem& rFont)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_F);
+ m_aStylesEnd.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
+ m_rExport.eCurrentEncoding = rtl_getTextEncodingFromWindowsCharset(sw::ms::rtl_TextEncodingToWinCharset(rFont.GetCharSet()));
+}
+
+void RtfAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ switch ( rFontSize.Which() )
+ {
+ case RES_CHRATR_FONTSIZE:
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_FS);
+ m_aStylesEnd.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
+ break;
+ case RES_CHRATR_CJK_FONTSIZE:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FS);
+ m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
+ break;
+ case RES_CHRATR_CTL_FONTSIZE:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AFS);
+ m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
+ break;
+ }
+}
+
+void RtfAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // in quater points then in twips
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPND);
+ m_aStyles.append((sal_Int32)(rKerning.GetValue() / 5));
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPNDTW);
+ m_aStyles.append((sal_Int32)(rKerning.GetValue()));
+}
+
+void RtfAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ switch (rLanguage.Which())
+ {
+ case RES_CHRATR_LANGUAGE:
+ m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LANG);
+ m_aStylesEnd.append((sal_Int32)rLanguage.GetLanguage());
+ break;
+ case RES_CHRATR_CJK_LANGUAGE:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANGFE);
+ m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
+ break;
+ case RES_CHRATR_CTL_LANGUAGE:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANG);
+ m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
+ break;
+ }
+}
+
+void RtfAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
+ if ( rPosture.GetPosture() == ITALIC_NONE )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SHAD);
+ if ( !rShadow.GetValue() )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const char* pStr = 0;
+ const SfxPoolItem* pItem = m_rExport.HasItem( RES_CHRATR_WORDLINEMODE );
+ bool bWord = false;
+ if (pItem)
+ bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;
+ switch(rUnderline.GetLineStyle() )
+ {
+ case UNDERLINE_SINGLE:
+ pStr = bWord ? OOO_STRING_SVTOOLS_RTF_ULW : OOO_STRING_SVTOOLS_RTF_UL;
+ break;
+ case UNDERLINE_DOUBLE:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULDB;
+ break;
+ case UNDERLINE_NONE:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULNONE;
+ break;
+ case UNDERLINE_DOTTED:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULD;
+ break;
+ case UNDERLINE_DASH:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULDASH;
+ break;
+ case UNDERLINE_DASHDOT:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULDASHD;
+ break;
+ case UNDERLINE_DASHDOTDOT:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULDASHDD;
+ break;
+ case UNDERLINE_BOLD:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULTH;
+ break;
+ case UNDERLINE_WAVE:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULWAVE;
+ break;
+ case UNDERLINE_BOLDDOTTED:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULTHD;
+ break;
+ case UNDERLINE_BOLDDASH:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASH;
+ break;
+ case UNDERLINE_LONGDASH:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULLDASH;
+ break;
+ case UNDERLINE_BOLDLONGDASH:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULTHLDASH;
+ break;
+ case UNDERLINE_BOLDDASHDOT:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHD;
+ break;
+ case UNDERLINE_BOLDDASHDOTDOT:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHDD;
+ break;
+ case UNDERLINE_BOLDWAVE:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULHWAVE;
+ break;
+ case UNDERLINE_DOUBLEWAVE:
+ pStr = OOO_STRING_SVTOOLS_RTF_ULULDBWAVE;
+ break;
+ default:
+ break;
+ }
+
+ if( pStr )
+ {
+ m_aStyles.append(pStr);
+ // NEEDSWORK looks like here rUnderline.GetColor() is always black,
+ // even if the color in the odt is for example green...
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ULC);
+ m_aStyles.append( (sal_Int32)m_rExport.GetColor(rUnderline.GetColor()) );
+ }
+}
+
+void RtfAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
+ if ( rWeight.GetWeight() != WEIGHT_BOLD )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KERNING);
+ m_aStyles.append((sal_Int32) (rAutoKern.GetValue() ? 1 : 0));
+}
+
+void RtfAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ANIMTEXT);
+ m_aStyles.append((sal_Int32) (rBlink.GetValue() ? 2 : 0));
+}
+
+void RtfAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if( !rBrush.GetColor().GetTransparency() )
+ {
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHCBPAT);
+ m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
+ }
+}
+
+void RtfAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HICH);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
+ m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
+}
+
+void RtfAttributeOutput::CharFontSizeCJK( const SvxFontHeightItem& rFontSize )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ CharFontSize( rFontSize );
+}
+
+void RtfAttributeOutput::CharLanguageCJK( const SvxLanguageItem& rLanguageItem )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ CharLanguage( rLanguageItem );
+}
+
+void RtfAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
+ if ( rPosture.GetPosture() == ITALIC_NONE )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
+ if ( rWeight.GetWeight() != WEIGHT_BOLD )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
+ m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
+}
+
+void RtfAttributeOutput::CharFontSizeCTL( const SvxFontHeightItem& rFontSize )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ CharFontSize( rFontSize );
+}
+
+void RtfAttributeOutput::CharLanguageCTL( const SvxLanguageItem& rLanguageItem )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ CharLanguage( rLanguageItem );
+}
+
+void RtfAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AI);
+ if ( rPosture.GetPosture() == ITALIC_NONE )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AB);
+ if ( rWeight.GetWeight() != WEIGHT_BOLD )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HORZVERT);
+ m_aStyles.append((sal_Int32)(rRotate.IsFitToLine() ? 1 : 0));
+}
+
+void RtfAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const sal_Char* pStr;
+ switch( rEmphasisMark.GetEmphasisMark())
+ {
+ case EMPHASISMARK_NONE: pStr = OOO_STRING_SVTOOLS_RTF_ACCNONE; break;
+ case EMPHASISMARK_SIDE_DOTS: pStr = OOO_STRING_SVTOOLS_RTF_ACCCOMMA; break;
+ default: pStr = OOO_STRING_SVTOOLS_RTF_ACCDOT; break;
+ }
+ m_aStyles.append(pStr);
+}
+
+void RtfAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if( rTwoLines.GetValue() )
+ {
+ sal_Unicode cStart = rTwoLines.GetStartBracket();
+ sal_Unicode cEnd = rTwoLines.GetEndBracket();
+
+ USHORT nType;
+ if( !cStart && !cEnd )
+ nType = 0;
+ else if( '{' == cStart || '}' == cEnd )
+ nType = 4;
+ else if( '<' == cStart || '>' == cEnd )
+ nType = 3;
+ else if( '[' == cStart || ']' == cEnd )
+ nType = 2;
+ else // all other kind of brackets
+ nType = 1;
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TWOINONE);
+ m_aStyles.append((sal_Int32)nType);
+ }
+}
+
+void RtfAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHARSCALEX);
+ m_aStyles.append((sal_Int32)rScaleWidth.GetValue());
+}
+
+void RtfAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const sal_Char* pStr;
+ switch (rRelief.GetValue())
+ {
+ case RELIEF_EMBOSSED:
+ pStr = OOO_STRING_SVTOOLS_RTF_EMBO;
+ break;
+ case RELIEF_ENGRAVED:
+ pStr = OOO_STRING_SVTOOLS_RTF_IMPR;
+ break;
+ default:
+ pStr = 0;
+ break;
+ }
+
+ if (pStr)
+ m_aStyles.append(pStr);
+}
+
+void RtfAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_V);
+ if ( !rHidden.GetValue() )
+ m_aStyles.append((sal_Int32)0);
+}
+
+void RtfAttributeOutput::TextINetFormat( const SwFmtINetFmt& rURL )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if( rURL.GetValue().Len() )
+ {
+ const SwCharFmt* pFmt;
+ const SwTxtINetFmt* pTxtAtr = rURL.GetTxtINetFmt();
+
+ m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
+ if( pTxtAtr && 0 != ( pFmt = pTxtAtr->GetCharFmt() ))
+ {
+ USHORT nStyle = m_rExport.GetId( *pFmt );
+ OString* pString = m_rExport.GetStyle(nStyle);
+ if (pString)
+ m_aStyles.append(*pString);
+ }
+ }
+}
+
+void RtfAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ USHORT nStyle = m_rExport.GetId( *rCharFmt.GetCharFmt() );
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_CS);
+ m_aStyles.append((sal_Int32)nStyle);
+ OString* pString = m_rExport.GetStyle(nStyle);
+ if (pString)
+ m_aStyles.append(*pString);
+}
+
+void RtfAttributeOutput::WriteTextFootnoteNumStr(const SwFmtFtn& rFootnote)
+{
+ if (!rFootnote.GetNumStr().Len())
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_CHFTN);
+ else
+ m_aRun.append(m_rExport.OutString(rFootnote.GetNumStr(), m_rExport.eCurrentEncoding));
+}
+
+void RtfAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
+{
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_SUPER " ");
+ WriteTextFootnoteNumStr(rFootnote);
+ m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FOOTNOTE);
+ if( rFootnote.IsEndNote() )
+ m_aRun.append(OOO_STRING_SVTOOLS_RTF_FTNALT);
+ m_aRun.append(' ');
+ WriteTextFootnoteNumStr(rFootnote);
+
+ /*
+ * The footnote contains a whole paragraph, so we have to:
+ * 1) Reset, then later restore the contents of our run buffer.
+ * 2) Buffer the output of the whole paragraph, as we do so for section headers already.
+ */
+ const SwNodeIndex* pIndex = rFootnote.GetTxtFtn()->GetStartNode();
+ OStringBuffer aRun = m_aRun;
+ m_aRun.setLength(0);
+ m_bBufferSectionHeaders = true;
+ m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
+ pIndex->GetNode().EndOfSectionIndex(),
+ !rFootnote.IsEndNote() ? TXT_FTN : TXT_EDN);
+ m_bBufferSectionHeaders = false;
+ m_aRun = aRun;
+ m_aRun.append(m_aSectionHeaders.makeStringAndClear());
+
+ m_aRun.append("}");
+ m_aRun.append("}");
+
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SL);
+ m_aStyles.append((sal_Int32)nSpace);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SLMULT);
+ m_aStyles.append((sal_Int32)nMulti);
+
+}
+
+void RtfAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ switch ( rAdjust.GetAdjust() )
+ {
+ case SVX_ADJUST_LEFT:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QL);
+ break;
+ case SVX_ADJUST_RIGHT:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QR);
+ break;
+ case SVX_ADJUST_BLOCKLINE:
+ case SVX_ADJUST_BLOCK:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QJ);
+ break;
+ case SVX_ADJUST_CENTER:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QC);
+ break;
+ default:
+ break;
+ }
+}
+
+void RtfAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if( !rSplit.GetValue() )
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEP);
+}
+
+void RtfAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if (rWidows.GetValue())
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_WIDCTLPAR);
+ else
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOWIDCTLPAR);
+}
+
+void RtfAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ long nOffset = ((SvxLRSpaceItem&)m_rExport.GetItem( RES_LR_SPACE )).GetTxtLeft();
+ for( USHORT n = 0; n < rTabStop.Count(); n++ )
+ {
+ const SvxTabStop & rTS = rTabStop[ n ];
+ if( SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment() )
+ {
+ const char* pFill = 0;
+ switch( rTS.GetFill() )
+ {
+ case cDfltFillChar:
+ break;
+
+ case '.': pFill = OOO_STRING_SVTOOLS_RTF_TLDOT; break;
+ case '_': pFill = OOO_STRING_SVTOOLS_RTF_TLUL; break;
+ case '-': pFill = OOO_STRING_SVTOOLS_RTF_TLTH; break;
+ case '=': pFill = OOO_STRING_SVTOOLS_RTF_TLEQ; break;
+ default:
+ break;
+ }
+ if( pFill )
+ m_aStyles.append(pFill);
+
+ const sal_Char* pAdjStr = 0;
+ switch (rTS.GetAdjustment())
+ {
+ case SVX_TAB_ADJUST_RIGHT:
+ pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
+ break;
+ case SVX_TAB_ADJUST_DECIMAL:
+ pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
+ break;
+ case SVX_TAB_ADJUST_CENTER:
+ pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
+ break;
+ default:
+ break;
+ }
+ if (pAdjStr)
+ m_aStyles.append(pAdjStr);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TX);
+ m_aStyles.append((sal_Int32)(rTS.GetTabPos() + nOffset));
+ }
+ else
+ {
+ m_aTabStop.append( OOO_STRING_SVTOOLS_RTF_DEFTAB );
+ m_aTabStop.append( (sal_Int32)rTabStop[0].GetTabPos() );
+ }
+ }
+}
+
+void RtfAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ sal_Int32 nFlags = rHyphenZone.IsHyphen() ? 1 : 0;
+ if( rHyphenZone.IsPageEnd() )
+ nFlags += 2;
+ m_aStyles.append('{');
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHEN);
+ m_aStyles.append((sal_Int32)nFlags);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHLEAD);
+ m_aStyles.append((sal_Int32)rHyphenZone.GetMinLead());
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHTRAIL);
+ m_aStyles.append((sal_Int32)rHyphenZone.GetMinTrail());
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHMAX);
+ m_aStyles.append((sal_Int32)rHyphenZone.GetMaxHyphens());
+ m_aStyles.append('}');
+}
+
+void RtfAttributeOutput::ParaNumRule_Impl( const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( USHRT_MAX == nNumId || 0 == nNumId || 0 == pTxtNd)
+ return;
+
+ const SwNumRule* pRule = pTxtNd->GetNumRule();
+
+ // --> OD 2008-03-18 #refactorlists#
+ // if( pRule && MAXLEVEL > pTxtNd->GetActualListLevel() )
+ if( pRule && pTxtNd->IsInList() )
+ // <--
+ {
+ // --> OD 2008-03-18 #refactorlists#
+ ASSERT( pTxtNd->GetActualListLevel() >= 0 && pTxtNd->GetActualListLevel() < MAXLEVEL,
+ "<SwRTFWriter::OutListNum(..)> - text node does not have valid list level. Serious defect -> please inform OD" );
+ // <--
+
+ const bool bExportNumRule = USHRT_MAX != nNumId;
+ const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl );
+ if( !pFmt )
+ pFmt = &pRule->Get( nLvl );
+
+ const SfxItemSet& rNdSet = pTxtNd->GetSwAttrSet();
+
+ if ( bExportNumRule ) {
+ m_aStyles.append('{');
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LISTTEXT);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PARD);
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
+ m_aStyles.append(' ');
+ }
+
+ SvxLRSpaceItem aLR( (SvxLRSpaceItem&)rNdSet.Get( RES_LR_SPACE ) );
+ aLR.SetTxtLeft( aLR.GetTxtLeft() + pFmt->GetIndentAt() );
+ aLR.SetTxtFirstLineOfst( pFmt->GetFirstLineOffset() );
+
+ USHORT nStyle = m_rExport.GetId( *pFmt->GetCharFmt() );
+ OString* pString = m_rExport.GetStyle(nStyle);
+ if (pString)
+ m_aStyles.append(*pString);
+
+ {
+ String sTxt;
+ if( SVX_NUM_CHAR_SPECIAL == pFmt->GetNumberingType() || SVX_NUM_BITMAP == pFmt->GetNumberingType() )
+ sTxt = pFmt->GetBulletChar();
+ else
+ sTxt = pTxtNd->GetNumString();
+
+ m_aStyles.append(' ');
+
+ if (sTxt.Len())
+ {
+ m_aStyles.append(m_rExport.OutString(sTxt, m_rExport.eDefaultEncoding));
+ }
+
+ if( bExportNumRule )
+ {
+ if( OUTLINE_RULE != pRule->GetRuleType() )
+ {
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
+ m_aStyles.append('}');
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
+ if( nLvl > 8 ) // RTF knows only 9 levels
+ {
+ m_aStyles.append((sal_Int32)8);
+ m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SOUTLVL);
+ m_aStyles.append((sal_Int32)nLvl);
+ m_aStyles.append('}');
+ }
+ else
+ m_aStyles.append((sal_Int32)nLvl);
+ }
+ else
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB "}");
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LS);
+ m_aStyles.append((sal_Int32)m_rExport.GetId(*pRule)+1);
+ m_aStyles.append(' ');
+ }
+ else if( sTxt.Len() )
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
+ }
+ FormatLRSpace(aLR);
+ }
+}
+
+void RtfAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if (!rScriptSpace.GetValue( ))
+ return;
+ switch ( rScriptSpace.Which( ) )
+ {
+ case RES_PARATR_SCRIPTSPACE:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ASPALPHA);
+ break;
+ /* Is this needed?
+ case RES_PARATR_HANGINGPUNCTUATION:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOOVERFLOW);
+ break;
+ case RES_PARATR_FORBIDDEN_RULES:
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOCWRAP);
+ break;*/
+ default:
+ break;
+ }
+}
+
+void RtfAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const char* pStr;
+ switch ( rAlign.GetValue() )
+ {
+ case SvxParaVertAlignItem::TOP: pStr = OOO_STRING_SVTOOLS_RTF_FAHANG; break;
+ case SvxParaVertAlignItem::BOTTOM: pStr = OOO_STRING_SVTOOLS_RTF_FAVAR; break;
+ case SvxParaVertAlignItem::CENTER: pStr = OOO_STRING_SVTOOLS_RTF_FACENTER; break;
+ case SvxParaVertAlignItem::BASELINE: pStr = OOO_STRING_SVTOOLS_RTF_FAROMAN; break;
+ // default == SvxParaVertAlignItem::AUTOMATIC
+ default: pStr = OOO_STRING_SVTOOLS_RTF_FAAUTO; break;
+ }
+ m_aStyles.append(pStr);
+}
+
+void RtfAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& /*rGrid*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax )
+ {
+ if( rSize.GetWidth() )
+ {
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_ABSW);
+ m_aRunText.append((sal_Int32)rSize.GetWidth());
+ }
+
+ if( rSize.GetHeight() )
+ {
+ long nH = rSize.GetHeight();
+ if( ATT_FIX_SIZE == rSize.GetHeightSizeType() )
+ nH = -nH;
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_ABSH);
+ m_aRunText.append((sal_Int32)nH);
+ }
+ }
+ else if (m_rExport.bOutPageDescs)
+ {
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGWSXN);
+ m_aSectionBreaks.append((sal_Int32)rSize.GetWidth());
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGHSXN);
+ m_aSectionBreaks.append((sal_Int32)rSize.GetHeight());
+ if (!m_bBufferSectionBreaks)
+ m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
+ }
+}
+
+void RtfAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( !m_rExport.bOutFlyFrmAttrs )
+ {
+ if( m_rExport.bOutPageDescs )
+ {
+ if( rLRSpace.GetLeft() )
+ {
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGLSXN);
+ m_aSectionBreaks.append((sal_Int32)rLRSpace.GetLeft());
+ }
+ if( rLRSpace.GetRight() )
+ {
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGRSXN);
+ m_aSectionBreaks.append((sal_Int32)rLRSpace.GetRight());
+ }
+ if (!m_bBufferSectionBreaks)
+ m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
+ }
+ else
+ {
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LI);
+ m_aStyles.append( (sal_Int32) rLRSpace.GetTxtLeft() );
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RI);
+ m_aStyles.append( (sal_Int32) rLRSpace.GetRight() );
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LIN);
+ m_aStyles.append( (sal_Int32) rLRSpace.GetTxtLeft() );
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RIN);
+ m_aStyles.append( (sal_Int32) rLRSpace.GetRight() );
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FI);
+ m_aStyles.append( (sal_Int32) rLRSpace.GetTxtFirstLineOfst() );
+ }
+ }
+ else if (rLRSpace.GetLeft() == rLRSpace.GetRight() && m_rExport.bRTFFlySyntax)
+ {
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_DFRMTXTX;
+ m_rExport.OutLong( rLRSpace.GetLeft() );
+ }
+}
+
+void RtfAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( !m_rExport.bOutFlyFrmAttrs )
+ {
+ if( m_rExport.bOutPageDescs )
+ {
+ if( rULSpace.GetUpper() )
+ {
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGTSXN);
+ m_aSectionBreaks.append((sal_Int32)rULSpace.GetUpper());
+ }
+ if( rULSpace.GetLower() )
+ {
+ m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGBSXN);
+ m_aSectionBreaks.append((sal_Int32)rULSpace.GetLower());
+ }
+ if (!m_bBufferSectionBreaks)
+ m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
+ }
+ else
+ {
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
+ m_aStyles.append( (sal_Int32) rULSpace.GetUpper() );
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
+ m_aStyles.append( (sal_Int32) rULSpace.GetLower() );
+ }
+ }
+ else if (rULSpace.GetUpper() == rULSpace.GetLower() && m_rExport.bRTFFlySyntax)
+ {
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_DFRMTXTY;
+ m_rExport.OutLong( rULSpace.GetLower() );
+ }
+}
+
+void RtfAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( m_rExport.bOutFlyFrmAttrs && !m_rExport.bRTFFlySyntax )
+ {
+ SwSurround eSurround = rSurround.GetSurround();
+ BOOL bGold = SURROUND_IDEAL == eSurround;
+ if( bGold )
+ eSurround = SURROUND_PARALLEL;
+ RTFSurround aMC( bGold, static_cast< BYTE >(eSurround) );
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLYMAINCNT);
+ m_aRunText.append( (sal_Int32) aMC.GetValue() );
+ }
+}
+
+void RtfAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax )
+ {
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_PVPARA);
+
+ switch (rFlyVert.GetVertOrient())
+ {
+ case text::VertOrientation::TOP:
+ case text::VertOrientation::LINE_TOP:
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_POSYT);
+ break;
+ case text::VertOrientation::BOTTOM:
+ case text::VertOrientation::LINE_BOTTOM:
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_POSYB);
+ break;
+ case text::VertOrientation::CENTER:
+ case text::VertOrientation::LINE_CENTER:
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_POSYC);
+ break;
+ case text::VertOrientation::NONE:
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_POSY);
+ m_aRunText.append((sal_Int32)rFlyVert.GetPos());
+ break;
+ default:
+ break;
+ }
+ }
+ else if ( !m_rExport.bRTFFlySyntax )
+ {
+ RTFVertOrient aVO( static_cast< USHORT >(rFlyVert.GetVertOrient()), static_cast< USHORT >(rFlyVert.GetRelationOrient()) );
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLYVERT);
+ m_aRunText.append((sal_Int32)aVO.GetValue());
+ }
+}
+
+void RtfAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax )
+ {
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_PHCOL);
+
+ const char* pS = 0;
+ switch(rFlyHori.GetHoriOrient())
+ {
+ case text::HoriOrientation::RIGHT:
+ pS = rFlyHori.IsPosToggle() ? OOO_STRING_SVTOOLS_RTF_POSXO : OOO_STRING_SVTOOLS_RTF_POSXR;
+ break;
+ case text::HoriOrientation::LEFT:
+ pS = rFlyHori.IsPosToggle() ? OOO_STRING_SVTOOLS_RTF_POSXI : OOO_STRING_SVTOOLS_RTF_POSXL;
+ break;
+ case text::HoriOrientation::CENTER:
+ pS = OOO_STRING_SVTOOLS_RTF_POSXC;
+ break;
+ case text::HoriOrientation::NONE:
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_POSX);
+ m_aRunText.append((sal_Int32)rFlyHori.GetPos());
+ break;
+ default:
+ break;
+ }
+ if (pS)
+ m_aRunText.append(pS);
+ } else if ( !m_rExport.bRTFFlySyntax )
+ {
+ RTFHoriOrient aHO( static_cast< USHORT >(rFlyHori.GetHoriOrient()),
+ static_cast< USHORT >(rFlyHori.GetRelationOrient()) );
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLYHORZ);
+ m_aRunText.append((sal_Int32)aHO.GetValue());
+ }
+}
+
+void RtfAttributeOutput::FormatAnchor( const SwFmtAnchor& rAnchor )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( !m_rExport.bRTFFlySyntax )
+ {
+ USHORT nId = static_cast< USHORT >(rAnchor.GetAnchorId());
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLYANCHOR);
+ m_aRunText.append((sal_Int32)nId);
+ switch( nId )
+ {
+ case FLY_AT_PAGE:
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLYPAGE);
+ m_aRunText.append((sal_Int32)rAnchor.GetPageNum());
+ break;
+ case FLY_AT_PARA:
+ case FLY_AS_CHAR:
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLYCNTNT);
+ break;
+ }
+ }
+}
+
+void RtfAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if( !rBrush.GetColor().GetTransparency() )
+ {
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHCBPAT);
+ m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
+ }
+}
+
+void RtfAttributeOutput::FormatBox( const SvxBoxItem& rBox )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ static USHORT __READONLY_DATA aBorders[] = {
+ BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT };
+ static const sal_Char* aBorderNames[] = {
+ OOO_STRING_SVTOOLS_RTF_BRDRT, OOO_STRING_SVTOOLS_RTF_BRDRL, OOO_STRING_SVTOOLS_RTF_BRDRB, OOO_STRING_SVTOOLS_RTF_BRDRR };
+
+ USHORT nDist = rBox.GetDistance();
+
+ if ( m_rExport.bRTFFlySyntax )
+ return;
+
+ if( rBox.GetTop() && rBox.GetBottom() &&
+ rBox.GetLeft() && rBox.GetRight() &&
+ *rBox.GetTop() == *rBox.GetBottom() &&
+ *rBox.GetTop() == *rBox.GetLeft() &&
+ *rBox.GetTop() == *rBox.GetRight() &&
+ nDist == rBox.GetDistance( BOX_LINE_TOP ) &&
+ nDist == rBox.GetDistance( BOX_LINE_LEFT ) &&
+ nDist == rBox.GetDistance( BOX_LINE_BOTTOM ) &&
+ nDist == rBox.GetDistance( BOX_LINE_RIGHT ))
+ m_aSectionBreaks.append(OutBorderLine( m_rExport, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist ));
+ else
+ {
+ const USHORT* pBrd = aBorders;
+ const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
+ for(int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
+ {
+ if (const SvxBorderLine* pLn = rBox.GetLine(*pBrd))
+ {
+ m_aSectionBreaks.append(OutBorderLine(m_rExport, pLn, *pBrdNms,
+ rBox.GetDistance(*pBrd)));
+ }
+ }
+ }
+
+ const USHORT* pBrd = aBorders;
+ const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
+ for( int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms )
+ {
+ const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
+ if( pLn )
+ {
+ m_aSectionBreaks.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
+ m_aSectionBreaks.append(OutBorderLine( m_rExport, pLn, *pBrdNms ));
+ m_aSectionBreaks.append("}" OOO_STRING_SVTOOLS_RTF_BRSP);
+ m_aSectionBreaks.append((sal_Int32)rBox.GetDistance( *pBrd ));
+ }
+ }
+
+ if (!m_bBufferSectionBreaks)
+ m_aStyles.append(m_aSectionBreaks.makeStringAndClear());
+}
+
+void RtfAttributeOutput::FormatColumns_Impl( USHORT nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLS;
+ m_rExport.OutLong( nCols );
+
+ if( bEven )
+ {
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLSX;
+ m_rExport.OutLong( rCol.GetGutterWidth( TRUE ) );
+ }
+ else
+ {
+ const SwColumns & rColumns = rCol.GetColumns( );
+ for( USHORT n = 0; n < nCols; )
+ {
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLNO;
+ m_rExport.OutLong( n+1 );
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLW;
+ m_rExport.OutLong( rCol.CalcPrtColWidth( n, nPageSize ) );
+
+ if( ++n != nCols )
+ {
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLSR;
+ m_rExport.OutLong( rColumns[ n-1 ]->GetRight() +
+ rColumns[ n ]->GetLeft() );
+ }
+ }
+ }
+}
+
+void RtfAttributeOutput::FormatKeep( const SvxFmtKeepItem& rItem )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if( rItem.GetValue() )
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEPN);
+}
+
+void RtfAttributeOutput::FormatTextGrid( const SwTextGridItem& /*rGrid*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( !rNumbering.IsCount( ) )
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOLINE);
+}
+
+void RtfAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if (!m_rExport.bOutPageDescs)
+ {
+ if (rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP)
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RTLPAR);
+ else
+ m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LTRPAR);
+ }
+}
+
+void RtfAttributeOutput::WriteExpand( const SwField* /*pFld*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::RefField( const SwField& /*rFld*/, const String& /*rRef*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::HiddenField( const SwField& /*rFld*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::SetField( const SwField& /*rFld*/, ww::eField /*eType*/, const String& /*rCmd*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfAttributeOutput::PostitField( const SwField* pFld )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ const SwPostItField& rPFld = *(SwPostItField*)pFld;
+
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " ");
+ m_aRunText.append(OUStringToOString(OUString(rPFld.GetPar1()), m_rExport.eCurrentEncoding));
+ m_aRunText.append("}");
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNAUTHOR " ");
+ m_aRunText.append(OUStringToOString(OUString(rPFld.GetPar1()), m_rExport.eCurrentEncoding));
+ m_aRunText.append("}");
+ m_aRunText.append(OOO_STRING_SVTOOLS_RTF_CHATN);
+
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ANNOTATION);
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNDATE " ");
+ m_aRunText.append((sal_Int32)sw::ms::DateTime2DTTM(rPFld.GetDate()));
+ m_aRunText.append('}');
+ m_aRunText.append(OUStringToOString(OUString(rPFld.GetTxt()), m_rExport.eCurrentEncoding));
+ m_aRunText.append('}');
+}
+
+bool RtfAttributeOutput::DropdownField( const SwField* /*pFld*/ )
+{
+ // this is handled in OutputFlyFrame_Impl()
+ return true;
+}
+
+RtfAttributeOutput::RtfAttributeOutput( RtfExport &rExport )
+ : m_rExport( rExport ),
+ m_pTableWrt( NULL ),
+ m_bTableCellOpen( false ),
+ m_nTableDepth( 0 ),
+ m_bTblAfterCell( false ),
+ m_nColBreakNeeded( false ),
+ m_bBufferSectionBreaks( false ),
+ m_bBufferSectionHeaders( false )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+}
+
+RtfAttributeOutput::~RtfAttributeOutput()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+}
+
+MSWordExportBase& RtfAttributeOutput::GetExport()
+{
+ return m_rExport;
+}
+
+// These are used by wwFont::WriteRtf()
+
+/// Start the font.
+void RtfAttributeOutput::StartFont( const String& rFamilyName ) const
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << OUStringToOString( OUString( rFamilyName ), m_rExport.eCurrentEncoding ).getStr();
+}
+
+/// End the font.
+void RtfAttributeOutput::EndFont() const
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << ";}";
+}
+
+/// Alternate name for the font.
+void RtfAttributeOutput::FontAlternateName( const String& rName ) const
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_FALT << ' ';
+ m_rExport.Strm() << OUStringToOString( OUString( rName ), m_rExport.eCurrentEncoding ) << '}';
+}
+
+/// Font charset.
+void RtfAttributeOutput::FontCharset( sal_uInt8 nCharSet ) const
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_FCHARSET;
+ m_rExport.OutULong( nCharSet );
+ m_rExport.Strm() << ' ';
+}
+
+/// Font family.
+void RtfAttributeOutput::FontFamilyType( FontFamily eFamily, const wwFont &rFont ) const
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_F;
+
+ const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL;
+ switch (eFamily)
+ {
+ case FAMILY_ROMAN:
+ pStr = OOO_STRING_SVTOOLS_RTF_FROMAN;
+ break;
+ case FAMILY_SWISS:
+ pStr = OOO_STRING_SVTOOLS_RTF_FSWISS;
+ break;
+ case FAMILY_MODERN:
+ pStr = OOO_STRING_SVTOOLS_RTF_FMODERN;
+ break;
+ case FAMILY_SCRIPT:
+ pStr = OOO_STRING_SVTOOLS_RTF_FSCRIPT;
+ break;
+ case FAMILY_DECORATIVE:
+ pStr = OOO_STRING_SVTOOLS_RTF_FDECOR;
+ break;
+ default:
+ break;
+ }
+ m_rExport.OutULong(m_rExport.maFontHelper.GetId(rFont)) << pStr;
+}
+
+/// Font pitch.
+void RtfAttributeOutput::FontPitchType( FontPitch ePitch ) const
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_FPRQ;
+
+ USHORT nVal = 0;
+ switch (ePitch)
+ {
+ case PITCH_FIXED:
+ nVal = 1;
+ break;
+ case PITCH_VARIABLE:
+ nVal = 2;
+ break;
+ default:
+ break;
+ }
+ m_rExport.OutULong(nVal);
+}
+
+static bool IsEMF(const sal_uInt8 *pGraphicAry, unsigned long nSize)
+{
+ if (pGraphicAry && (nSize > 0x2c ))
+ {
+ // check the magic number
+ if (
+ (pGraphicAry[0x28] == 0x20 ) && (pGraphicAry[0x29] == 0x45) &&
+ (pGraphicAry[0x2a] == 0x4d ) && (pGraphicAry[0x2b] == 0x46)
+ )
+ {
+ //emf detected
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool StripMetafileHeader(const sal_uInt8 *&rpGraphicAry, unsigned long &rSize)
+{
+ if (rpGraphicAry && (rSize > 0x22))
+ {
+ if (
+ (rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) &&
+ (rpGraphicAry[2] == 0xc6) && (rpGraphicAry[3] == 0x9a)
+ )
+ { // we have to get rid of the metafileheader
+ rpGraphicAry += 22;
+ rSize -= 22;
+ return true;
+ }
+ }
+ return false;
+}
+
+static OString WriteHex(const sal_uInt8* pData, sal_uInt32 nSize, sal_uInt32 nLimit = 64)
+{
+ OStringBuffer aRet;
+
+ sal_uInt32 nBreak = 0;
+ for (sal_uInt32 i = 0; i < nSize; i++)
+ {
+ OString sNo = OString::valueOf(sal_Int32(pData[i]), 16);
+ if (sNo.getLength() < 2)
+ aRet.append('0');
+ aRet.append(sNo);
+ if (++nBreak == nLimit)
+ {
+ aRet.append(RtfExport::sNewLine);
+ nBreak = 0;
+ }
+ }
+
+ return aRet.makeStringAndClear();
+}
+
+static OString WriteHex(sal_Int32 nNum)
+{
+ return WriteHex((sal_uInt8*)&nNum, sizeof(sal_Int32));
+}
+
+static OString WriteHex(OString sString)
+{
+ OStringBuffer aRet;
+
+ aRet.append(WriteHex(sString.getLength()+1));
+ aRet.append(WriteHex((sal_uInt8*)sString.getStr(), sString.getLength()+1));
+
+ return aRet.makeStringAndClear();
+}
+
+static OString ExportPICT(const Size &rOrig, const Size &rRendered, const Size &rMapped,
+ const SwCropGrf &rCr, const char *pBLIPType, const sal_uInt8 *pGraphicAry,
+ unsigned long nSize)
+{
+ OStringBuffer aRet;
+ bool bIsWMF = (const char *)pBLIPType == (const char *)OOO_STRING_SVTOOLS_RTF_WMETAFILE ? true : false;
+ if (pBLIPType && nSize && pGraphicAry)
+ {
+ aRet.append("{" OOO_STRING_SVTOOLS_RTF_PICT);
+
+ long nXCroppedSize = rOrig.Width()-(rCr.GetLeft() + rCr.GetRight());
+ long nYCroppedSize = rOrig.Height()-(rCr.GetTop() + rCr.GetBottom());
+ /* #127543#: Graphic with a zero height or width, typically copied from webpages, caused
+ crashes. */
+ if( !nXCroppedSize )
+ nXCroppedSize = 100;
+ if( !nYCroppedSize )
+ nYCroppedSize = 100;
+
+ //Given the original size and taking cropping into account
+ //first, how much has the original been scaled to get the
+ //final rendered size
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEX);
+ aRet.append((sal_Int32)((100 * rRendered.Width()) / nXCroppedSize));
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEY);
+ aRet.append((sal_Int32)((100 * rRendered.Height()) / nYCroppedSize));
+
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPL);
+ aRet.append((sal_Int32)rCr.GetLeft());
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPR);
+ aRet.append((sal_Int32)rCr.GetRight());
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPT);
+ aRet.append((sal_Int32)rCr.GetTop());
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPB);
+ aRet.append((sal_Int32)rCr.GetBottom());
+
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICW);
+ aRet.append((sal_Int32)rMapped.Width());
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICH);
+ aRet.append((sal_Int32)rMapped.Height());
+
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
+ aRet.append((sal_Int32)rOrig.Width());
+ aRet.append(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
+ aRet.append((sal_Int32)rOrig.Height());
+
+ aRet.append(pBLIPType);
+ if (bIsWMF)
+ {
+ aRet.append((sal_Int32)8);
+ StripMetafileHeader(pGraphicAry, nSize);
+ }
+ aRet.append(RtfExport::sNewLine);
+ aRet.append(WriteHex(pGraphicAry, nSize));
+ aRet.append('}');
+ }
+ return aRet.makeStringAndClear();
+}
+
+void RtfAttributeOutput::FlyFrameOLEData( SwOLENode& rOLENode )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
+ sal_Int64 nAspect = rOLENode.GetAspect();
+ svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
+ SvGlobalName aObjName(aObjRef->getClassID());
+
+ if (SotExchange::IsMath(aObjName))
+ {
+ // ObjectHeader
+ m_aRunText.append(WriteHex(0x00000501)); // OLEVersion
+ m_aRunText.append(WriteHex(0x00000002)); // FormatID
+ m_aRunText.append(WriteHex(OString("Equation.3"))); // ClassName
+ m_aRunText.append(WriteHex(0x00000000)); // TopicName
+ m_aRunText.append(WriteHex(0x00000000)); // ItemName
+
+ // NativeData
+ SvMemoryStream *pStream = new SvMemoryStream;
+ SvStorage* pStorage = new SvStorage(*pStream);
+ m_rExport.pOLEExp->ExportOLEObject( aObjRef, *pStorage );
+ pStream->Seek(STREAM_SEEK_TO_END);
+ sal_uInt32 nNativeDataSize = pStream->Tell();
+ const sal_uInt8* pNativeData = (sal_uInt8*)pStream->GetData();
+ m_aRunText.append(WriteHex(nNativeDataSize));
+ m_aRunText.append(RtfExport::sNewLine);
+ m_aRunText.append(WriteHex(pNativeData, nNativeDataSize, 126));
+ m_aRunText.append(RtfExport::sNewLine);
+ delete pStream;
+
+ // MetaFilePresentationObject
+ pStream = new SvMemoryStream;
+ Graphic* pGraphic = rOLENode.GetGraphic();
+ if (GraphicConverter::Export(*pStream, *pGraphic, CVT_WMF) != ERRCODE_NONE)
+ OSL_ENSURE(false, "failed to export the presentation data");
+ pStream->Seek(STREAM_SEEK_TO_END);
+ sal_uInt32 nPresentationDataSize = pStream->Tell();
+ const sal_uInt8* pPresentationData = (sal_uInt8*)pStream->GetData();
+ m_aRunText.append(WriteHex(pPresentationData, nPresentationDataSize, 126));
+ }
+}
+
+void RtfAttributeOutput::FlyFrameOLE( SwOLENode& rOLENode, const Size& rSize )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ SvMemoryStream aStream;
+ const sal_uInt8* pGraphicAry = 0;
+ sal_uInt32 nSize = 0;
+ Graphic* pGraphic = rOLENode.GetGraphic();
+
+ Size aSize(sw::util::GetSwappedInSize(rOLENode));
+ Size aRendered(aSize);
+ aRendered.Width() = rSize.Width();
+ aRendered.Height() = rSize.Height();
+ Size aMapped(pGraphic->GetPrefSize());
+ const SwCropGrf &rCr = (const SwCropGrf &)rOLENode.GetAttr(RES_GRFATR_CROPGRF);
+ const sal_Char* pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
+
+ if (GraphicConverter::Export(aStream, *pGraphic, CVT_WMF) != ERRCODE_NONE)
+ OSL_ENSURE(false, "failed to export the graphic");
+ aStream.Seek(STREAM_SEEK_TO_END);
+ nSize = aStream.Tell();
+ pGraphicAry = (sal_uInt8*)aStream.GetData();
+
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_OBJECT OOO_STRING_SVTOOLS_RTF_OBJEMB);
+
+ // export the object data in the appropriate format; RTF requires the usage of the OLE 1.0 format
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_OBJDATA " ");
+ FlyFrameOLEData(rOLENode);
+ m_aRunText.append("}{" OOO_STRING_SVTOOLS_RTF_RESULT);
+
+ SwTwips nHeight = aSize.Height();
+ nHeight/=20; //nHeight was in twips, want it in half points, but then half of total height.
+ long nFontHeight = ((const SvxFontHeightItem&)m_rExport.GetItem(RES_CHRATR_FONTSIZE)).GetHeight();
+ nHeight-=nFontHeight/20;
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_DN).append(nHeight);
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
+ m_aRunText.append(ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize));
+ m_aRunText.append("}}}}");
+}
+
+void RtfAttributeOutput::FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ SvMemoryStream aStream;
+ const sal_uInt8* pGraphicAry = 0;
+ sal_uInt32 nSize = 0;
+
+ Graphic aGraphic(rGrfNode.GetGrf());
+
+ // If there is no graphic there is not much point in parsing it
+ if(aGraphic.GetType()==GRAPHIC_NONE)
+ return;
+
+ GfxLink aGraphicLink;
+ const sal_Char* pBLIPType = 0;
+ if (aGraphic.IsLink())
+ {
+ aGraphicLink = aGraphic.GetLink();
+ nSize = aGraphicLink.GetDataSize();
+ pGraphicAry = aGraphicLink.GetData();
+ switch (aGraphicLink.GetType())
+ {
+ case GFX_LINK_TYPE_NATIVE_JPG:
+ pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
+ break;
+ case GFX_LINK_TYPE_NATIVE_PNG:
+ pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
+ break;
+ case GFX_LINK_TYPE_NATIVE_WMF:
+ pBLIPType =
+ IsEMF(pGraphicAry, nSize) ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ GraphicType eGraphicType = aGraphic.GetType();
+ if (!pGraphicAry)
+ {
+ if (ERRCODE_NONE == GraphicConverter::Export(aStream, aGraphic,
+ (eGraphicType == GRAPHIC_BITMAP) ? CVT_PNG : CVT_WMF))
+ {
+ pBLIPType = (eGraphicType == GRAPHIC_BITMAP) ?
+ OOO_STRING_SVTOOLS_RTF_PNGBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
+ aStream.Seek(STREAM_SEEK_TO_END);
+ nSize = aStream.Tell();
+ pGraphicAry = (sal_uInt8*)aStream.GetData();
+ }
+ }
+
+ Size aMapped(eGraphicType == GRAPHIC_BITMAP ? aGraphic.GetSizePixel() : aGraphic.GetPrefSize());
+
+ const SwCropGrf &rCr = (const SwCropGrf &)rGrfNode.GetAttr(RES_GRFATR_CROPGRF);
+
+ //Get original size in twips
+ Size aSize(sw::util::GetSwappedInSize(rGrfNode));
+ Size aRendered(aSize);
+ aRendered.Width() = rSize.Width();
+ aRendered.Height() = rSize.Height();
+
+ /*
+ If the graphic is not of type WMF then we will have to store two
+ graphics, one in the native format wrapped in shppict, and the other in
+ the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
+ a wmf already then we don't need any such wrapping
+ */
+ bool bIsWMF = (const sal_Char*)pBLIPType == (const sal_Char*)OOO_STRING_SVTOOLS_RTF_WMETAFILE ? true : false;
+ if (!bIsWMF)
+ m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
+
+ if (pBLIPType)
+ m_aRunText.append(ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize));
+ else
+ {
+ aStream.Seek(0);
+ GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
+ pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
+ aStream.Seek(STREAM_SEEK_TO_END);
+ nSize = aStream.Tell();
+ pGraphicAry = (sal_uInt8*)aStream.GetData();
+
+ m_aRunText.append(ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize));
+ }
+
+ if (!bIsWMF)
+ {
+ m_aRunText.append("}" "{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT);
+
+ aStream.Seek(0);
+ GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
+ pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
+ aStream.Seek(STREAM_SEEK_TO_END);
+ nSize = aStream.Tell();
+ pGraphicAry = (sal_uInt8*)aStream.GetData();
+
+ m_aRunText.append(ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize));
+
+ m_aRunText.append('}');
+ }
+
+ m_aRunText.append(m_rExport.sNewLine);
+}
+
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
new file mode 100644
index 0000000000..8a4d0e7665
--- /dev/null
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -0,0 +1,573 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _RTFATTRIBUTEOUTPUT_HXX_
+#define _RTFATTRIBUTEOUTPUT_HXX_
+
+#include <set>
+#include "attributeoutputbase.hxx"
+#include "fields.hxx"
+
+#include <vcl/vclenum.hxx>
+
+#include <fldbas.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <vector>
+
+class RtfExport;
+
+class SwGrfNode;
+class SwOLENode;
+class SdrObject;
+
+class RtfAttributeOutput : public AttributeOutputBase
+{
+public:
+ /// Export the state of RTL/CJK.
+ virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript );
+
+ /// Start of the paragraph.
+ virtual void StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo );
+
+ /// End of the paragraph.
+ virtual void EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner );
+
+ /// Empty paragraph.
+ virtual void EmptyParagraph();
+
+ /// Called before we start outputting the attributes.
+ virtual void StartParagraphProperties( const SwTxtNode& rNode );
+
+ /// Called after we end outputting the attributes.
+ virtual void EndParagraphProperties();
+
+ /// Start of the text run.
+ virtual void StartRun( const SwRedlineData* pRedlineData );
+
+ /// End of the text run.
+ virtual void EndRun();
+
+ /// Called before we start outputting the attributes.
+ virtual void StartRunProperties();
+
+ /// Called after we end outputting the attributes.
+ virtual void EndRunProperties( const SwRedlineData* pRedlineData );
+
+ /// Output text (inside a run).
+ virtual void RunText( const String& rText, rtl_TextEncoding eCharSet = RTL_TEXTENCODING_UTF8 );
+
+ // Access to (anyway) private buffers, used by the sdr exporter
+ rtl::OStringBuffer& RunText();
+ rtl::OStringBuffer& Styles();
+
+ /// Output text (without markup).
+ virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet );
+
+ /// Output ruby start.
+ virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby );
+
+ /// Output ruby end.
+ virtual void EndRuby();
+
+ /// Output URL start.
+ virtual bool StartURL( const String& rUrl, const String& rTarget );
+
+ /// Output URL end.
+ virtual bool EndURL();
+
+ virtual void FieldVanish( const String& rTxt, ww::eField eType );
+
+ /// Output redlining.
+ ///
+ /// The common attribute that can be among the run properties.
+ virtual void Redline( const SwRedlineData* pRedline );
+
+ virtual void FormatDrop( const SwTxtNode& rNode, const SwFmtDrop& rSwFmtDrop, USHORT nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner );
+
+ /// Output style.
+ virtual void ParagraphStyle( USHORT nStyle );
+
+ virtual void TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo );
+
+ virtual void TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner );
+
+ virtual void TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ virtual void TableRowEnd( sal_uInt32 nDepth );
+
+ /// Start of the styles table.
+ virtual void StartStyles();
+
+ /// End of the styles table.
+ virtual void EndStyles( USHORT nNumberOfStyles );
+
+ /// Write default style.
+ virtual void DefaultStyle( USHORT nStyle );
+
+ /// Start of a style in the styles table.
+ virtual void StartStyle( const String& rName, bool bPapFmt,
+ USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId );
+
+ /// End of a style in the styles table.
+ virtual void EndStyle();
+
+ /// Start of (paragraph or run) properties of a style.
+ virtual void StartStyleProperties( bool bParProp, USHORT nStyle );
+
+ /// End of (paragraph or run) properties of a style.
+ virtual void EndStyleProperties( bool bParProp );
+
+ /// Numbering rule and Id.
+ virtual void OutlineNumbering( BYTE nLvl, const SwNumFmt &rNFmt, const SwFmt &rFmt );
+
+ /// Page break
+ /// As a paragraph property - the paragraph should be on the next page.
+ virtual void PageBreakBefore( bool bBreak );
+
+ /// Write a section break
+ /// msword::ColumnBreak or msword::PageBreak
+ virtual void SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo = NULL );
+
+ /// Start of the section properties.
+ virtual void StartSection();
+
+ /// End of the section properties.
+ virtual void EndSection();
+
+ /// Protection of forms.
+ virtual void SectionFormProtection( bool bProtected );
+
+ /// Numbering of the lines in the document.
+ virtual void SectionLineNumbering( ULONG nRestartNo, const SwLineNumberInfo& rLnNumInfo );
+
+ /// Has different headers/footers for the title page.
+ virtual void SectionTitlePage();
+
+ /// Description of the page borders.
+ virtual void SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* pFirstPageFmt );
+
+ /// Columns populated from right/numbers on the right side?
+ virtual void SectionBiDi( bool bBiDi );
+
+ /// The style of the page numbers.
+ ///
+ /// nPageRestartNumberr being 0 means no restart.
+ virtual void SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber );
+
+ /// The type of breaking.
+ virtual void SectionType( BYTE nBreakCode );
+
+ /// Definition of a numbering instance.
+ virtual void NumberingDefinition( USHORT nId, const SwNumRule &rRule );
+
+ /// Start of the abstract numbering definition instance.
+ virtual void StartAbstractNumbering( USHORT nId );
+
+ /// End of the abstract numbering definition instance.
+ virtual void EndAbstractNumbering();
+
+ /// All the numbering level information.
+ virtual void NumberingLevel( BYTE nLevel,
+ USHORT nStart,
+ USHORT nNumberingType,
+ SvxAdjust eAdjust,
+ const BYTE *pNumLvlPos,
+ BYTE nFollow,
+ const wwFont *pFont,
+ const SfxItemSet *pOutSet,
+ sal_Int16 nIndentAt,
+ sal_Int16 nFirstLineIndex,
+ sal_Int16 nListTabPos,
+ const String &rNumberingString );
+
+ void WriteField_Impl( const SwField* pFld, ww::eField eType, const String& rFldCmd, BYTE nMode );
+ void WriteBookmarks_Impl( std::vector< rtl::OUString >& rStarts, std::vector< rtl::OUString >& rEnds );
+ void WriteHeaderFooter_Impl( const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr );
+
+protected:
+ /// Output frames - the implementation.
+ virtual void OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft );
+
+ /// Sfx item Sfx item RES_CHRATR_CASEMAP
+ virtual void CharCaseMap( const SvxCaseMapItem& rCaseMap );
+
+ /// Sfx item Sfx item RES_CHRATR_COLOR
+ virtual void CharColor( const SvxColorItem& rColor);
+
+ /// Sfx item Sfx item RES_CHRATR_CONTOUR
+ virtual void CharContour( const SvxContourItem& rContour );
+
+ /// Sfx item RES_CHRATR_CROSSEDOUT
+ virtual void CharCrossedOut( const SvxCrossedOutItem& rCrossedOut );
+
+ /// Sfx item RES_CHRATR_ESCAPEMENT
+ virtual void CharEscapement( const SvxEscapementItem& rEscapement );
+
+ /// Sfx item RES_CHRATR_FONT
+ virtual void CharFont( const SvxFontItem& rFont );
+
+ /// Sfx item RES_CHRATR_FONTSIZE
+ virtual void CharFontSize( const SvxFontHeightItem& rFontSize );
+
+ /// Sfx item RES_CHRATR_KERNING
+ virtual void CharKerning( const SvxKerningItem& rKerning );
+
+ /// Sfx item RES_CHRATR_LANGUAGE
+ virtual void CharLanguage( const SvxLanguageItem& rLanguage );
+
+ /// Sfx item RES_CHRATR_POSTURE
+ virtual void CharPosture( const SvxPostureItem& rPosture );
+
+ /// Sfx item RES_CHRATR_SHADOWED
+ virtual void CharShadow( const SvxShadowedItem& rShadow );
+
+ /// Sfx item RES_CHRATR_UNDERLINE
+ virtual void CharUnderline( const SvxUnderlineItem& rUnderline );
+
+ /// Sfx item RES_CHRATR_WEIGHT
+ virtual void CharWeight( const SvxWeightItem& rWeight );
+
+ /// Sfx item RES_CHRATR_AUTOKERN
+ virtual void CharAutoKern( const SvxAutoKernItem& );
+
+ /// Sfx item RES_CHRATR_BLINK
+ virtual void CharAnimatedText( const SvxBlinkItem& rBlink );
+
+ /// Sfx item RES_CHRATR_BACKGROUND
+ virtual void CharBackground( const SvxBrushItem& rBrush );
+
+ /// Sfx item RES_CHRATR_CJK_FONT
+ virtual void CharFontCJK( const SvxFontItem& rFont );
+
+ /// Sfx item RES_CHRATR_CJK_FONTSIZE
+ virtual void CharFontSizeCJK( const SvxFontHeightItem& rFontSize );
+
+ /// Sfx item RES_CHRATR_CJK_LANGUAGE
+ virtual void CharLanguageCJK( const SvxLanguageItem& rLanguageItem );
+
+ /// Sfx item RES_CHRATR_CJK_POSTURE
+ virtual void CharPostureCJK( const SvxPostureItem& rPosture );
+
+ /// Sfx item RES_CHRATR_CJK_WEIGHT
+ virtual void CharWeightCJK( const SvxWeightItem& rWeight );
+
+ /// Sfx item RES_CHRATR_CTL_FONT
+ virtual void CharFontCTL( const SvxFontItem& rFont );
+
+ /// Sfx item RES_CHRATR_CTL_FONTSIZE
+ virtual void CharFontSizeCTL( const SvxFontHeightItem& rFontSize );
+
+ /// Sfx item RES_CHRATR_CTL_LANGUAGE
+ virtual void CharLanguageCTL( const SvxLanguageItem& rLanguageItem );
+
+ /// Sfx item RES_CHRATR_CTL_POSTURE
+ virtual void CharPostureCTL( const SvxPostureItem& rWeight );
+
+ /// Sfx item RES_CHRATR_CTL_WEIGHT
+ virtual void CharWeightCTL( const SvxWeightItem& rWeight );
+
+ /// Sfx item RES_CHRATR_ROTATE
+ virtual void CharRotate( const SvxCharRotateItem& rRotate );
+
+ /// Sfx item RES_CHRATR_EMPHASIS_MARK
+ virtual void CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark );
+
+ /// Sfx item RES_CHRATR_TWO_LINES
+ virtual void CharTwoLines( const SvxTwoLinesItem& rTwoLines );
+
+ /// Sfx item RES_CHRATR_SCALEW
+ virtual void CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth );
+
+ /// Sfx item RES_CHRATR_RELIEF
+ virtual void CharRelief( const SvxCharReliefItem& rRelief);
+
+ /// Sfx item RES_CHRATR_HIDDEN
+ virtual void CharHidden( const SvxCharHiddenItem& rHidden );
+
+ /// Sfx item RES_TXTATR_INETFMT
+ virtual void TextINetFormat( const SwFmtINetFmt& );
+
+ /// Sfx item RES_TXTATR_CHARFMT
+ virtual void TextCharFormat( const SwFmtCharFmt& );
+
+ /// Sfx item RES_TXTATR_FTN
+ virtual void TextFootnote_Impl( const SwFmtFtn& );
+
+ /// Sfx item RES_PARATR_LINESPACING
+ virtual void ParaLineSpacing_Impl( short nSpace, short nMulti );
+
+ /// Sfx item RES_PARATR_ADJUST
+ virtual void ParaAdjust( const SvxAdjustItem& rAdjust );
+
+ /// Sfx item RES_PARATR_SPLIT
+ virtual void ParaSplit( const SvxFmtSplitItem& rSplit );
+
+ /// Sfx item RES_PARATR_WIDOWS
+ virtual void ParaWidows( const SvxWidowsItem& rWidows );
+
+ /// Sfx item RES_PARATR_TABSTOP
+ virtual void ParaTabStop( const SvxTabStopItem& rTabStop );
+
+ /// Sfx item RES_PARATR_HYPHENZONE
+ virtual void ParaHyphenZone( const SvxHyphenZoneItem& );
+
+ /// Sfx item RES_PARATR_NUMRULE
+ virtual void ParaNumRule_Impl( const SwTxtNode *pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId );
+
+ /// Sfx item RES_PARATR_SCRIPTSPACE
+ virtual void ParaScriptSpace( const SfxBoolItem& );
+
+ /// Sfx item RES_PARATR_VERTALIGN
+ virtual void ParaVerticalAlign( const SvxParaVertAlignItem& rAlign );
+
+ /// Sfx item RES_PARATR_SNAPTOGRID
+ virtual void ParaSnapToGrid( const SvxParaGridItem& );
+
+ /// Sfx item RES_FRM_SIZE
+ virtual void FormatFrameSize( const SwFmtFrmSize& );
+
+ /// Sfx item RES_PAPER_BIN
+ virtual void FormatPaperBin( const SvxPaperBinItem& );
+
+ /// Sfx item RES_LR_SPACE
+ virtual void FormatLRSpace( const SvxLRSpaceItem& rLRSpace );
+
+ /// Sfx item RES_UL_SPACE
+ virtual void FormatULSpace( const SvxULSpaceItem& rULSpace );
+
+ /// Sfx item RES_SURROUND
+ virtual void FormatSurround( const SwFmtSurround& );
+
+ /// Sfx item RES_VERT_ORIENT
+ virtual void FormatVertOrientation( const SwFmtVertOrient& );
+
+ /// Sfx item RES_HORI_ORIENT
+ virtual void FormatHorizOrientation( const SwFmtHoriOrient& );
+
+ /// Sfx item RES_ANCHOR
+ virtual void FormatAnchor( const SwFmtAnchor& );
+
+ /// Sfx item RES_BACKGROUND
+ virtual void FormatBackground( const SvxBrushItem& );
+
+ /// Sfx item RES_BOX
+ virtual void FormatBox( const SvxBoxItem& );
+
+ /// Sfx item RES_COL
+ virtual void FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize );
+
+ /// Sfx item RES_KEEP
+ virtual void FormatKeep( const SvxFmtKeepItem& );
+
+ /// Sfx item RES_TEXTGRID
+ virtual void FormatTextGrid( const SwTextGridItem& );
+
+ /// Sfx item RES_LINENUMBER
+ virtual void FormatLineNumbering( const SwFmtLineNumber& );
+
+ /// Sfx item RES_FRAMEDIR
+ virtual void FormatFrameDirection( const SvxFrameDirectionItem& );
+
+ /// Write the expanded field
+ virtual void WriteExpand( const SwField* pFld );
+
+ virtual void RefField( const SwField& rFld, const String& rRef );
+ virtual void HiddenField( const SwField& rFld );
+ virtual void SetField( const SwField& rFld, ww::eField eType, const String& rCmd );
+ virtual void PostitField( const SwField* pFld );
+ virtual bool DropdownField( const SwField* pFld );
+
+ /// Reference to the export, where to get the data from
+ RtfExport &m_rExport;
+
+private:
+
+ /// Output graphic fly frames.
+ void FlyFrameGraphic( const SwGrfNode& rGrfNode, const Size& rSize );
+ void FlyFrameOLE( SwOLENode& rOLENode, const Size& rSize );
+ void FlyFrameOLEData( SwOLENode& rOLENode );
+
+ /*
+ * Table methods.
+ */
+
+ void InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ void StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ void StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ void StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ void TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner );
+
+ void EndTableCell( );
+
+ void EndTableRow( );
+
+ void EndTable();
+
+ /// End cell, row, and even the entire table if necessary.
+ void FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph = false );
+
+ void WriteTextFootnoteNumStr(const SwFmtFtn& rFootnote);
+
+ /*
+ * Current style name and its ID.
+ */
+ String m_rStyleName;
+ USHORT m_nStyleId;
+ /*
+ * Current list ID.
+ */
+ USHORT m_nListId;
+ /*
+ * This is needed because the call order is: run text, run properties, paragraph properties.
+ * What we need is the opposite.
+ */
+ rtl::OStringBuffer m_aRun;
+ rtl::OStringBuffer m_aRunText;
+ /*
+ * This is written after runs.
+ */
+ rtl::OStringBuffer m_aAfterRuns;
+ /*
+ * Same for colors and stylesheets: first we just want to output colors,
+ * need to buffer the stylesheet table to output it after the color one.
+ */
+ rtl::OStringBuffer m_aStylesheet;
+ /*
+ * This one just holds the style commands in the current style.
+ */
+ rtl::OStringBuffer m_aStyles;
+ /*
+ * This is the same as m_aStyles but the conents of it is written last.
+ */
+ rtl::OStringBuffer m_aStylesEnd;
+
+ /*
+ * We just get a "end of strike" mark at the end of strike, store here what to finish: single or double strike.
+ */
+ bool m_bStrikeDouble;
+
+ /*
+ * The current table helper.
+ */
+ SwWriteTable *m_pTableWrt;
+
+ /*
+ * Remember if we are in an open cell, or not.
+ */
+ bool m_bTableCellOpen;
+
+ /*
+ * Remember the current table depth.
+ */
+ sal_uInt32 m_nTableDepth;
+
+ /*
+ * Remember if we wrote a \cell or not.
+ */
+ bool m_bTblAfterCell;
+
+ /*
+ * For late output of row definitions.
+ */
+ rtl::OStringBuffer m_aRowDefs;
+
+ /*
+ * Is a column break needed after the next \par?
+ */
+ bool m_nColBreakNeeded;
+
+ /*
+ * If section breaks should be buffered to m_aSectionBreaks
+ */
+ bool m_bBufferSectionBreaks;
+ rtl::OStringBuffer m_aSectionBreaks;
+
+ /*
+ * If section headers (and footers) should be buffered to
+ * m_aSectionHeaders.
+ */
+ bool m_bBufferSectionHeaders;
+ rtl::OStringBuffer m_aSectionHeaders;
+
+public:
+ RtfAttributeOutput( RtfExport &rExport );
+
+ virtual ~RtfAttributeOutput();
+
+ /// Return the right export class.
+ virtual MSWordExportBase& GetExport();
+
+ rtl::OStringBuffer m_aTabStop;
+
+ // These are used by wwFont::WriteRtf()
+ /// Start the font.
+ void StartFont( const String& rFamilyName ) const;
+
+ /// End the font.
+ void EndFont() const;
+
+ /// Alternate name for the font.
+ void FontAlternateName( const String& rName ) const;
+
+ /// Font charset.
+ void FontCharset( sal_uInt8 nCharSet ) const;
+
+ /// Font family.
+ void FontFamilyType( FontFamily eFamily, const wwFont &rFont ) const;
+
+ /// Font pitch.
+ void FontPitchType( FontPitch ePitch ) const;
+};
+
+#endif // _RTFATTRIBUTEOUTPUT_HXX_
+
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
new file mode 100644
index 0000000000..6e922245e6
--- /dev/null
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -0,0 +1,1240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtfexport.hxx"
+#include "rtfexportfilter.hxx"
+#include "rtfsdrexport.hxx"
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/i18n/ScriptType.hdl>
+#include <com/sun/star/frame/XModel.hpp>
+
+#include <map>
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+
+#include <IMark.hxx>
+#include <docsh.hxx>
+#include <ndtxt.hxx>
+#include <wrtww8.hxx>
+#include <fltini.hxx>
+#include <fmtline.hxx>
+#include <fmtpdsc.hxx>
+#include <frmfmt.hxx>
+#include <section.hxx>
+#include <pagedesc.hxx>
+#include <swtable.hxx>
+#include <fmtfsize.hxx>
+#include <frmatr.hxx>
+#include <ftninfo.hxx>
+#include <fmthdft.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/protitem.hxx>
+
+#include <docary.hxx>
+#include <numrule.hxx>
+#include <charfmt.hxx>
+#include <lineinfo.hxx>
+#include <swmodule.hxx>
+
+#include "ww8par.hxx"
+#include "ww8scan.hxx"
+
+#include <comphelper/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/font.hxx>
+#include <svtools/rtfkeywd.hxx>
+#include <unotools/configmgr.hxx>
+
+using namespace ::comphelper;
+using namespace ::com::sun::star;
+
+using rtl::OString;
+using rtl::OUString;
+using rtl::OStringBuffer;
+using rtl::OUStringBuffer;
+
+using sw::mark::IMark;
+
+#if defined(UNX)
+const sal_Char RtfExport::sNewLine = '\012';
+#else
+const sal_Char __FAR_DATA RtfExport::sNewLine[] = "\015\012";
+#endif
+
+// the default text encoding for the export, if it doesn't fit unicode will
+// be used
+#define DEF_ENCODING RTL_TEXTENCODING_ASCII_US
+
+AttributeOutputBase& RtfExport::AttrOutput() const
+{
+ return *m_pAttrOutput;
+}
+
+MSWordSections& RtfExport::Sections() const
+{
+ return *m_pSections;
+}
+
+RtfSdrExport& RtfExport::SdrExporter() const
+{
+ return *m_pSdrExport;
+}
+
+bool RtfExport::CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich )
+{
+ // FIXME is this actually true for rtf? - this is copied from DOCX
+ if ( nScript == i18n::ScriptType::ASIAN )
+ {
+ // for asian in ww8, there is only one fontsize
+ // and one fontstyle (posture/weight)
+ switch ( nWhich )
+ {
+ case RES_CHRATR_FONTSIZE:
+ case RES_CHRATR_POSTURE:
+ case RES_CHRATR_WEIGHT:
+ return false;
+ default:
+ break;
+ }
+ }
+ else if ( nScript != i18n::ScriptType::COMPLEX )
+ {
+ // for western in ww8, there is only one fontsize
+ // and one fontstyle (posture/weight)
+ switch ( nWhich )
+ {
+ case RES_CHRATR_CJK_FONTSIZE:
+ case RES_CHRATR_CJK_POSTURE:
+ case RES_CHRATR_CJK_WEIGHT:
+ return false;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+void RtfExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ std::vector< OUString > aStarts;
+ std::vector< OUString > aEnds;
+
+ IMarkVector aMarks;
+ if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
+ {
+ for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
+ it < end; ++it )
+ {
+ IMark* pMark = (*it);
+ xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
+ xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+ if ( nStart == nAktPos )
+ aStarts.push_back( pMark->GetName() );
+
+ if ( nEnd == nAktPos )
+ aEnds.push_back( pMark->GetName() );
+ }
+ }
+
+ m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
+}
+
+void RtfExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ std::vector<OUString> aStarts;
+ std::vector<OUString> aEnds;
+
+ aStarts.push_back(rName);
+ aEnds.push_back(rName);
+
+ m_pAttrOutput->WriteBookmarks_Impl(aStarts, aEnds);
+}
+
+void RtfExport::WriteChar( sal_Unicode )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* WriteChar() has nothing to do for rtf. */
+}
+
+static bool IsExportNumRule( const SwNumRule& rRule, BYTE* pEnd = 0 )
+{
+ BYTE nEnd = MAXLEVEL;
+ while( nEnd-- && !rRule.GetNumFmt( nEnd ))
+ ;
+ ++nEnd;
+
+ const SwNumFmt* pNFmt;
+ BYTE nLvl;
+
+ for( nLvl = 0; nLvl < nEnd; ++nLvl )
+ if( SVX_NUM_NUMBER_NONE != ( pNFmt = &rRule.Get( nLvl ))
+ ->GetNumberingType() || pNFmt->GetPrefix().Len() ||
+ (pNFmt->GetSuffix().Len() && pNFmt->GetSuffix() != aDotStr ))
+ break;
+
+ if( pEnd )
+ *pEnd = nEnd;
+ return nLvl != nEnd;
+}
+
+void RtfExport::BuildNumbering()
+{
+ const SwNumRuleTbl& rListTbl = pDoc->GetNumRuleTbl();
+
+ for( USHORT n = rListTbl.Count()+1; n; )
+ {
+ SwNumRule* pRule;
+ --n;
+ if( n == rListTbl.Count() )
+ pRule = (SwNumRule*)pDoc->GetOutlineNumRule();
+ else
+ {
+ pRule = rListTbl[ n ];
+ if( !pDoc->IsUsed( *pRule ))
+ continue;
+ }
+
+ if( IsExportNumRule( *pRule ))
+ GetId( *pRule );
+ }
+}
+
+void RtfExport::WriteNumbering()
+{
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+
+ if ( !pUsedNumTbl )
+ return; // no numbering is used
+
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_LISTTABLE;
+ AbstractNumberingDefinitions();
+ Strm() << '}';
+
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDETABLE;
+ NumberingDefinitions();
+ Strm() << '}';
+
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+void RtfExport::WriteRevTab()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ int nRevAuthors = pDoc->GetRedlineTbl().Count();
+
+ if (nRevAuthors < 1)
+ return;
+
+ // RTF always seems to use Unknown as the default first entry
+ String sUnknown(RTL_CONSTASCII_USTRINGPARAM("Unknown"));
+ GetRedline(sUnknown);
+
+ for( USHORT i = 0; i < pDoc->GetRedlineTbl().Count(); ++i )
+ {
+ const SwRedline* pRedl = pDoc->GetRedlineTbl()[ i ];
+
+ GetRedline(SW_MOD()->GetRedlineAuthor(pRedl->GetAuthor()));
+ }
+
+ // Now write the table
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_REVTBL << ' ';
+ for(std::map<String,USHORT>::iterator aIter = m_aRedlineTbl.begin(); aIter != m_aRedlineTbl.end(); ++aIter)
+ Strm() << '{' << OutString((*aIter).first, eDefaultEncoding) << ";}";
+ Strm() << '}' << sNewLine;
+}
+
+void RtfExport::WriteHeadersFooters( BYTE nHeadFootFlags,
+ const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, BYTE /*nBreakCode*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // headers
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
+ WriteHeaderFooter( rLeftFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERL );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
+ WriteHeaderFooter( rFmt, true, OOO_STRING_SVTOOLS_RTF_HEADER );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
+ WriteHeaderFooter( rFirstPageFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERF );
+
+ // footers
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
+ WriteHeaderFooter( rLeftFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERL );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
+ WriteHeaderFooter( rFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTER );
+
+ if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
+ WriteHeaderFooter( rFirstPageFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERF );
+}
+
+void RtfExport::OutputField( const SwField* pFld, ww::eField eFldType, const String& rFldCmd, BYTE nMode )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
+}
+
+void RtfExport::WriteFormData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
+{
+ OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
+}
+
+void RtfExport::DoComboBox(const rtl::OUString& /*rName*/,
+ const rtl::OUString& /*rHelp*/,
+ const rtl::OUString& /*rToolTip*/,
+ const rtl::OUString& /*rSelected*/,
+ uno::Sequence<rtl::OUString>& /*rListItems*/)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // this is handled in RtfAttributeOutput::OutputFlyFrame_Impl
+}
+
+void RtfExport::DoFormText(const SwInputField* /*pFld*/)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // this is hanled in RtfAttributeOutput::OutputFlyFrame_Impl
+}
+
+ULONG RtfExport::ReplaceCr( BYTE )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // Completely unused for Rtf export... only here for code sharing
+ // purpose with binary export
+
+ return 0;
+}
+
+void RtfExport::WriteFonts()
+{
+ Strm() << sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_FONTTBL;
+ maFontHelper.WriteFontTable( *m_pAttrOutput );
+ Strm() << '}';
+}
+
+void RtfExport::WriteStyles()
+{
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+ pStyles->OutputStylesTable();
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+void RtfExport::WriteMainText()
+{
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+ pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
+ WriteText();
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+void RtfExport::WriteInfo()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_INFO;
+
+ SwDocShell *pDocShell(pDoc->GetDocShell());
+ uno::Reference<document::XDocumentProperties> xDocProps;
+ if (pDocShell) {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocShell->GetModel(), uno::UNO_QUERY);
+ xDocProps.set(xDPS->getDocumentProperties());
+ }
+
+ if (xDocProps.is()) {
+ OutUnicode(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle());
+ OutUnicode(OOO_STRING_SVTOOLS_RTF_SUBJECT, xDocProps->getSubject());
+
+ OutUnicode(OOO_STRING_SVTOOLS_RTF_KEYWORDS,
+ ::comphelper::string::convertCommaSeparated(xDocProps->getKeywords()));
+ OutUnicode(OOO_STRING_SVTOOLS_RTF_DOCCOMM, xDocProps->getDescription());
+
+ OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getAuthor());
+ OutDateTime(OOO_STRING_SVTOOLS_RTF_CREATIM, xDocProps->getCreationDate());
+
+ OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR,xDocProps->getModifiedBy());
+ OutDateTime(OOO_STRING_SVTOOLS_RTF_REVTIM, xDocProps->getModificationDate());
+
+ OutDateTime(OOO_STRING_SVTOOLS_RTF_PRINTIM, xDocProps->getPrintDate());
+ }
+
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_COMMENT << " ";
+ OUString sProduct;
+ utl::ConfigManager::GetDirectConfigProperty(utl::ConfigManager::PRODUCTNAME) >>= sProduct;
+ Strm() << OUStringToOString( sProduct, eCurrentEncoding) << "}{" << OOO_STRING_SVTOOLS_RTF_VERN;
+ OutULong( SUPD*10 ) << '}';
+ Strm() << '}';
+}
+
+void RtfExport::WritePageDescTable()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // Write page descriptions (page styles)
+ USHORT nSize = pDoc->GetPageDescCnt();
+ if( !nSize )
+ return;
+
+ Strm() << sNewLine; // a separator
+ bOutPageDescs = TRUE;
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_PGDSCTBL;
+ for( USHORT n = 0; n < nSize; ++n )
+ {
+ const SwPageDesc& rPageDesc =
+ const_cast<const SwDoc*>(pDoc)->GetPageDesc( n );
+
+ Strm() << sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_PGDSC;
+ OutULong( n ) << OOO_STRING_SVTOOLS_RTF_PGDSCUSE;
+ OutULong( rPageDesc.ReadUseOn() );
+
+ OutPageDescription( rPageDesc, FALSE, FALSE );
+
+ // search for the next page description
+ USHORT i = nSize;
+ while( i )
+ if( rPageDesc.GetFollow() ==
+ &const_cast<const SwDoc *>(pDoc)->GetPageDesc( --i ) )
+ break;
+ Strm() << OOO_STRING_SVTOOLS_RTF_PGDSCNXT;
+ OutULong( i ) << ' ';
+ Strm() << OutString( rPageDesc.GetName(), eDefaultEncoding) << ";}";
+ }
+ Strm() << '}' << sNewLine;
+ bOutPageDescs = FALSE;
+}
+
+void RtfExport::ExportDocument_Impl()
+{
+#ifdef DEBUG
+ // MSWordExportBase::WriteText and others write debug messages to std::clog
+ // which is not interesting while debugging RtfExport
+ std::ostringstream aOss;
+ std::streambuf *pOldBuf = std::clog.rdbuf(aOss.rdbuf());
+#endif
+
+ // Make the header
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_RTF << '1'
+ << OOO_STRING_SVTOOLS_RTF_ANSI;
+ Strm() << OOO_STRING_SVTOOLS_RTF_DEFF;
+ OutULong( maFontHelper.GetId( (SvxFontItem&)pDoc->GetAttrPool().GetDefaultItem(
+ RES_CHRATR_FONT ) ));
+ // If this not exist, MS don't understand our ansi characters (0x80-0xff).
+ Strm() << "\\adeflang1025";
+
+ // Font table
+ WriteFonts();
+
+ pStyles = new MSWordStyles( *this );
+ // Color and stylesheet table
+ WriteStyles();
+
+ // List table
+ BuildNumbering();
+ WriteNumbering();
+
+ WriteRevTab();
+
+ WriteInfo();
+ // Default TabSize
+ Strm() << m_pAttrOutput->m_aTabStop.makeStringAndClear() << sNewLine;
+ // Page description
+ WritePageDescTable();
+
+ // Enable form protection by default if needed, as there is no switch to
+ // enable it on a per-section basis. OTOH don't always enable it as it
+ // breaks moving of drawings - so write it only in case there is really a
+ // protected section in the document.
+ {
+ const SfxItemPool& rPool = pDoc->GetAttrPool();
+ USHORT nMaxItem = rPool.GetItemCount(RES_PROTECT);
+ for( USHORT n = 0; n < nMaxItem; ++n )
+ {
+ const SvxProtectItem* pProtect = (const SvxProtectItem*)rPool.GetItem(RES_PROTECT, n);
+ if (pProtect && pProtect->IsCntntProtected())
+ {
+ Strm() << OOO_STRING_SVTOOLS_RTF_FORMPROT;
+ break;
+ }
+ }
+ }
+
+ // enable form field shading
+ Strm() << OOO_STRING_SVTOOLS_RTF_FORMSHADE;
+
+ // size and empty margins of the page
+ if( pDoc->GetPageDescCnt() )
+ {
+ //JP 06.04.99: Bug 64361 - Seeking the first SwFmtPageDesc. If
+ // no set, the default is valid
+ const SwFmtPageDesc* pSttPgDsc = 0;
+ {
+ const SwNode& rSttNd = *pDoc->GetNodes()[
+ pDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 ];
+ const SfxItemSet* pSet = 0;
+
+ if( rSttNd.IsCntntNode() )
+ pSet = &rSttNd.GetCntntNode()->GetSwAttrSet();
+ else if( rSttNd.IsTableNode() )
+ pSet = &rSttNd.GetTableNode()->GetTable().
+ GetFrmFmt()->GetAttrSet();
+ else if( rSttNd.IsSectionNode() )
+ pSet = &rSttNd.GetSectionNode()->GetSection().
+ GetFmt()->GetAttrSet();
+
+ if( pSet )
+ {
+ USHORT nPosInDoc;
+ pSttPgDsc = (SwFmtPageDesc*)&pSet->Get( RES_PAGEDESC );
+ if( !pSttPgDsc->GetPageDesc() )
+ pSttPgDsc = 0;
+ else if( pDoc->FindPageDescByName( pSttPgDsc->
+ GetPageDesc()->GetName(), &nPosInDoc ))
+ {
+ Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_PGDSCNO;
+ OutULong( nPosInDoc ) << '}';
+ }
+ }
+ }
+ const SwPageDesc& rPageDesc = pSttPgDsc ? *pSttPgDsc->GetPageDesc()
+ : const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 );
+ const SwFrmFmt &rFmtPage = rPageDesc.GetMaster();
+
+ {
+ if( rPageDesc.GetLandscape() )
+ Strm() << OOO_STRING_SVTOOLS_RTF_LANDSCAPE;
+
+ const SwFmtFrmSize& rSz = rFmtPage.GetFrmSize();
+ // Clipboard document is always created without a printer, then
+ // the size will be always LONG_MAX! Solution then is to use A4
+ if( LONG_MAX == rSz.GetHeight() || LONG_MAX == rSz.GetWidth() )
+ {
+ Strm() << OOO_STRING_SVTOOLS_RTF_PAPERH;
+ Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
+ OutULong( a4.Height() ) << OOO_STRING_SVTOOLS_RTF_PAPERW;
+ OutULong( a4.Width() );
+ }
+ else
+ {
+ Strm() << OOO_STRING_SVTOOLS_RTF_PAPERH;
+ OutULong( rSz.GetHeight() ) << OOO_STRING_SVTOOLS_RTF_PAPERW;
+ OutULong( rSz.GetWidth() );
+ }
+ }
+
+ {
+ const SvxLRSpaceItem& rLR = rFmtPage.GetLRSpace();
+ Strm() << OOO_STRING_SVTOOLS_RTF_MARGL;
+ OutLong( rLR.GetLeft() ) << OOO_STRING_SVTOOLS_RTF_MARGR;
+ OutLong( rLR.GetRight() );
+ }
+
+ {
+ const SvxULSpaceItem& rUL = rFmtPage.GetULSpace();
+ Strm() << OOO_STRING_SVTOOLS_RTF_MARGT;
+ OutLong( rUL.GetUpper() ) << OOO_STRING_SVTOOLS_RTF_MARGB;
+ OutLong( rUL.GetLower() );
+ }
+
+ Strm() << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE;
+ // All sections are unlocked by default
+ Strm() << OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED;
+ OutLong(1);
+ OutPageDescription( rPageDesc, FALSE, TRUE ); // Changed bCheckForFirstPage to TRUE so headers
+ // following title page are correctly added - i13107
+ if( pSttPgDsc )
+ {
+ pAktPageDesc = &rPageDesc;
+ }
+ }
+
+ // line numbering
+ const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo();
+ if ( rLnNumInfo.IsPaintLineNumbers() )
+ AttrOutput().SectionLineNumbering( 0, rLnNumInfo );
+
+ {
+ // write the footnotes and endnotes-out Info
+ const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
+
+ const char* pOut = FTNPOS_CHAPTER == rFtnInfo.ePos
+ ? OOO_STRING_SVTOOLS_RTF_ENDDOC
+ : OOO_STRING_SVTOOLS_RTF_FTNBJ;
+ Strm() << pOut << OOO_STRING_SVTOOLS_RTF_FTNSTART;
+ OutLong( rFtnInfo.nFtnOffset + 1 );
+
+ switch( rFtnInfo.eNum )
+ {
+ case FTNNUM_PAGE: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTPG; break;
+ case FTNNUM_DOC: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTCONT; break;
+ // case FTNNUM_CHAPTER:
+ default: pOut = OOO_STRING_SVTOOLS_RTF_FTNRESTART; break;
+ }
+ Strm() << pOut;
+
+ switch( rFtnInfo.aFmt.GetNumberingType() )
+ {
+ case SVX_NUM_CHARS_LOWER_LETTER:
+ case SVX_NUM_CHARS_LOWER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_FTNNALC; break;
+ case SVX_NUM_CHARS_UPPER_LETTER:
+ case SVX_NUM_CHARS_UPPER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_FTNNAUC; break;
+ case SVX_NUM_ROMAN_LOWER: pOut = OOO_STRING_SVTOOLS_RTF_FTNNRLC; break;
+ case SVX_NUM_ROMAN_UPPER: pOut = OOO_STRING_SVTOOLS_RTF_FTNNRUC; break;
+ case SVX_NUM_CHAR_SPECIAL: pOut = OOO_STRING_SVTOOLS_RTF_FTNNCHI; break;
+ // case SVX_NUM_ARABIC:
+ default: pOut = OOO_STRING_SVTOOLS_RTF_FTNNAR; break;
+ }
+ Strm() << pOut;
+
+
+ const SwEndNoteInfo& rEndNoteInfo = pDoc->GetEndNoteInfo();
+
+ Strm() << OOO_STRING_SVTOOLS_RTF_AENDDOC << OOO_STRING_SVTOOLS_RTF_AFTNRSTCONT
+ << OOO_STRING_SVTOOLS_RTF_AFTNSTART;
+ OutLong( rEndNoteInfo.nFtnOffset + 1 );
+
+ switch( rEndNoteInfo.aFmt.GetNumberingType() )
+ {
+ case SVX_NUM_CHARS_LOWER_LETTER:
+ case SVX_NUM_CHARS_LOWER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNALC; break;
+ case SVX_NUM_CHARS_UPPER_LETTER:
+ case SVX_NUM_CHARS_UPPER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAUC; break;
+ case SVX_NUM_ROMAN_LOWER: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRLC; break;
+ case SVX_NUM_ROMAN_UPPER: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRUC; break;
+ case SVX_NUM_CHAR_SPECIAL: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNCHI; break;
+ // case SVX_NUM_ARABIC:
+ default: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAR; break;
+ }
+ Strm() << pOut;
+ }
+
+ Strm() << sNewLine;
+
+ // Init sections
+ m_pSections = new MSWordSections( *this );
+
+ WriteMainText();
+
+ Strm() << '}';
+
+#ifdef DEBUG
+ std::clog.rdbuf(pOldBuf);
+#endif
+}
+
+void RtfExport::PrepareNewPageDesc( const SfxItemSet* pSet,
+ const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt,
+ const SwPageDesc* pNewPgDesc )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ const SwSectionFmt* pFmt = GetSectionFormat( rNd );
+ const ULONG nLnNm = GetSectionLineNo( pSet, rNd );
+
+ OSL_ENSURE( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
+
+ if ( pNewPgDescFmt )
+ m_pSections->AppendSection( *pNewPgDescFmt, rNd, pFmt, nLnNm );
+ else if ( pNewPgDesc )
+ m_pSections->AppendSection( pNewPgDesc, rNd, pFmt, nLnNm );
+
+ AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
+}
+
+bool RtfExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
+{
+ bool bRet( false );
+
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
+ {
+ if (const SwFmt *pParent = rFmt.DerivedFrom())
+ {
+ if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
+ {
+ // Level 9 disables the outline
+ Strm() << OOO_STRING_SVTOOLS_RTF_LEVEL << 9;
+
+ bRet = true;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+void RtfExport::OutputGrfNode( const SwGrfNode& )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop, see RtfAttributeOutput::FlyFrameGraphic */
+}
+
+void RtfExport::OutputOLENode( const SwOLENode& )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop, see RtfAttributeOutput::FlyFrameOLE */
+}
+
+void RtfExport::AppendSection( const SwPageDesc* pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_pSections->AppendSection( pPageDesc, pFmt, nLnNum );
+ AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
+}
+
+RtfExport::RtfExport( RtfExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam, Writer* pWriter )
+ : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
+ m_pFilter( pFilter ),
+ m_pWriter( pWriter ),
+ m_pAttrOutput( NULL ),
+ m_pSections( NULL ),
+ m_pSdrExport( NULL ),
+ eDefaultEncoding(
+ rtl_getTextEncodingFromWindowsCharset(
+ sw::ms::rtl_TextEncodingToWinCharset(DEF_ENCODING))),
+ eCurrentEncoding(eDefaultEncoding),
+ bRTFFlySyntax(false)
+{
+ // the attribute output for the document
+ m_pAttrOutput = new RtfAttributeOutput( *this );
+ // that just causes problems for RTF
+ bSubstituteBullets = false;
+ // needed to have a complete font table
+ maFontHelper.bLoadAllFonts = true;
+ // the related SdrExport
+ m_pSdrExport = new RtfSdrExport( *this );
+
+ if (!m_pWriter)
+ m_pWriter = &m_pFilter->m_aWriter;
+}
+
+RtfExport::~RtfExport()
+{
+ delete m_pAttrOutput, m_pAttrOutput = NULL;
+ delete m_pSdrExport, m_pSdrExport = NULL;
+}
+
+SvStream& RtfExport::Strm()
+{
+ return m_pWriter->Strm();
+}
+
+SvStream& RtfExport::OutULong( ULONG nVal )
+{
+ return m_pWriter->OutULong( Strm(), nVal );
+}
+
+SvStream& RtfExport::OutLong( long nVal )
+{
+ return m_pWriter->OutLong( Strm(), nVal );
+}
+
+void RtfExport::OutUnicode(const sal_Char *pToken, const String &rContent)
+{
+ if (rContent.Len())
+ {
+ Strm() << '{' << pToken << ' ';
+ Strm() << OutString( rContent, eCurrentEncoding ).getStr();
+ Strm() << '}';
+ }
+}
+
+OString RtfExport::OutHex(ULONG nHex, BYTE nLen)
+{
+ sal_Char aNToABuf[] = "0000000000000000";
+
+ OSL_ENSURE( nLen < sizeof(aNToABuf), "nLen is too big" );
+ if( nLen >= sizeof(aNToABuf) )
+ nLen = (sizeof(aNToABuf)-1);
+
+ // Set pointer to the buffer end
+ sal_Char* pStr = aNToABuf + (sizeof(aNToABuf)-1);
+ for( BYTE n = 0; n < nLen; ++n )
+ {
+ *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
+ if( *pStr > '9' )
+ *pStr += 39;
+ nHex >>= 4;
+ }
+ return OString(pStr);
+}
+
+OString RtfExport::OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc)
+{
+ OStringBuffer aBuf;
+ const sal_Char* pStr = 0;
+ // 0x0b instead of \n, etc because of the replacements in SwAttrIter::GetSnippet()
+ switch (c)
+ {
+ case 0x0b:
+ // hard line break
+ pStr = OOO_STRING_SVTOOLS_RTF_LINE;
+ break;
+ case '\t':
+ pStr = OOO_STRING_SVTOOLS_RTF_TAB;
+ break;
+ case '\\':
+ case '}':
+ case '{':
+ aBuf.append('\\');
+ aBuf.append((sal_Char)c);
+ break;
+ case 0xa0:
+ // non-breaking space
+ pStr = "\\~";
+ break;
+ case 0x1e:
+ // non-breaking hyphen
+ pStr = "\\_";
+ break;
+ case 0x1f:
+ // optional hyphen
+ pStr = "\\-";
+ break;
+ default:
+ if (c >= ' ' && c <= '~')
+ aBuf.append((sal_Char)c);
+ else {
+ //If we can't convert to the dest encoding, or if
+ //its an uncommon multibyte sequence which most
+ //readers won't be able to handle correctly, then
+ //If we can't convert to the dest encoding, then
+ //export as unicode
+ OUString sBuf(&c, 1);
+ OString sConverted;
+ sal_uInt32 nFlags =
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR;
+ bool bWriteAsUnicode = !(sBuf.convertToString(&sConverted,
+ eDestEnc, nFlags))
+ || (RTL_TEXTENCODING_UTF8==eDestEnc); // #i43933# do not export UTF-8 chars in RTF;
+ if (bWriteAsUnicode)
+ sBuf.convertToString(&sConverted,
+ eDestEnc, OUSTRING_TO_OSTRING_CVTFLAGS);
+ const sal_Int32 nLen = sConverted.getLength();
+
+ if (bWriteAsUnicode && pUCMode)
+ {
+ // then write as unicode - character
+ if (*pUCMode != nLen)
+ {
+ aBuf.append("\\uc");
+ aBuf.append((sal_Int32)nLen);
+ // #i47831# add an additional whitespace, so that "document whitespaces" are not ignored.
+ aBuf.append(' ');
+ *pUCMode = nLen;
+ }
+ aBuf.append("\\u");
+ aBuf.append((sal_Int32)c);
+ }
+
+ for (sal_Int32 nI = 0; nI < nLen; ++nI)
+ {
+ aBuf.append("\\'");
+ aBuf.append(OutHex(sConverted.getStr()[nI], 2));
+ }
+ }
+ }
+ if (pStr) {
+ aBuf.append(pStr);
+ aBuf.append(' ');
+ }
+ return aBuf.makeStringAndClear();
+}
+
+OString RtfExport::OutString(const String &rStr, rtl_TextEncoding eDestEnc)
+{
+ OSL_TRACE("%s, rStr = '%s'", OSL_THIS_FUNC,
+ OUStringToOString( OUString( rStr ), eCurrentEncoding ).getStr());
+ OStringBuffer aBuf;
+ int nUCMode = 1;
+ for (xub_StrLen n = 0; n < rStr.Len(); ++n)
+ aBuf.append(OutChar(rStr.GetChar(n), &nUCMode, eDestEnc));
+ if (nUCMode != 1) {
+ aBuf.append(OOO_STRING_SVTOOLS_RTF_UC);
+ aBuf.append((sal_Int32)1);
+ aBuf.append(" "); // #i47831# add an additional whitespace, so that "document whitespaces" are not ignored.;
+ }
+ return aBuf.makeStringAndClear();
+}
+
+void RtfExport::OutDateTime(const sal_Char* pStr, const util::DateTime& rDT )
+{
+ Strm() << '{' << pStr << OOO_STRING_SVTOOLS_RTF_YR;
+ OutULong( rDT.Year ) << OOO_STRING_SVTOOLS_RTF_MO;
+ OutULong( rDT.Month ) << OOO_STRING_SVTOOLS_RTF_DY;
+ OutULong( rDT.Day ) << OOO_STRING_SVTOOLS_RTF_HR;
+ OutULong( rDT.Hours ) << OOO_STRING_SVTOOLS_RTF_MIN;
+ OutULong( rDT.Minutes ) << '}';
+}
+
+USHORT RtfExport::GetColor( const Color& rColor ) const
+{
+ for (RtfColorTbl::const_iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); it++ )
+ if ((*it).second == rColor) {
+ OSL_TRACE("%s returning %d (%d,%d,%d)", OSL_THIS_FUNC, (*it).first, rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue());
+ return (*it).first;
+ }
+ OSL_ENSURE( FALSE, "No such Color in m_aColTbl!" );
+ return 0;
+}
+
+void RtfExport::InsColor( const Color& rCol )
+{
+ USHORT n;
+ for (RtfColorTbl::iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); it++ )
+ if ((*it).second == rCol)
+ return; // Already in the table
+ if (rCol.GetColor() == COL_AUTO)
+ n = 0;
+ else
+ {
+ n = m_aColTbl.size();
+ // Fix for the case when first a !COL_AUTO gets inserted as #0, then
+ // gets overwritten by COL_AUTO
+ if (!n)
+ n++;
+ }
+ m_aColTbl.insert(std::pair<USHORT,Color>( n, rCol ));
+}
+
+void RtfExport::InsColorLine( const SvxBoxItem& rBox )
+{
+ const SvxBorderLine* pLine = 0;
+
+ if( rBox.GetTop() )
+ InsColor( (pLine = rBox.GetTop())->GetColor() );
+ if( rBox.GetBottom() && pLine != rBox.GetBottom() )
+ InsColor( (pLine = rBox.GetBottom())->GetColor() );
+ if( rBox.GetLeft() && pLine != rBox.GetLeft() )
+ InsColor( (pLine = rBox.GetLeft())->GetColor() );
+ if( rBox.GetRight() && pLine != rBox.GetRight() )
+ InsColor( rBox.GetRight()->GetColor() );
+}
+void RtfExport::OutColorTable()
+{
+ // Build the table from rPool since the colors provided to
+ // RtfAttributeOutput callbacks are too late.
+ USHORT n, nMaxItem;
+ const SfxItemPool& rPool = pDoc->GetAttrPool();
+
+ // char color
+ {
+ const SvxColorItem* pCol = (const SvxColorItem*)GetDfltAttr(
+ RES_CHRATR_COLOR );
+ InsColor( pCol->GetValue() );
+ if( 0 != ( pCol = (const SvxColorItem*)rPool.GetPoolDefaultItem(
+ RES_CHRATR_COLOR ) ))
+ InsColor( pCol->GetValue() );
+ nMaxItem = rPool.GetItemCount(RES_CHRATR_COLOR);
+ for( n = 0; n < nMaxItem; ++n )
+ {
+ if( 0 != (pCol = (const SvxColorItem*)rPool.GetItem(
+ RES_CHRATR_COLOR, n ) ) )
+ InsColor( pCol->GetValue() );
+ }
+
+ const SvxUnderlineItem* pUnder = (const SvxUnderlineItem*)GetDfltAttr( RES_CHRATR_UNDERLINE );
+ InsColor( pUnder->GetColor() );
+ nMaxItem = rPool.GetItemCount(RES_CHRATR_UNDERLINE);
+ for( n = 0; n < nMaxItem;n++)
+ {
+ if( 0 != (pUnder = (const SvxUnderlineItem*)rPool.GetItem( RES_CHRATR_UNDERLINE, n ) ) )
+ InsColor( pUnder->GetColor() );
+
+ }
+
+ const SvxOverlineItem* pOver = (const SvxOverlineItem*)GetDfltAttr( RES_CHRATR_OVERLINE );
+ InsColor( pOver->GetColor() );
+ nMaxItem = rPool.GetItemCount(RES_CHRATR_OVERLINE);
+ for( n = 0; n < nMaxItem;n++)
+ {
+ if( 0 != (pOver = (const SvxOverlineItem*)rPool.GetItem( RES_CHRATR_OVERLINE, n ) ) )
+ InsColor( pOver->GetColor() );
+
+ }
+
+ }
+
+ // background color
+ static const USHORT aBrushIds[] = {
+ RES_BACKGROUND, RES_CHRATR_BACKGROUND, 0 };
+
+ for( const USHORT* pIds = aBrushIds; *pIds; ++pIds )
+ {
+ const SvxBrushItem* pBkgrd = (const SvxBrushItem*)GetDfltAttr( *pIds );
+ InsColor( pBkgrd->GetColor() );
+ if( 0 != ( pBkgrd = (const SvxBrushItem*)rPool.GetPoolDefaultItem(
+ *pIds ) ))
+ {
+ InsColor( pBkgrd->GetColor() );
+ }
+ nMaxItem = rPool.GetItemCount( *pIds );
+ for( n = 0; n < nMaxItem; ++n )
+ if( 0 != (pBkgrd = (const SvxBrushItem*)rPool.GetItem(
+ *pIds , n ) ))
+ {
+ InsColor( pBkgrd->GetColor() );
+ }
+ }
+
+ // shadow color
+ {
+ const SvxShadowItem* pShadow = (const SvxShadowItem*)GetDfltAttr(
+ RES_SHADOW );
+ InsColor( pShadow->GetColor() );
+ if( 0 != ( pShadow = (const SvxShadowItem*)rPool.GetPoolDefaultItem(
+ RES_SHADOW ) ))
+ {
+ InsColor( pShadow->GetColor() );
+ }
+ nMaxItem = rPool.GetItemCount(RES_SHADOW);
+ for( n = 0; n < nMaxItem; ++n )
+ if( 0 != (pShadow = (const SvxShadowItem*)rPool.GetItem(
+ RES_SHADOW, n ) ) )
+ {
+ InsColor( pShadow->GetColor() );
+ }
+ }
+
+ // frame border color
+ {
+ const SvxBoxItem* pBox;
+ if( 0 != ( pBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
+ RES_BOX ) ))
+ InsColorLine( *pBox );
+ nMaxItem = rPool.GetItemCount(RES_BOX);
+ for( n = 0; n < nMaxItem; ++n )
+ if( 0 != (pBox = (const SvxBoxItem*)rPool.GetItem( RES_BOX, n ) ))
+ InsColorLine( *pBox );
+ }
+
+ for( n = 0; n < m_aColTbl.size(); n++ )
+ {
+ const Color& rCol = m_aColTbl[ n ];
+ if( n || COL_AUTO != rCol.GetColor() )
+ {
+ Strm() << OOO_STRING_SVTOOLS_RTF_RED;
+ OutULong( rCol.GetRed() ) << OOO_STRING_SVTOOLS_RTF_GREEN;
+ OutULong( rCol.GetGreen() ) << OOO_STRING_SVTOOLS_RTF_BLUE;
+ OutULong( rCol.GetBlue() );
+ }
+ Strm() << ';';
+ }
+}
+
+void RtfExport::InsStyle( USHORT nId, const OString& rStyle )
+{
+ m_aStyTbl.insert(std::pair<USHORT,OString>(nId, rStyle) );
+}
+
+OString* RtfExport::GetStyle( USHORT nId )
+{
+ std::map<USHORT,OString>::iterator i = m_aStyTbl.find(nId);
+ if (i != m_aStyTbl.end())
+ return &i->second;
+ return NULL;
+}
+
+USHORT RtfExport::GetRedline( const String& rAuthor )
+{
+ std::map<String,USHORT>::iterator i = m_aRedlineTbl.find(rAuthor);
+ if (i != m_aRedlineTbl.end())
+ return i->second;
+ else
+ {
+ int nId = m_aRedlineTbl.size();
+ m_aRedlineTbl.insert(std::pair<String,USHORT>(rAuthor,nId));
+ return nId;
+ }
+}
+
+void RtfExport::OutContent( const SwNode& rNode )
+{
+ OutputContentNode(*rNode.GetCntntNode());
+}
+
+void RtfExport::OutPageDescription( const SwPageDesc& rPgDsc, BOOL bWriteReset, BOOL bCheckForFirstPage )
+{
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+ const SwPageDesc *pSave = pAktPageDesc;
+
+ pAktPageDesc = &rPgDsc;
+ if( bCheckForFirstPage && pAktPageDesc->GetFollow() &&
+ pAktPageDesc->GetFollow() != pAktPageDesc )
+ pAktPageDesc = pAktPageDesc->GetFollow();
+
+ if( bWriteReset )
+ {
+ if( pCurPam->GetPoint()->nNode == pOrigPam->Start()->nNode )
+ Strm() << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE;
+ else
+ Strm() << OOO_STRING_SVTOOLS_RTF_SECT << OOO_STRING_SVTOOLS_RTF_SECTD;
+ }
+
+ if( pAktPageDesc->GetLandscape() )
+ Strm() << OOO_STRING_SVTOOLS_RTF_LNDSCPSXN;
+
+ const SwFmt *pFmt = &pAktPageDesc->GetMaster(); //GetLeft();
+ bOutPageDescs = true;
+ OutputFormat(*pFmt, true, false);
+ bOutPageDescs = false;
+
+ // normal header / footer (without a style)
+ const SfxPoolItem* pItem;
+ if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_HEADER, FALSE,
+ &pItem ) == SFX_ITEM_SET)
+ WriteHeaderFooter(*pItem, true);
+ if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_FOOTER, FALSE,
+ &pItem ) == SFX_ITEM_SET)
+ WriteHeaderFooter(*pItem, false);
+
+ // title page
+ if( pAktPageDesc != &rPgDsc )
+ {
+ pAktPageDesc = &rPgDsc;
+ if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_HEADER,
+ FALSE, &pItem ) == SFX_ITEM_SET )
+ WriteHeaderFooter(*pItem, true);
+ if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_FOOTER,
+ FALSE, &pItem ) == SFX_ITEM_SET )
+ WriteHeaderFooter(*pItem, false);
+ }
+
+ // numbering type
+ AttrOutput().SectionPageNumbering(pAktPageDesc->GetNumType().GetNumberingType(), 0);
+
+ pAktPageDesc = pSave;
+ //bOutPageDesc = bOldOut;
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+void RtfExport::WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader)
+{
+ if (bHeader)
+ {
+ const SwFmtHeader& rHeader = (const SwFmtHeader&)rItem;
+ if (!rHeader.IsActive())
+ return;
+ }
+ else
+ {
+ const SwFmtFooter& rFooter = (const SwFmtFooter&)rItem;
+ if (!rFooter.IsActive())
+ return;
+ }
+
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+
+ Strm() << (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY : OOO_STRING_SVTOOLS_RTF_FOOTERY);
+ OutLong( pAktPageDesc->GetMaster().
+ GetULSpace().GetUpper() );
+ const sal_Char* pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADER : OOO_STRING_SVTOOLS_RTF_FOOTER);
+ /* is this a title page? */
+ if( pAktPageDesc->GetFollow() && pAktPageDesc->GetFollow() != pAktPageDesc )
+ {
+ Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG;
+ pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERF : OOO_STRING_SVTOOLS_RTF_FOOTERF);
+ }
+ Strm() << '{' << pStr;
+ WriteHeaderFooterText(pAktPageDesc->GetMaster(), bHeader);
+ Strm() << '}';
+
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+void RtfExport::WriteHeaderFooter(const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr)
+{
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+
+ m_pAttrOutput->WriteHeaderFooter_Impl( rFmt, bHeader, pStr );
+
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+class SwRTFWriter : public Writer
+{
+ public:
+ SwRTFWriter( const String& rFilterName, const String& rBaseURL );
+ virtual ~SwRTFWriter();
+ virtual ULONG WriteStream();
+};
+
+SwRTFWriter::SwRTFWriter( const String& /*rFltName*/, const String & rBaseURL )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ SetBaseURL( rBaseURL );
+}
+
+SwRTFWriter::~SwRTFWriter()
+{}
+
+ULONG SwRTFWriter::WriteStream()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ RtfExport aExport( NULL, pDoc, new SwPaM( *pCurPam->End(), *pCurPam->Start() ), pCurPam, this );
+ aExport.ExportDocument( true );
+ return 0;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportRTF( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+ xRet = new SwRTFWriter( rFltName, rBaseURL );
+}
+
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx
new file mode 100644
index 0000000000..0a2f3f4d0b
--- /dev/null
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -0,0 +1,211 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _RTFEXPORT_HXX_
+#define _RTFEXPORT_HXX_
+
+#include <set>
+#include "rtfattributeoutput.hxx"
+#include "wrtww8.hxx"
+
+#include <rtl/ustring.hxx>
+
+#include <cstdio>
+#include <map>
+
+class RtfExportFilter;
+class RtfSdrExport;
+typedef std::map<USHORT,Color> RtfColorTbl;
+typedef std::map<USHORT,rtl::OString> RtfStyleTbl;
+typedef std::map<String,USHORT> RtfRedlineTbl;
+class SwNode;
+class SwEndNode;
+class SwTableNode;
+class SwTxtNode;
+class SwGrfNode;
+class SwOLENode;
+class SwSectionNode;
+class SwNumRuleTbl;
+
+namespace com { namespace sun { namespace star {
+ namespace frame { class XModel; }
+} } }
+
+/// The class that does all the actual RTF export-related work.
+class RtfExport : public MSWordExportBase
+{
+ /// Pointer to the filter that owns us.
+ RtfExportFilter *m_pFilter;
+ Writer* m_pWriter;
+
+ /// Attribute output for document.
+ RtfAttributeOutput *m_pAttrOutput;
+
+ /// Sections/headers/footers
+ MSWordSections *m_pSections;
+
+ RtfSdrExport *m_pSdrExport;
+
+public:
+ /// Access to the attribute output class.
+ virtual AttributeOutputBase& AttrOutput() const;
+
+ /// Access to the sections/headers/footres.
+ virtual MSWordSections& Sections() const;
+
+ /// Access to the Rtf Sdr exporter.
+ virtual RtfSdrExport& SdrExporter() const;
+
+ /// Hack, unfortunately necessary at some places for now.
+ virtual bool HackIsWW8OrHigher() const { return true; }
+
+ /// Guess the script (asian/western).
+ virtual bool CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich );
+
+ virtual void AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen );
+
+ virtual void AppendBookmark( const rtl::OUString& rName, bool bSkip = false );
+
+ virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t()*/ ) { /* no-op for rtf, most probably should not even be in MSWordExportBase */ }
+ virtual void WriteChar( sal_Unicode );
+
+ /// Write the numbering table.
+ virtual void WriteNumbering();
+
+ /// Write the revision table.
+ virtual void WriteRevTab();
+
+ /// Output the actual headers and footers.
+ virtual void WriteHeadersFooters( BYTE nHeadFootFlags,
+ const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, BYTE nBreakCode );
+
+ /// Write the field
+ virtual void OutputField( const SwField* pFld, ww::eField eFldType,
+ const String& rFldCmd, BYTE nMode = nsFieldFlags::WRITEFIELD_ALL );
+
+ /// Write the data of the form field
+ virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark );
+ virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark );
+
+ virtual void DoComboBox(const rtl::OUString &rName,
+ const rtl::OUString &rHelp,
+ const rtl::OUString &ToolTip,
+ const rtl::OUString &rSelected,
+ com::sun::star::uno::Sequence<rtl::OUString> &rListItems);
+
+ virtual void DoFormText(const SwInputField * pFld);
+
+ virtual ULONG ReplaceCr( BYTE nChar );
+
+protected:
+ /// Format-dependant part of the actual export.
+ virtual void ExportDocument_Impl();
+
+ virtual void SectionBreaksAndFrames( const SwTxtNode& /*rNode*/ ) {}
+
+ /// Get ready for a new section.
+ virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
+ const SwNode& rNd,
+ const SwFmtPageDesc* pNewPgDescFmt = 0,
+ const SwPageDesc* pNewPgDesc = 0 );
+
+ /// Return value indicates if an inherited outline numbering is suppressed.
+ virtual bool DisallowInheritingOutlineNumbering(const SwFmt &rFmt);
+
+ /// Output SwGrfNode
+ virtual void OutputGrfNode( const SwGrfNode& );
+
+ /// Output SwOLENode
+ virtual void OutputOLENode( const SwOLENode& );
+
+ virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum );
+
+public:
+ /// Pass the pDocument, pCurrentPam and pOriginalPam to the base class.
+ RtfExport( RtfExportFilter *pFilter, SwDoc *pDocument,
+ SwPaM *pCurrentPam, SwPaM *pOriginalPam, Writer* pWriter );
+
+ /// Destructor.
+ virtual ~RtfExport();
+
+#if defined(UNX)
+ static const sal_Char sNewLine; // \012 or \015
+#else
+ static const sal_Char __FAR_DATA sNewLine[]; // \015\012
+#endif
+
+ rtl_TextEncoding eDefaultEncoding;
+ rtl_TextEncoding eCurrentEncoding;
+ /// This is used by OutputFlyFrame_Impl() to control the written syntax
+ bool bRTFFlySyntax;
+
+ BOOL m_bOutStyleTab : 1;
+ SvStream& Strm();
+ SvStream& OutULong( ULONG nVal );
+ SvStream& OutLong( long nVal );
+ void OutUnicode(const sal_Char *pToken, const String &rContent);
+ void OutDateTime(const sal_Char* pStr, const util::DateTime& rDT );
+ rtl::OString OutChar(sal_Unicode c, int *pUCMode, rtl_TextEncoding eDestEnc);
+ rtl::OString OutString(const String &rStr, rtl_TextEncoding eDestEnc);
+ rtl::OString OutHex(ULONG nHex, BYTE nLen);
+ void OutPageDescription( const SwPageDesc& rPgDsc, BOOL bWriteReset, BOOL bCheckForFirstPage );
+ void OutContent( const SwNode& rNode );
+
+ USHORT GetColor( const Color& rColor ) const;
+ void InsColor( const Color& rCol );
+ void InsColorLine( const SvxBoxItem& rBox );
+ void OutColorTable();
+ USHORT GetRedline( const String& rAuthor );
+
+ void InsStyle( USHORT nId, const rtl::OString& rStyle );
+ rtl::OString* GetStyle( USHORT nId );
+
+private:
+ /// No copying.
+ RtfExport( const RtfExport& );
+
+ /// No copying.
+ RtfExport& operator=( const RtfExport& );
+
+ void WriteFonts();
+ void WriteStyles();
+ void WriteMainText();
+ void WriteInfo();
+ /// Writes the writer-specific \pgdsctbl group.
+ void WritePageDescTable();
+ /// This is necessary to have the numbering table ready before the main text is being processed.
+ void BuildNumbering();
+ void WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader);
+ void WriteHeaderFooter(const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr);
+
+ RtfColorTbl m_aColTbl;
+ RtfStyleTbl m_aStyTbl;
+ RtfRedlineTbl m_aRedlineTbl;
+};
+
+#endif // _RTFEXPORT_HXX_
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfexportfilter.cxx b/sw/source/filter/ww8/rtfexportfilter.cxx
new file mode 100644
index 0000000000..df680e4264
--- /dev/null
+++ b/sw/source/filter/ww8/rtfexportfilter.cxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <rtfexportfilter.hxx>
+#include <rtfexport.hxx>
+#include <rtfimportfilter.hxx>
+
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <unotxdoc.hxx>
+
+#include <cppuhelper/factory.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+using namespace ::comphelper;
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+RtfExportFilter::RtfExportFilter( const uno::Reference< lang::XMultiServiceFactory >& xMSF) :
+ m_xMSF( xMSF )
+{
+}
+
+RtfExportFilter::~RtfExportFilter()
+{
+}
+
+sal_Bool RtfExportFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
+ throw (uno::RuntimeException)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ MediaDescriptor aMediaDesc = aDescriptor;
+ ::uno::Reference< io::XStream > xStream =
+ aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_STREAMFOROUTPUT(), uno::Reference< io::XStream >() );
+ m_pStream = utl::UcbStreamHelper::CreateStream( xStream, sal_True );
+ m_aWriter.SetStream(m_pStream);
+
+ // get SwDoc*
+ uno::Reference< uno::XInterface > xIfc( m_xSrcDoc, uno::UNO_QUERY );
+ SwXTextDocument *pTxtDoc = dynamic_cast< SwXTextDocument * >( xIfc.get() );
+ if ( !pTxtDoc ) {
+ return sal_False;
+ }
+
+ SwDoc *pDoc = pTxtDoc->GetDocShell()->GetDoc();
+ if ( !pDoc ) {
+ return sal_False;
+ }
+
+ // get SwPaM*
+ // we get SwPaM for the entire document; copy&paste is handled internally, not via UNO
+ SwPaM aPam( pDoc->GetNodes().GetEndOfContent() );
+ aPam.SetMark();
+ aPam.Move( fnMoveBackward, fnGoDoc );
+
+ SwPaM *pCurPam = new SwPaM( *aPam.End(), *aPam.Start() );
+
+ // export the document
+ // (in a separate block so that it's destructed before the commit)
+ {
+ RtfExport aExport( this, pDoc, pCurPam, &aPam, NULL );
+ aExport.ExportDocument( true );
+ }
+
+ // delete the pCurPam
+ if ( pCurPam )
+ {
+ while ( pCurPam->GetNext() != pCurPam )
+ delete pCurPam->GetNext();
+ delete pCurPam;
+ }
+ delete m_pStream;
+
+ return sal_True;
+}
+
+
+void RtfExportFilter::cancel( ) throw (uno::RuntimeException)
+{
+}
+
+void RtfExportFilter::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ m_xSrcDoc = xDoc;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// UNO helpers
+//////////////////////////////////////////////////////////////////////////
+
+OUString RtfExport_getImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPL_NAME_RTFEXPORT ) );
+}
+
+uno::Sequence< OUString > SAL_CALL RtfExport_getSupportedServiceNames() throw()
+{
+ const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.ExportFilter" ) );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL RtfExport_createInstance(const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*) new RtfExportFilter( rSMgr );
+}
+
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfexportfilter.hxx b/sw/source/filter/ww8/rtfexportfilter.hxx
new file mode 100644
index 0000000000..98f102217d
--- /dev/null
+++ b/sw/source/filter/ww8/rtfexportfilter.hxx
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _RTFEXPORTFILTER_HXX_
+#define _RTFEXPORTFILTER_HXX_
+
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <tools/stream.hxx>
+#include <shellio.hxx>
+
+// This is just here so that we don't have to copy&paste its string format methods
+class RtfWriter : public Writer
+{
+protected:
+ ULONG WriteStream() { return 0; }
+};
+
+/// The physical access to the RTF document (for writing).
+class RtfExportFilter : public cppu::WeakImplHelper2
+<
+ com::sun::star::document::XFilter,
+ com::sun::star::document::XExporter
+>
+{
+protected:
+ ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMSF;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xSrcDoc;
+ SvStream* m_pStream;
+public:
+ RtfExportFilter( const ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF );
+ virtual ~RtfExportFilter();
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancel( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XExporter
+ virtual void SAL_CALL setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ RtfWriter m_aWriter;
+};
+
+::rtl::OUString RtfExport_getImplementationName();
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL RtfExport_getSupportedServiceNames()
+ throw();
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL RtfExport_createInstance(
+ const ::com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > &xMSF)
+ throw( ::com::sun::star::uno::Exception );
+
+#define IMPL_NAME_RTFEXPORT "com.sun.star.comp.Writer.RtfExport"
+
+#endif // _RTFEXPORTFILTER_HXX_
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfimportfilter.cxx b/sw/source/filter/ww8/rtfimportfilter.cxx
new file mode 100644
index 0000000000..7261e5734b
--- /dev/null
+++ b/sw/source/filter/ww8/rtfimportfilter.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtfimportfilter.hxx"
+#include "../rtf/swparrtf.hxx"
+
+#include <docsh.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <unotxdoc.hxx>
+#include <swerror.h>
+
+#include <cppuhelper/factory.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+
+using namespace ::comphelper;
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+using rtl::OUStringToOString;
+
+RtfImportFilter::RtfImportFilter( const uno::Reference< lang::XMultiServiceFactory >& xMSF) :
+ m_xMSF( xMSF )
+{
+}
+
+RtfImportFilter::~RtfImportFilter()
+{
+}
+
+sal_Bool RtfImportFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
+ throw (uno::RuntimeException)
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ MediaDescriptor aMediaDesc = aDescriptor;
+ ::uno::Reference< io::XInputStream > xInputStream =
+ aMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_INPUTSTREAM(), uno::Reference< io::XInputStream >() );
+ SvStream* pStream = utl::UcbStreamHelper::CreateStream( xInputStream, sal_True );
+ if (!pStream)
+ return sal_False;
+
+ // get SwDoc*
+ uno::Reference< uno::XInterface > xIfc( m_xDstDoc, uno::UNO_QUERY );
+ SwXTextDocument *pTxtDoc = dynamic_cast< SwXTextDocument * >( xIfc.get() );
+ if (!pTxtDoc)
+ return sal_False;
+ SwDoc *pDoc = pTxtDoc->GetDocShell()->GetDoc();
+ if (!pDoc)
+ return sal_False;
+
+ // get SwPaM*
+ // NEEDSWORK should we care about partial imports? For now we just import
+ // the whole document
+ SwPaM aPam( pDoc->GetNodes().GetEndOfContent() );
+ aPam.SetMark();
+ aPam.Move( fnMoveBackward, fnGoDoc );
+ SwPaM *pCurPam = new SwPaM( *aPam.End(), *aPam.Start() );
+
+ String aURL;
+ OUString sTemp;
+ for ( sal_Int32 i = 0; i < aDescriptor.getLength(); i++ )
+ {
+ if( aDescriptor[i].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("URL")) )
+ {
+ aDescriptor[i].Value >>= sTemp;
+ aURL = sTemp;
+ }
+ }
+
+ RtfReader aReader;
+ return aReader.Read(pStream, *pDoc, aURL, *pCurPam) == 0;
+}
+
+
+void RtfImportFilter::cancel( ) throw (uno::RuntimeException)
+{
+}
+
+void RtfImportFilter::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ m_xDstDoc = xDoc;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// UNO helpers
+//////////////////////////////////////////////////////////////////////////
+
+OUString RtfImport_getImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPL_NAME_RTFIMPORT ) );
+}
+
+uno::Sequence< OUString > SAL_CALL RtfImport_getSupportedServiceNames() throw()
+{
+ const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.ImportFilter" ) );
+ const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+}
+
+uno::Reference< uno::XInterface > SAL_CALL RtfImport_createInstance(const uno::Reference< lang::XMultiServiceFactory > & rSMgr ) throw( uno::Exception )
+{
+ return (cppu::OWeakObject*) new RtfImportFilter( rSMgr );
+}
+
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfimportfilter.hxx b/sw/source/filter/ww8/rtfimportfilter.hxx
new file mode 100644
index 0000000000..6f6d84d1bf
--- /dev/null
+++ b/sw/source/filter/ww8/rtfimportfilter.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _RTFIMPORTFILTER_HXX_
+#define _RTFIMPORTFILTER_HXX_
+
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <tools/stream.hxx>
+#include <shellio.hxx>
+
+/// The physical access to the RTF document (for reading).
+class RtfImportFilter : public cppu::WeakImplHelper2
+<
+ com::sun::star::document::XFilter,
+ com::sun::star::document::XImporter
+>
+{
+protected:
+ ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMSF;
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xDstDoc;
+public:
+ RtfImportFilter( const ::com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF );
+ virtual ~RtfImportFilter();
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL cancel( )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XImporter
+ virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+};
+
+::rtl::OUString RtfImport_getImplementationName();
+::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL RtfImport_getSupportedServiceNames()
+ throw();
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL RtfImport_createInstance(
+ const ::com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory > &xMSF)
+ throw( ::com::sun::star::uno::Exception );
+
+#define IMPL_NAME_RTFIMPORT "com.sun.star.comp.Writer.RtfImport"
+
+#endif // _RTFIMPORTFILTER_HXX_
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx
new file mode 100644
index 0000000000..a2def60f48
--- /dev/null
+++ b/sw/source/filter/ww8/rtfsdrexport.cxx
@@ -0,0 +1,577 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtfsdrexport.hxx"
+#include "rtfexport.hxx"
+#include "writerhelper.hxx"
+
+#include <com/sun/star/i18n/ScriptType.hdl>
+#include <osl/diagnose.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <svl/itemiter.hxx>
+#include <svtools/rtfkeywd.hxx>
+#include <editeng/editdata.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/svdotext.hxx>
+#include <tools/stream.hxx>
+#include <breakit.hxx>
+
+using rtl::OString;
+using rtl::OStringBuffer;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using namespace sw::util;
+
+/// Implementation of an empty stream that silently succeeds, but does nothing.
+///
+/// In fact, this is a hack. The right solution is to abstract EscherEx to be
+/// able to work without SvStream; but at the moment it is better to live with
+/// this I guess.
+class SvNullStream : public SvStream
+{
+protected:
+ virtual sal_Size GetData( void* pData, sal_Size nSize ) { memset( pData, 0, nSize ); return nSize; }
+ virtual sal_Size PutData( const void*, sal_Size nSize ) { return nSize; }
+ virtual sal_Size SeekPos( sal_Size nPos ) { return nPos; }
+ virtual void SetSize( sal_Size ) {}
+ virtual void FlushData() {}
+
+public:
+ SvNullStream() : SvStream() {}
+ virtual ~SvNullStream() {}
+};
+
+RtfSdrExport::RtfSdrExport( RtfExport &rExport )
+ : EscherEx( EscherExGlobalRef( new EscherExGlobal ), *( new SvNullStream )),
+ m_rExport( rExport ),
+ m_rAttrOutput( (RtfAttributeOutput&)m_rExport.AttrOutput() ),
+ m_nShapeType( ESCHER_ShpInst_Nil ),
+ m_pShapeStyle( new OStringBuffer( 200 ) ),
+ m_pShapeTypeWritten( new bool[ ESCHER_ShpInst_COUNT ] )
+{
+ mnGroupLevel = 1;
+ memset( m_pShapeTypeWritten, 0, ESCHER_ShpInst_COUNT * sizeof( bool ) );
+}
+
+RtfSdrExport::~RtfSdrExport()
+{
+ delete mpOutStrm, mpOutStrm = NULL;
+ delete m_pShapeStyle, m_pShapeStyle = NULL;
+ delete[] m_pShapeTypeWritten, m_pShapeTypeWritten = NULL;
+}
+
+void RtfSdrExport::OpenContainer( UINT16 nEscherContainer, int nRecInstance )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ EscherEx::OpenContainer( nEscherContainer, nRecInstance );
+
+ if ( nEscherContainer == ESCHER_SpContainer )
+ {
+ m_nShapeType = ESCHER_ShpInst_Nil;
+ if ( m_pShapeStyle->getLength() )
+ m_pShapeStyle->makeStringAndClear();
+ m_pShapeStyle->ensureCapacity( 200 );
+ m_aShapeProps.clear();
+ }
+}
+
+void RtfSdrExport::CloseContainer()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( mRecTypes.back() == ESCHER_SpContainer )
+ {
+ // write the shape now when we have all the info
+ sal_Int32 nShapeElement = StartShape();
+ EndShape( nShapeElement );
+
+ // cleanup
+ m_nShapeType = ESCHER_ShpInst_Nil;
+ }
+
+ EscherEx::CloseContainer();
+}
+
+UINT32 RtfSdrExport::EnterGroup( const String& /*rShapeName*/, const Rectangle* /*pRect*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ return GenerateShapeId();
+}
+
+void RtfSdrExport::LeaveGroup()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop */
+}
+
+void RtfSdrExport::AddShape( UINT32 nShapeType, UINT32 nShapeFlags, UINT32 /*nShapeId*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ m_nShapeType = nShapeType;
+ m_nShapeFlags = nShapeFlags;
+}
+
+inline sal_uInt16 impl_GetUInt16( const sal_uInt8* &pVal )
+{
+ sal_uInt16 nRet = *pVal++;
+ nRet += ( *pVal++ ) << 8;
+ return nRet;
+}
+
+inline sal_Int32 impl_GetPointComponent( const sal_uInt8* &pVal, sal_uInt16 nPointSize )
+{
+ sal_Int32 nRet = 0;
+ if ( ( nPointSize == 0xfff0 ) || ( nPointSize == 4 ) )
+ {
+ sal_uInt16 nUnsigned = *pVal++;
+ nUnsigned += ( *pVal++ ) << 8;
+
+ nRet = sal_Int16( nUnsigned );
+ }
+ else if ( nPointSize == 8 )
+ {
+ sal_uInt32 nUnsigned = *pVal++;
+ nUnsigned += ( *pVal++ ) << 8;
+ nUnsigned += ( *pVal++ ) << 16;
+ nUnsigned += ( *pVal++ ) << 24;
+
+ nRet = nUnsigned;
+ }
+
+ return nRet;
+}
+
+void RtfSdrExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( m_nShapeType == ESCHER_ShpInst_Nil )
+ return;
+
+ if ( m_nShapeType == ESCHER_ShpInst_Line )
+ AddLineDimensions( rRect );
+ else
+ AddRectangleDimensions( *m_pShapeStyle, rRect );
+
+ // properties
+ const EscherProperties &rOpts = rProps.GetOpts();
+ for ( EscherProperties::const_iterator it = rOpts.begin(); it != rOpts.end(); ++it )
+ {
+ sal_uInt16 nId = ( it->nPropId & 0x0FFF );
+
+ switch ( nId )
+ {
+ case ESCHER_Prop_WrapText:
+ {
+ int nWrapType = 0;
+ switch ( it->nPropValue )
+ {
+ case ESCHER_WrapSquare: nWrapType = 2; break;
+ case ESCHER_WrapByPoints: nWrapType = 4; break;
+ case ESCHER_WrapNone: nWrapType = 3; break;
+ case ESCHER_WrapTopBottom: nWrapType = 1; break;
+ case ESCHER_WrapThrough: nWrapType = 5; break;
+ }
+ if ( nWrapType )
+ m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPWR).append((sal_Int32)nWrapType);
+ }
+ break;
+ case ESCHER_Prop_fillColor:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fillColor"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_fillBackColor:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fillBackColor"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_AnchorText:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("anchorText"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_fNoFillHitTest:
+ if (it->nPropValue)
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fNoFillHitTest"), OString::valueOf(sal_Int32(1))));
+ break;
+ case ESCHER_Prop_fNoLineDrawDash:
+ if (it->nPropValue)
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fNoLineDrawDash"), OString::valueOf(sal_Int32(1))));
+ break;
+ case ESCHER_Prop_lineColor:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("lineColor"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_lineBackColor:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("lineBackColor"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_lineJoinStyle:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("lineJoinStyle"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_fshadowObscured:
+ if (it->nPropValue)
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fshadowObscured"), OString::valueOf(sal_Int32(1))));
+ break;
+ case ESCHER_Prop_geoLeft:
+ case ESCHER_Prop_geoTop:
+ {
+ sal_uInt32 nLeft = 0, nTop = 0;
+
+ if ( nId == ESCHER_Prop_geoLeft )
+ {
+ nLeft = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
+ }
+ else
+ {
+ nTop = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
+ }
+
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("geoLeft"),
+ OString::valueOf(sal_Int32(sal_Int32( nLeft )))));
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("geoTop"),
+ OString::valueOf(sal_Int32(sal_Int32( nTop )))));
+ }
+ break;
+
+ case ESCHER_Prop_geoRight:
+ case ESCHER_Prop_geoBottom:
+ {
+ sal_uInt32 nLeft = 0, nRight = 0, nTop = 0, nBottom = 0;
+ rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
+ rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
+
+ if ( nId == ESCHER_Prop_geoRight )
+ {
+ nRight = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoBottom, nBottom );
+ }
+ else
+ {
+ nBottom = it->nPropValue;
+ rProps.GetOpt( ESCHER_Prop_geoRight, nRight );
+ }
+
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("geoRight"),
+ OString::valueOf(sal_Int32(sal_Int32( nRight ) - sal_Int32( nLeft )))));
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("geoBottom"),
+ OString::valueOf(sal_Int32(sal_Int32( nBottom ) - sal_Int32( nTop )))));
+ }
+ break;
+ case ESCHER_Prop_pVertices:
+ case ESCHER_Prop_pSegmentInfo:
+ {
+ EscherPropSortStruct aVertices;
+ EscherPropSortStruct aSegments;
+
+ if ( rProps.GetOpt( ESCHER_Prop_pVertices, aVertices ) &&
+ rProps.GetOpt( ESCHER_Prop_pSegmentInfo, aSegments ) )
+ {
+ const sal_uInt8 *pVerticesIt = aVertices.pBuf + 6;
+ const sal_uInt8 *pSegmentIt = aSegments.pBuf;
+
+ OStringBuffer aSegmentInfo( 512 );
+ OStringBuffer aVerticies( 512 );
+
+ sal_uInt16 nPointSize = aVertices.pBuf[4] + ( aVertices.pBuf[5] << 8 );
+
+ // number of segments
+ sal_uInt16 nSegments = impl_GetUInt16( pSegmentIt );
+ sal_Int32 nVertices = 0;
+ aSegmentInfo.append("2;").append((sal_Int32)nSegments);
+ pSegmentIt += 4;
+
+ for ( ; nSegments; --nSegments )
+ {
+ sal_uInt16 nSeg = impl_GetUInt16( pSegmentIt );
+ aSegmentInfo.append(';').append((sal_Int32)nSeg);
+ switch ( nSeg )
+ {
+ case 0x0001: // lineto
+ case 0x4000: // moveto
+ {
+ sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
+ aVerticies.append( ";(" ).append( nX ).append( "," ).append( nY ).append( ")" );
+ nVertices ++;
+ }
+ break;
+ case 0x2001: // curveto
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
+ sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
+ aVerticies.append( ";(" ).append( nX ).append( "," ).append( nY ).append( ")" );
+ nVertices ++;
+ }
+ }
+ break;
+ case 0xb300:
+ case 0xac00:
+ case 0xaa00: // nofill
+ case 0xab00: // nostroke
+ case 0x6001: // close
+ case 0x8000: // end
+ break;
+ default:
+ OSL_TRACE("%s: unhandled segment '%x' in the path", OSL_THIS_FUNC, nSeg);
+ break;
+ }
+ }
+
+ if (aVerticies.getLength() )
+ {
+ // We know the number of vertices at the end only, so we have to prepend them here.
+ OStringBuffer aBuf;
+ aBuf.append("8;").append((sal_Int32)nVertices);
+ aBuf.append(aVerticies.makeStringAndClear());
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("pVerticies"), aBuf.makeStringAndClear()));
+ }
+ if ( aSegmentInfo.getLength() )
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("pSegmentInfo"), aSegmentInfo.makeStringAndClear()));
+ }
+ else
+ OSL_TRACE("%s: unhandled shape path, missing either pVertices or pSegmentInfo", OSL_THIS_FUNC);
+ }
+ break;
+ case ESCHER_Prop_shapePath:
+ // noop, we use pSegmentInfo instead
+ break;
+ case ESCHER_Prop_fFillOK:
+ if (!it->nPropValue)
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fFillOK"), OString::valueOf(sal_Int32(0))));
+ break;
+ case ESCHER_Prop_dxTextLeft:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("dxTextLeft"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_dyTextTop:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("dyTextTop"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_dxTextRight:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("dxTextRight"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_dyTextBottom:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("dyTextBottom"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_FitTextToShape:
+ // Size text to fit shape size: not supported by RTF
+ break;
+ case ESCHER_Prop_adjustValue:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("adjustValue"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ case ESCHER_Prop_txflTextFlow:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("txflTextFlow"), OString::valueOf(sal_Int32(it->nPropValue))));
+ break;
+ default:
+ OSL_TRACE("%s: unhandled property: %d (value: %d)", OSL_THIS_FUNC, nId, it->nPropValue);
+ break;
+ }
+ }
+}
+
+void RtfSdrExport::AddLineDimensions( const Rectangle& rRectangle )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // We get the position relative to (the current?) character
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("posrelh"), OString::valueOf(sal_Int32(3))));
+
+ switch ( m_nShapeFlags & 0xC0 )
+ {
+ case 0x40:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fFlipV"), OString::valueOf(sal_Int32(1))));
+ break;
+ case 0x80:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fFlipH"), OString::valueOf(sal_Int32(1))));
+ break;
+ case 0xC0:
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fFlipV"), OString::valueOf(sal_Int32(1))));
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("fFlipH"), OString::valueOf(sal_Int32(1))));
+ break;
+ }
+
+ // the actual dimensions
+ m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPLEFT).append(rRectangle.Left());
+ m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPTOP).append(rRectangle.Top());
+ m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPRIGHT).append(rRectangle.Right());
+ m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM).append(rRectangle.Bottom());
+}
+
+void RtfSdrExport::AddRectangleDimensions( rtl::OStringBuffer& rBuffer, const Rectangle& rRectangle )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ // We get the position relative to (the current?) character
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("posrelh"), OString::valueOf(sal_Int32(3))));
+
+ rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPLEFT).append(rRectangle.Left());
+ rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPTOP).append(rRectangle.Top());
+ rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPRIGHT).append(rRectangle.Right());
+ rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM).append(rRectangle.Bottom());
+}
+
+void RtfSdrExport::AddShapeAttribute( sal_Int32 /*nAttribute*/, const rtl::OString& /*rValue*/ )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ /* noop */
+}
+
+extern const char* pShapeTypes[];
+
+sal_Int32 RtfSdrExport::StartShape()
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( m_nShapeType == ESCHER_ShpInst_Nil )
+ return -1;
+
+ m_aShapeProps.insert(std::pair<OString,OString>(OString("shapeType"), OString::valueOf(sal_Int32(m_nShapeType))));
+
+ m_rAttrOutput.RunText().append('{').append(OOO_STRING_SVTOOLS_RTF_SHP);
+ m_rAttrOutput.RunText().append('{').append(OOO_STRING_SVTOOLS_RTF_IGNORE).append(OOO_STRING_SVTOOLS_RTF_SHPINST);
+
+ m_rAttrOutput.RunText().append(m_pShapeStyle->makeStringAndClear());
+ // Ignore \shpbxpage, \shpbxmargin, and \shpbxcolumn, in favor of the posrelh property.
+ m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE);
+ // Ignore \shpbypage, \shpbymargin, and \shpbycolumn, in favor of the posrelh property.
+ m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE);
+
+ for(std::map<OString,OString>::reverse_iterator i = m_aShapeProps.rbegin(); i != m_aShapeProps.rend(); i++)
+ m_rAttrOutput.RunText().append('{').append(OOO_STRING_SVTOOLS_RTF_SP)
+ .append('{').append(OOO_STRING_SVTOOLS_RTF_SN " ").append((*i).first).append('}')
+ .append('{').append(OOO_STRING_SVTOOLS_RTF_SV " ").append((*i).second).append('}')
+ .append('}');
+
+ // now check if we have some text
+ const SdrTextObj* pTxtObj = PTR_CAST(SdrTextObj, m_pSdrObject);
+ if (pTxtObj)
+ {
+ const OutlinerParaObject* pParaObj = 0;
+ bool bOwnParaObj = false;
+
+ /*
+ #i13885#
+ When the object is actively being edited, that text is not set into
+ the objects normal text object, but lives in a seperate object.
+ */
+ if (pTxtObj->IsTextEditActive())
+ {
+ pParaObj = pTxtObj->GetEditOutlinerParaObject();
+ bOwnParaObj = true;
+ }
+ else
+ {
+ pParaObj = pTxtObj->GetOutlinerParaObject();
+ }
+
+ if( pParaObj )
+ {
+ // this is reached only in case some text is attached to the shape
+ WriteOutliner(*pParaObj);
+ if( bOwnParaObj )
+ delete pParaObj;
+ }
+ }
+
+ return m_nShapeType;
+}
+
+void RtfSdrExport::WriteOutliner(const OutlinerParaObject& rParaObj)
+{
+ OSL_TRACE("%s start", OSL_THIS_FUNC);
+
+ const EditTextObject& rEditObj = rParaObj.GetTextObject();
+ MSWord_SdrAttrIter aAttrIter( m_rExport, rEditObj, TXT_HFTXTBOX );
+
+ USHORT nPara = rEditObj.GetParagraphCount();
+
+ m_rAttrOutput.RunText().append('{').append(OOO_STRING_SVTOOLS_RTF_SHPTXT).append(' ');
+ for (USHORT n = 0; n < nPara; ++n)
+ {
+ if( n )
+ aAttrIter.NextPara( n );
+
+ rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
+
+ String aStr( rEditObj.GetText( n ));
+ xub_StrLen nAktPos = 0;
+ xub_StrLen nEnd = aStr.Len();
+
+ aAttrIter.OutParaAttr(false);
+ m_rAttrOutput.RunText().append(m_rAttrOutput.Styles().makeStringAndClear());
+
+ do {
+ xub_StrLen nNextAttr = aAttrIter.WhereNext();
+ rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
+
+ if( nNextAttr > nEnd )
+ nNextAttr = nEnd;
+
+ aAttrIter.OutAttr( nAktPos );
+ m_rAttrOutput.RunText().append('{').append(m_rAttrOutput.Styles().makeStringAndClear()).append(m_rExport.sNewLine);
+ bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
+ if( !bTxtAtr )
+ {
+ String aOut( aStr.Copy( nAktPos, nNextAttr - nAktPos ) );
+ m_rAttrOutput.RunText().append( m_rExport.OutString( aOut, eChrSet ) );
+ }
+
+ m_rAttrOutput.RunText().append('}');
+
+ nAktPos = nNextAttr;
+ eChrSet = eNextChrSet;
+ aAttrIter.NextPos();
+ }
+ while( nAktPos < nEnd );
+ }
+ m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_PAR).append('}');
+
+ OSL_TRACE("%s end", OSL_THIS_FUNC);
+}
+
+void RtfSdrExport::EndShape( sal_Int32 nShapeElement )
+{
+ OSL_TRACE("%s", OSL_THIS_FUNC);
+
+ if ( nShapeElement >= 0 )
+ {
+ // end of the shape
+ m_rAttrOutput.RunText().append('}').append('}');
+ }
+}
+
+UINT32 RtfSdrExport::AddSdrObject( const SdrObject& rObj )
+{
+ m_pSdrObject = &rObj;
+ return EscherEx::AddSdrObject(rObj);
+}
+
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/rtfsdrexport.hxx b/sw/source/filter/ww8/rtfsdrexport.hxx
new file mode 100644
index 0000000000..46d5e58baf
--- /dev/null
+++ b/sw/source/filter/ww8/rtfsdrexport.hxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _RTFSdrEXPORT_HXX_
+#define _RTFSdrEXPORT_HXX_
+
+#include <filter/msfilter/escherex.hxx>
+#include <editeng/outlobj.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <map>
+
+class RtfExport;
+class RtfAttributeOutput;
+
+class RtfSdrExport : public EscherEx
+{
+ RtfExport &m_rExport;
+
+ RtfAttributeOutput &m_rAttrOutput;
+
+ const SdrObject* m_pSdrObject;
+
+ /// Remember the shape type.
+ sal_uInt32 m_nShapeType;
+
+ /// Remember the shape flags.
+ sal_uInt32 m_nShapeFlags;
+
+ /// Remember style, the most important shape attribute ;-)
+ rtl::OStringBuffer *m_pShapeStyle;
+
+ std::map<rtl::OString,rtl::OString> m_aShapeProps;
+
+ /// Remember which shape types we had already written.
+ bool *m_pShapeTypeWritten;
+
+public:
+ RtfSdrExport( RtfExport &rExport );
+ virtual ~RtfSdrExport();
+
+ /// Export the sdr object as Sdr.
+ ///
+ /// Call this when you need to export the object as Sdr in RTF.
+ UINT32 AddSdrObject( const SdrObject& rObj );
+
+protected:
+ /// Add an attribute to the generated shape element.
+ ///
+ /// This should be called from within StartShape() to ensure that the
+ /// added attribute is preserved.
+ void AddShapeAttribute( sal_Int32 nAttribute, const rtl::OString& sValue );
+
+ /// Start the shape for which we just collected the information.
+ ///
+ /// Returns the element's tag number, -1 means we wrote nothing.
+ virtual sal_Int32 StartShape();
+
+ /// End the shape.
+ ///
+ /// The parameter is just what we got from StartShape().
+ virtual void EndShape( sal_Int32 nShapeElement );
+
+ virtual void Commit( EscherPropertyContainer& rProps, const Rectangle& rRect );
+
+private:
+
+ virtual void OpenContainer( UINT16 nEscherContainer, int nRecInstance = 0 );
+ virtual void CloseContainer();
+
+ virtual UINT32 EnterGroup( const String& rShapeName, const Rectangle* pBoundRect = 0 );
+ virtual void LeaveGroup();
+
+ virtual void AddShape( UINT32 nShapeType, UINT32 nShapeFlags, UINT32 nShapeId = 0 );
+
+private:
+ /// Add starting and ending point of a line to the m_pShapeAttrList.
+ void AddLineDimensions( const Rectangle& rRectangle );
+
+ /// Add position and size to the OStringBuffer.
+ void AddRectangleDimensions( rtl::OStringBuffer& rBuffer, const Rectangle& rRectangle );
+
+ void WriteOutliner(const OutlinerParaObject& rParaObj);
+};
+
+#endif // _RTFSdrEXPORT_HXX_
+/* vi:set shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx
index 72dbabefd9..71889e25bf 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -811,49 +811,7 @@ void WW8Export::AppendFlyInFlys(const sw::Frame& rFrmFmt,
OutputField(0, ww::eSHAPE, aEmptyStr, WRITEFIELD_CLOSE);
}
-class WW8_SdrAttrIter : public MSWordAttrIter
-{
-private:
- const EditTextObject* pEditObj;
- const SfxItemPool* pEditPool;
- EECharAttribArray aTxtAtrArr;
- SvPtrarr aChrTxtAtrArr;
- SvUShorts aChrSetArr;
- USHORT nPara;
- xub_StrLen nAktSwPos;
- xub_StrLen nTmpSwPos; // fuer HasItem()
- rtl_TextEncoding eNdChrSet;
- USHORT nScript;
- BYTE mnTyp;
-
- xub_StrLen SearchNext( xub_StrLen nStartPos );
- void SetCharSet(const EECharAttrib& rTxtAttr, bool bStart);
-
- //No copying
- WW8_SdrAttrIter(const WW8_SdrAttrIter&);
- WW8_SdrAttrIter& operator=(const WW8_SdrAttrIter&);
-public:
- WW8_SdrAttrIter( WW8Export& rWr, const EditTextObject& rEditObj,
- BYTE nType );
- void NextPara( USHORT nPar );
- void OutParaAttr(bool bCharAttr);
- void OutEEField(const SfxPoolItem& rHt);
-
- bool IsTxtAttr(xub_StrLen nSwPos);
-
- void NextPos() { nAktSwPos = SearchNext( nAktSwPos + 1 ); }
-
- void OutAttr( xub_StrLen nSwPos );
- virtual const SfxPoolItem* HasTextItem( USHORT nWhich ) const;
- virtual const SfxPoolItem& GetItem( USHORT nWhich ) const;
- bool OutAttrWithRange(xub_StrLen nPos);
- xub_StrLen WhereNext() const { return nAktSwPos; }
- rtl_TextEncoding GetNextCharSet() const;
- rtl_TextEncoding GetNodeCharSet() const { return eNdChrSet; }
-};
-
-
-WW8_SdrAttrIter::WW8_SdrAttrIter( WW8Export& rWr,
+MSWord_SdrAttrIter::MSWord_SdrAttrIter( MSWordExportBase& rWr,
const EditTextObject& rEditObj, BYTE nTyp )
: MSWordAttrIter( rWr ), pEditObj(&rEditObj), pEditPool(0),
aTxtAtrArr( 0, 4 ), aChrTxtAtrArr( 0, 4 ), aChrSetArr( 0, 4 ),
@@ -862,7 +820,7 @@ WW8_SdrAttrIter::WW8_SdrAttrIter( WW8Export& rWr,
NextPara( 0 );
}
-void WW8_SdrAttrIter::NextPara( USHORT nPar )
+void MSWord_SdrAttrIter::NextPara( USHORT nPar )
{
nPara = nPar;
// Attributwechsel an Pos 0 wird ignoriert, da davon ausgegangen
@@ -885,7 +843,7 @@ void WW8_SdrAttrIter::NextPara( USHORT nPar )
nAktSwPos = SearchNext( 1 );
}
-rtl_TextEncoding WW8_SdrAttrIter::GetNextCharSet() const
+rtl_TextEncoding MSWord_SdrAttrIter::GetNextCharSet() const
{
if( aChrSetArr.Count() )
return (rtl_TextEncoding)aChrSetArr[ aChrSetArr.Count() - 1 ];
@@ -893,7 +851,7 @@ rtl_TextEncoding WW8_SdrAttrIter::GetNextCharSet() const
}
// der erste Parameter in SearchNext() liefert zurueck, ob es ein TxtAtr ist.
-xub_StrLen WW8_SdrAttrIter::SearchNext( xub_StrLen nStartPos )
+xub_StrLen MSWord_SdrAttrIter::SearchNext( xub_StrLen nStartPos )
{
xub_StrLen nPos;
xub_StrLen nMinPos = STRING_MAXLEN;
@@ -932,7 +890,7 @@ xub_StrLen WW8_SdrAttrIter::SearchNext( xub_StrLen nStartPos )
return nMinPos;
}
-void WW8_SdrAttrIter::SetCharSet(const EECharAttrib& rAttr, bool bStart)
+void MSWord_SdrAttrIter::SetCharSet(const EECharAttrib& rAttr, bool bStart)
{
void* p = 0;
rtl_TextEncoding eChrSet;
@@ -962,7 +920,7 @@ void WW8_SdrAttrIter::SetCharSet(const EECharAttrib& rAttr, bool bStart)
}
}
-void WW8_SdrAttrIter::OutEEField(const SfxPoolItem& rHt)
+void MSWord_SdrAttrIter::OutEEField(const SfxPoolItem& rHt)
{
const SvxFieldItem &rField = (const SvxFieldItem &)rHt;
const SvxFieldData *pFld = rField.GetField();
@@ -981,7 +939,7 @@ void WW8_SdrAttrIter::OutEEField(const SfxPoolItem& rHt)
}
}
-void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos )
+void MSWord_SdrAttrIter::OutAttr( xub_StrLen nSwPos )
{
OutParaAttr(true);
@@ -1038,7 +996,7 @@ void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos )
}
}
-bool WW8_SdrAttrIter::IsTxtAttr(xub_StrLen nSwPos)
+bool MSWord_SdrAttrIter::IsTxtAttr(xub_StrLen nSwPos)
{
for (USHORT i = 0; i < aTxtAtrArr.Count(); ++i)
{
@@ -1063,7 +1021,7 @@ bool WW8_SdrAttrIter::IsTxtAttr(xub_StrLen nSwPos)
// Attribut-Anfangposition fragen kann.
// Es koennen nur Attribute mit Ende abgefragt werden.
// Es wird mit bDeep gesucht
-const SfxPoolItem* WW8_SdrAttrIter::HasTextItem(USHORT nWhich) const
+const SfxPoolItem* MSWord_SdrAttrIter::HasTextItem(USHORT nWhich) const
{
const SfxPoolItem* pRet = 0;
nWhich = sw::hack::TransformWhichBetweenPools(*pEditPool,
@@ -1088,7 +1046,7 @@ const SfxPoolItem* WW8_SdrAttrIter::HasTextItem(USHORT nWhich) const
return pRet;
}
-const SfxPoolItem& WW8_SdrAttrIter::GetItem( USHORT nWhich ) const
+const SfxPoolItem& MSWord_SdrAttrIter::GetItem( USHORT nWhich ) const
{
using sw::hack::GetSetWhichFromSwDocWhich;
const SfxPoolItem* pRet = HasTextItem(nWhich);
@@ -1102,7 +1060,7 @@ const SfxPoolItem& WW8_SdrAttrIter::GetItem( USHORT nWhich ) const
return *pRet;
}
-void WW8_SdrAttrIter::OutParaAttr(bool bCharAttr)
+void MSWord_SdrAttrIter::OutParaAttr(bool bCharAttr)
{
SfxItemSet aSet( pEditObj->GetParaAttribs( nPara ));
if( aSet.Count() )
@@ -1175,7 +1133,7 @@ void WW8Export::WriteOutliner(const OutlinerParaObject& rParaObj, BYTE nTyp)
{
bool bAnyWrite = false;
const EditTextObject& rEditObj = rParaObj.GetTextObject();
- WW8_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
+ MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
USHORT nPara = rEditObj.GetParagraphCount();
BYTE bNul = 0;
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 81a2bacbd8..5d8f5e27c8 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1,7 +1,7 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ *
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
@@ -337,7 +337,7 @@ xub_StrLen SwAttrIter::SearchNext( xub_StrLen nStartPos )
xub_StrLen pos = lcl_getMinPos( fieldEndPos, fieldStartPos );
pos = lcl_getMinPos( pos, formElementPos );
- if (pos!=STRING_NOTFOUND)
+ if (pos!=STRING_NOTFOUND)
nMinPos=pos;
// first the redline, then the attributes
@@ -894,7 +894,7 @@ bool WW8AttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget,
if ( sMark.Len() )
( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"';
-
+
if ( rTarget.Len() )
( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget;
@@ -1344,10 +1344,10 @@ short MSWordExportBase::GetDefaultFrameDirection( ) const
else if ( pOutFmtNode->ISA( SwTxtFmtColl ) )
nDir = FRMDIR_HORI_LEFT_TOP; //what else can we do :-(
}
-
+
if ( nDir == FRMDIR_ENVIRONMENT )
nDir = FRMDIR_HORI_LEFT_TOP; //Set something
-
+
return nDir;
}
@@ -1597,12 +1597,12 @@ void WW8AttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop &rS
m_rWW8Export.WriteCR( pTextNodeInfoInner );
if ( pTextNodeInfo.get() != NULL )
- {
-#ifdef DEBUG
+ {
+#ifdef DEBUG
::std::clog << pTextNodeInfo->toString() << ::std::endl;
#endif
- TableInfoCell( pTextNodeInfoInner );
+ TableInfoCell( pTextNodeInfoInner );
}
m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
@@ -1646,14 +1646,127 @@ void WW8AttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop &rS
m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() );
}
-xub_StrLen MSWordExportBase::GetNextPos( SwAttrIter* aAttrIter, const SwTxtNode& /*rNode*/, xub_StrLen /*nAktPos*/ )
+xub_StrLen MSWordExportBase::GetNextPos( SwAttrIter* aAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos )
+{
+ // Get the bookmarks for the normal run
+ xub_StrLen nNextPos = aAttrIter->WhereNext();
+
+ GetSortedBookmarks( rNode, nAktPos, nNextPos - nAktPos );
+
+ xub_StrLen nNextBookmark = nNextPos;
+ NearestBookmark( nNextPos );
+
+ return std::min( nNextPos, nNextBookmark );
+}
+
+void MSWordExportBase::UpdatePosition( SwAttrIter* aAttrIter, xub_StrLen nAktPos, xub_StrLen /*nEnd*/ )
+{
+ xub_StrLen nNextPos;
+
+ // either no bookmark, or it is not at the current position
+ if ( !NearestBookmark( nNextPos ) || nNextPos > nAktPos )
+ aAttrIter->NextPos();
+}
+
+bool MSWordExportBase::GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt,
+ xub_StrLen nEnd, IMarkVector& rArr )
+{
+ IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
+ ULONG nNd = rNd.GetIndex( );
+
+ const sal_Int32 nMarks = pMarkAccess->getMarksCount();
+ for ( sal_Int32 i = 0; i < nMarks; i++ )
+ {
+ IMark* pMark = ( pMarkAccess->getMarksBegin() + i )->get();
+
+ // Only keep the bookmarks starting or ending in this node
+ if ( pMark->GetMarkStart().nNode == nNd ||
+ pMark->GetMarkEnd().nNode == nNd )
+ {
+ xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex();
+ xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+ // Keep only the bookmars starting or ending in the snippet
+ bool bIsStartOk = ( nBStart >= nStt ) && ( nBStart <= nEnd );
+ bool bIsEndOk = ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
+
+ if ( bIsStartOk || bIsEndOk )
+ rArr.push_back( pMark );
+ }
+ }
+ return ( rArr.size() > 0 );
+}
+
+class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool >
+{
+public:
+ inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
+ {
+ xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
+ xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
+
+ return nOEnd < nTEnd;
+ }
+};
+
+bool MSWordExportBase::NearestBookmark( xub_StrLen& rNearest )
{
- return aAttrIter->WhereNext();
+ bool bHasBookmark = false;
+
+ if ( m_rSortedMarksStart.size( ) > 0 )
+ {
+ IMark* pMarkStart = m_rSortedMarksStart.front();
+ rNearest = pMarkStart->GetMarkStart().nContent.GetIndex();
+ bHasBookmark = true;
+ }
+
+ if ( m_rSortedMarksEnd.size( ) > 0 )
+ {
+ IMark* pMarkEnd = m_rSortedMarksEnd[0];
+ if ( !bHasBookmark )
+ rNearest = pMarkEnd->GetMarkEnd().nContent.GetIndex();
+ else
+ rNearest = std::min( rNearest, pMarkEnd->GetMarkEnd().nContent.GetIndex() );
+ bHasBookmark = true;
+ }
+
+ return bHasBookmark;
}
-void MSWordExportBase::UpdatePosition( SwAttrIter* aAttrIter, xub_StrLen /*nAktPos*/, xub_StrLen /*nEnd*/ )
+void MSWordExportBase::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
{
- aAttrIter->NextPos();
+ IMarkVector aMarksStart;
+ if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) )
+ {
+ IMarkVector aSortedEnd;
+ IMarkVector aSortedStart;
+ for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end();
+ it < end; ++it )
+ {
+ IMark* pMark = (*it);
+
+ // Remove the positions egals to the current pos
+ xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
+ xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
+
+ if ( nStart > nAktPos )
+ aSortedStart.push_back( pMark );
+
+ if ( nEnd > nAktPos )
+ aSortedEnd.push_back( pMark );
+ }
+
+ // Sort the bookmarks by end position
+ std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
+
+ m_rSortedMarksStart.swap( aSortedStart );
+ m_rSortedMarksEnd.swap( aSortedEnd );
+ }
+ else
+ {
+ m_rSortedMarksStart.clear( );
+ m_rSortedMarksEnd.clear( );
+ }
}
void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
@@ -1834,7 +1947,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
}
}
}
-
+
// Output the character attributes
AttrOutput().StartRunProperties();
aAttrIter.OutAttr( nAktPos ); // nAktPos - 1 ??
@@ -1887,7 +2000,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
while ( nAktPos < nEnd );
AttrOutput().StartParagraphProperties( rNode );
-
+
AttrOutput().ParagraphStyle( nStyle );
if ( mpParentFrame && !bIsInTable ) // Fly-Attrs
@@ -1903,7 +2016,7 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
if (pTextNodeInfoInner->isFirstInTable())
{
const SwTable * pTable = pTextNodeInfoInner->getTable();
- const SwTableFmt * pTabFmt =
+ const SwTableFmt * pTabFmt =
dynamic_cast<const SwTableFmt *>(pTable->GetRegisteredIn());
if (pTabFmt != NULL)
{
@@ -1911,8 +2024,8 @@ void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
AttrOutput().PageBreakBefore(true);
}
}
- }
-
+ }
+
if ( !bFlyInTable )
{
SfxItemSet* pTmpSet = 0;
diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index 2ed01f48a8..da139872e5 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -721,6 +721,9 @@ void MSWordExportBase::SubstituteBullet( String& rNumStr,
StarSymbolToMSMultiFont *pConvert = 0;
FontFamily eFamily = FAMILY_DECORATIVE;
+ if (!bSubstituteBullets)
+ return;
+
if (!pConvert)
{
pConvert = CreateStarSymbolToMSMultiFont();
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index 42b829a999..2a6a204118 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -79,6 +79,7 @@
#include "ww8par.hxx"
#include "ww8attributeoutput.hxx"
#include "docxattributeoutput.hxx"
+#include "rtfattributeoutput.hxx"
using namespace sw::util;
using namespace nsHdFtFlags;
@@ -711,6 +712,17 @@ void wwFont::WriteDocx( const DocxAttributeOutput* rAttrOutput ) const
rAttrOutput->EndFont();
}
+void wwFont::WriteRtf( const RtfAttributeOutput* rAttrOutput ) const
+{
+ rAttrOutput->FontFamilyType( meFamily, *this );
+ rAttrOutput->FontPitchType( mePitch );
+ rAttrOutput->FontCharset( sw::ms::rtl_TextEncodingToWinCharset( meChrSet ) );
+ rAttrOutput->StartFont( msFamilyNm );
+ if ( mbAlt )
+ rAttrOutput->FontAlternateName( msAltNm );
+ rAttrOutput->EndFont();
+}
+
bool operator<(const wwFont &r1, const wwFont &r2)
{
int nRet = memcmp(r1.maWW8_FFN, r2.maWW8_FFN, sizeof(r1.maWW8_FFN));
@@ -763,6 +775,22 @@ void wwFontHelper::InitFontTable(bool bWrtWW8,const SwDoc& rDoc)
GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
}
+
+ if (!bLoadAllFonts)
+ return;
+
+ const USHORT aTypes[] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT, 0 };
+ for (const USHORT* pId = aTypes; *pId; ++pId)
+ {
+ USHORT nMaxItem = rPool.GetItemCount( *pId );
+ for( USHORT nGet = 0; nGet < nMaxItem; ++nGet )
+ if( 0 != (pFont = (const SvxFontItem*)rPool.GetItem(
+ *pId, nGet )) )
+ {
+ GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
+ pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
+ }
+ }
}
USHORT wwFontHelper::GetId(const Font& rFont)
@@ -835,6 +863,14 @@ void wwFontHelper::WriteFontTable( const DocxAttributeOutput& rAttrOutput )
::std::bind2nd( ::std::mem_fun( &wwFont::WriteDocx ), &rAttrOutput ) );
}
+void wwFontHelper::WriteFontTable( const RtfAttributeOutput& rAttrOutput )
+{
+ ::std::vector<const wwFont *> aFontList( AsVector() );
+
+ ::std::for_each( aFontList.begin(), aFontList.end(),
+ ::std::bind2nd( ::std::mem_fun( &wwFont::WriteRtf ), &rAttrOutput ) );
+}
+
/* */
WW8_WrPlc0::WW8_WrPlc0( ULONG nOffset )
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 2cf3a421e2..43016e4641 100755
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -3371,7 +3371,7 @@ MSWordExportBase::MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM
mpTableInfo(new ww8::WW8TableInfo()), nUniqueList(0),
mnHdFtIndex(0), pAktPageDesc(0), pPapPlc(0), pChpPlc(0), pChpIter(0),
pStyles( NULL ),
- bHasHdr(false), bHasFtr(false),
+ bHasHdr(false), bHasFtr(false), bSubstituteBullets(true),
pDoc( pDocument ),
pCurPam( pCurrentPam ),
pOrigPam( pOriginalPam )
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index d73ebae2f2..3a005a91b5 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -1,7 +1,7 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ *
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
@@ -35,6 +35,7 @@
#define _SVSTDARR_ULONGS
#include <svl/svstdarr.hxx>
#endif
+#include <editeng/editdata.hxx>
#include <map>
#include <vector>
@@ -55,6 +56,7 @@
class SwAttrIter;
class AttributeOutputBase;
class DocxAttributeOutput;
+class RtfAttributeOutput;
class BitmapPalette;
class SwEscherEx;
class DateTime;
@@ -254,7 +256,7 @@ private:
void WriteFtnEndTxt( WW8Export& rWrt, ULONG nCpStt );
public:
void OutHeaderFooter(WW8Export& rWrt, bool bHeader,
- const SwFmt& rFmt, ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag, BYTE nBreakCode);
+ const SwFmt& rFmt, ULONG& rCpPos, BYTE nHFFlags, BYTE nFlag, BYTE nBreakCode);
};
//--------------------------------------------------------------------------
@@ -294,6 +296,7 @@ public:
rtl_TextEncoding eChrSet, bool bWrtWW8 );
bool Write( SvStream *pTableStram ) const;
void WriteDocx( const DocxAttributeOutput* rAttrOutput ) const;
+ void WriteRtf( const RtfAttributeOutput* rAttrOutput ) const;
rtl::OUString GetFamilyName() const { return rtl::OUString( msFamilyNm ); }
friend bool operator < (const wwFont &r1, const wwFont &r2);
};
@@ -309,7 +312,7 @@ private:
::std::vector< const wwFont* > AsVector() const;
public:
- wwFontHelper() : mbWrtWW8(false) {}
+ wwFontHelper() : mbWrtWW8(false), bLoadAllFonts(false) {}
/// rDoc used only to get the initial standard font(s) in use.
void InitFontTable(bool bWrtWW8, const SwDoc& rDoc);
USHORT GetId(const Font& rFont);
@@ -317,6 +320,10 @@ public:
USHORT GetId(const wwFont& rFont);
void WriteFontTable( SvStream *pTableStream, WW8Fib& pFib );
void WriteFontTable( const DocxAttributeOutput& rAttrOutput );
+ void WriteFontTable( const RtfAttributeOutput& rAttrOutput );
+
+ /// If true, all fonts are loaded before processing the document.
+ BYTE bLoadAllFonts: 1;
};
class DrawObj
@@ -535,6 +542,7 @@ public:
BYTE bEndAtTxtEnd : 1; // true: all END at Textend
BYTE bHasHdr : 1;
BYTE bHasFtr : 1;
+ BYTE bSubstituteBullets : 1; // true: SubstituteBullet() gets called
SwDoc *pDoc;
SwPaM *pCurPam, *pOrigPam;
@@ -542,6 +550,11 @@ public:
/// Stack to remember the nesting (see MSWordSaveData for more)
::std::stack< MSWordSaveData > maSaveData;
+ /// Used to split the runs according to the bookmarks start and ends
+ typedef std::vector< ::sw::mark::IMark* > IMarkVector;
+ IMarkVector m_rSortedMarksStart;
+ IMarkVector m_rSortedMarksEnd;
+
public:
/// The main function to export the document.
void ExportDocument( bool bWriteAll );
@@ -565,9 +578,9 @@ public:
/// Return the numeric id of the style.
USHORT GetId( const SwCharFmt& rFmt ) const;
-
+
USHORT GetId( const SwTOXType& rTOXType );
-
+
const SfxPoolItem& GetItem( USHORT nWhich ) const;
/// Find the reference.
@@ -648,7 +661,7 @@ public:
/// The return value indicates, if a follow page desc is written.
bool OutputFollowPageDesc( const SfxItemSet* pSet,
const SwTxtNode* pNd );
-
+
/// Write header/footer text.
void WriteHeaderFooterText( const SwFmt& rFmt, bool bHeader);
@@ -671,7 +684,7 @@ public:
/// Write static data of SwNumRule - LSTF
void NumberingDefinitions();
-
+
/// Write all Levels for all SwNumRules - LVLF
void AbstractNumberingDefinitions();
@@ -703,7 +716,7 @@ public:
/// Write the data of the form field
virtual void WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) = 0;
virtual void WriteHyperlinkData( const ::sw::mark::IFieldmark& rFieldmark ) = 0;
-
+
virtual void DoComboBox(const rtl::OUString &rName,
const rtl::OUString &rHelp,
const rtl::OUString &ToolTip,
@@ -749,7 +762,7 @@ protected:
bool FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const;
virtual void SectionBreaksAndFrames( const SwTxtNode& rNode ) = 0;
-
+
virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
const SwNode& rNd,
const SwFmtPageDesc* pNewPgDescFmt = 0,
@@ -780,7 +793,18 @@ protected:
///
/// One of OutputTextNode(), OutputGrfNode(), or OutputOLENode()
void OutputContentNode( const SwCntntNode& );
-
+
+ /// Find the nearest bookmark from the current position.
+ ///
+ /// Returns false when there is no bookmark.
+ bool NearestBookmark( xub_StrLen& rNearest );
+
+ void GetSortedBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos,
+ xub_StrLen nLen );
+
+ bool GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt, xub_StrLen nEnd,
+ IMarkVector& rArr );
+
public:
MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam );
virtual ~MSWordExportBase();
@@ -984,7 +1008,7 @@ public:
void WriteAsStringTable(const ::std::vector<String>&, INT32& rfcSttbf,
INT32& rlcbSttbf, USHORT nExtraLen = 0);
-
+
virtual ULONG ReplaceCr( BYTE nChar );
virtual void WriteCR( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner = ww8::WW8TableNodeInfoInner::Pointer_t() );
@@ -1098,7 +1122,7 @@ protected:
/// Output SwOLENode
virtual void OutputOLENode( const SwOLENode& );
-
+
virtual void AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, ULONG nLnNum );
private:
@@ -1346,6 +1370,47 @@ public:
virtual const SfxPoolItem& GetItem( USHORT nWhich ) const = 0;
};
+class MSWord_SdrAttrIter : public MSWordAttrIter
+{
+private:
+ const EditTextObject* pEditObj;
+ const SfxItemPool* pEditPool;
+ EECharAttribArray aTxtAtrArr;
+ SvPtrarr aChrTxtAtrArr;
+ SvUShorts aChrSetArr;
+ USHORT nPara;
+ xub_StrLen nAktSwPos;
+ xub_StrLen nTmpSwPos; // for HasItem()
+ rtl_TextEncoding eNdChrSet;
+ USHORT nScript;
+ BYTE mnTyp;
+
+ xub_StrLen SearchNext( xub_StrLen nStartPos );
+ void SetCharSet(const EECharAttrib& rTxtAttr, bool bStart);
+
+ //No copying
+ MSWord_SdrAttrIter(const MSWord_SdrAttrIter&);
+ MSWord_SdrAttrIter& operator=(const MSWord_SdrAttrIter&);
+public:
+ MSWord_SdrAttrIter( MSWordExportBase& rWr, const EditTextObject& rEditObj,
+ BYTE nType );
+ void NextPara( USHORT nPar );
+ void OutParaAttr(bool bCharAttr);
+ void OutEEField(const SfxPoolItem& rHt);
+
+ bool IsTxtAttr(xub_StrLen nSwPos);
+
+ void NextPos() { nAktSwPos = SearchNext( nAktSwPos + 1 ); }
+
+ void OutAttr( xub_StrLen nSwPos );
+ virtual const SfxPoolItem* HasTextItem( USHORT nWhich ) const;
+ virtual const SfxPoolItem& GetItem( USHORT nWhich ) const;
+ bool OutAttrWithRange(xub_StrLen nPos);
+ xub_StrLen WhereNext() const { return nAktSwPos; }
+ rtl_TextEncoding GetNextCharSet() const;
+ rtl_TextEncoding GetNodeCharSet() const { return eNdChrSet; }
+};
+
/// Class to collect and output the styles table.
class MSWordStyles
{
@@ -1399,11 +1464,11 @@ class WW8SHDLong
sal_uInt32 m_cvFore;
sal_uInt32 m_cvBack;
sal_uInt16 m_ipat;
-
+
public:
WW8SHDLong() : m_cvFore(0), m_cvBack(0), m_ipat(0) {}
virtual ~WW8SHDLong() {}
-
+
void Write(WW8Export & rExport);
void setCvFore(sal_uInt32 cvFore) { m_cvFore = cvFore; }
void setCvBack(sal_uInt32 cvBack) { m_cvBack = cvBack; }
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 1e5d01101f..cde7c02ce4 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -3340,7 +3340,7 @@ void WW8AttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
m_rWW8Export.pO->Insert( (BYTE)0x02, m_rWW8Export.pO->Count() );
sal_Unicode cStart = rTwoLines.GetStartBracket();
- sal_Unicode cEnd = rTwoLines.GetStartBracket();
+ sal_Unicode cEnd = rTwoLines.GetEndBracket();
/*
As per usual we have problems. We can have seperate left and right brackets
diff --git a/sw/util/msword.map b/sw/util/msword.map
index 16b9d25b0b..d2a9d9b4f7 100755
--- a/sw/util/msword.map
+++ b/sw/util/msword.map
@@ -6,6 +6,9 @@ UDK_3_0_0 {
ExportDOC;
SaveOrDelMSVBAStorage_ww8;
GetSaveWarningOfMSVBAStorage_ww8;
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
local:
*;
};