diff options
Diffstat (limited to 'sw/source/filter/rtf/wrtrtf.cxx')
-rw-r--r-- | sw/source/filter/rtf/wrtrtf.cxx | 1806 |
1 files changed, 1806 insertions, 0 deletions
diff --git a/sw/source/filter/rtf/wrtrtf.cxx b/sw/source/filter/rtf/wrtrtf.cxx new file mode 100644 index 000000000000..8e17bee3874b --- /dev/null +++ b/sw/source/filter/rtf/wrtrtf.cxx @@ -0,0 +1,1806 @@ +/************************************************************************* + * + * 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 + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" +#include <stdlib.h> +#include <hintids.hxx> + +#include <comphelper/string.hxx> +#include <tools/stream.hxx> +#include <tools/datetime.hxx> +#include <unotools/fontcvt.hxx> +#include <rtl/tencinfo.h> +#include <svtools/rtfkeywd.hxx> +#include <svtools/rtfout.hxx> +#include <editeng/paperinf.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/shaditem.hxx> +#include <editeng/brshitem.hxx> +#include <editeng/colritem.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/tstpitem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/frmdiritem.hxx> +#include <editeng/udlnitem.hxx> +#include <fmtpdsc.hxx> +#include <fmtcntnt.hxx> +#include <fmtfsize.hxx> +#include <fmthdft.hxx> +#include <frmatr.hxx> +#include <fmtanchr.hxx> +#include <docary.hxx> +#include <pam.hxx> +#include <doc.hxx> +#include <paratr.hxx> +#include <fldbas.hxx> +#include <ndtxt.hxx> +#include <wrtrtf.hxx> +#include <flypos.hxx> +#include <IMark.hxx> +#include <pagedesc.hxx> // fuer SwPageDesc... +#include <ftninfo.hxx> +#include <charfmt.hxx> +#include <SwStyleNameMapper.hxx> +#include <section.hxx> +#include <swtable.hxx> // fuer SwPageDesc ... +#include <swmodule.hxx> +#include <swerror.h> +#include <mdiexp.hxx> // ...Percent() +#include <statstr.hrc> // ResId fuer Statusleiste +#include <docsh.hxx> + +#include <com/sun/star/document/XDocumentProperties.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> + + +#if defined(UNX) +const sal_Char SwRTFWriter::sNewLine = '\012'; +#else +const sal_Char __FAR_DATA SwRTFWriter::sNewLine[] = "\015\012"; +#endif + +SV_DECL_VARARR( RTFColorTbl, Color, 5, 8 ) +SV_IMPL_VARARR( RTFColorTbl, Color ) + + +SwRTFWriter::SwRTFWriter( const String& rFltName, const String & rBaseURL ) : + eDefaultEncoding( + rtl_getTextEncodingFromWindowsCharset( + sw::ms::rtl_TextEncodingToWinCharset(DEF_ENCODING))), + eCurrentEncoding(eDefaultEncoding) +{ + SetBaseURL( rBaseURL ); + // schreibe Win-RTF-HelpFileFmt + bWriteHelpFmt = 'W' == rFltName.GetChar( 0 ); + // schreibe nur Gliederungs Absaetze + bOutOutlineOnly = 'O' == rFltName.GetChar( 0 ); + // enable non-standard tags for cut and paste + bNonStandard = '\0' == rFltName.GetChar( 0 ); +} + + +SwRTFWriter::~SwRTFWriter() +{} + + +ULONG SwRTFWriter::WriteStream() +{ + bOutPageAttr = bOutSection = TRUE; + + bOutStyleTab = bOutTable = bOutPageDesc = bOutPageDescTbl = + bAutoAttrSet = bOutListNumTxt = bOutLeftHeadFoot = bIgnoreNextPgBreak = + bTxtAttr = bAssociated = FALSE; + + nCurScript = 1; // latin - ask the doc?? + + nCurRedline = USHRT_MAX; + if(pDoc->GetRedlineTbl().Count()) + nCurRedline = 0; + + + pCurEndPosLst = 0; + nBkmkTabPos = -1; + pAktPageDesc = 0; + pAttrSet = 0; + pFlyFmt = 0; // kein FlyFrmFormat gesetzt + + pColTbl = new RTFColorTbl; + pNumRuleTbl = 0; + + BYTE nSz = (BYTE)Min( pDoc->GetSpzFrmFmts()->Count(), USHORT(255) ); + SwPosFlyFrms aFlyPos( nSz, nSz ); + + //Abkuerzung wenn nur Gliederung ausgegeben werden soll, und keine + //Gliederungsabsaetze ausserhalb des Body stehen. + if ( bOutOutlineOnly && + pDoc->GetNodes().GetOutLineNds().Count() && + pDoc->GetNodes().GetOutLineNds()[0]->GetIndex() > + pDoc->GetNodes().GetEndOfExtras().GetIndex() ) + { + nAktFlyPos = 0; + pFlyPos = 0; + MakeHeader(); + + const SwOutlineNodes &rOutLine = pDoc->GetNodes().GetOutLineNds(); + for ( USHORT i = 0; i < rOutLine.Count(); ++i ) + { + const SwNode *pNd = pDoc->GetNodes()[*rOutLine[i]]; + ASSERT( pNd->IsCntntNode(), "Outlinenode and no CntNode!?" ); + + SwCntntNode* pCNd = (SwCntntNode*)pNd; + + // erfrage den aktuellen PageDescriptor. + const SwPageDesc* pTmp = pCNd->GetSwAttrSet().GetPageDesc().GetPageDesc(); + if( pTmp ) + pAktPageDesc = pTmp; + pCurPam->GetPoint()->nContent.Assign( pCNd, 0 ); + Out( aRTFNodeFnTab, *pCNd, *this ); + } + } + else + { + long nMaxNode = pDoc->GetNodes().Count(); + + if( bShowProgress ) + ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() ); + + // Tabelle am Doc.-Anfang beachten + { + SwTableNode * pTNd = pCurPam->GetNode()->FindTableNode(); + if( pTNd && bWriteAll ) + { + // mit dem TabellenNode anfangen !! + pCurPam->GetPoint()->nNode = *pTNd; + + if( bWriteOnlyFirstTable ) + pCurPam->GetMark()->nNode = *pTNd->EndOfSectionNode(); + } + } + + // Tabelle fuer die freifliegenden Rahmen erzeugen, aber nur wenn + // das gesamte Dokument geschrieben wird + nAktFlyPos = 0; + pDoc->GetAllFlyFmts( aFlyPos, bWriteAll ? 0 : pOrigPam ); + + // sollten nur Rahmen vorhanden sein? + // (Moeglich, wenn eine Rahmen-Selektion ins Clipboard + // gestellt wurde) + if( bWriteAll && + // keine Laenge + *pCurPam->GetPoint() == *pCurPam->GetMark() && + // Rahmen vorhanden + pDoc->GetSpzFrmFmts()->Count() && !aFlyPos.Count() && + // nur ein Node im Array + pDoc->GetNodes().GetEndOfExtras().GetIndex() + 3 == + pDoc->GetNodes().GetEndOfContent().GetIndex() && + // und genau der ist selektiert + pDoc->GetNodes().GetEndOfContent().GetIndex() - 1 == + pCurPam->GetPoint()->nNode.GetIndex() ) + { + // dann den Inhalt vom Rahmen ausgeben. + // dieser steht immer an Position 0 !! + SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[ 0 ]; + const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx(); + if( pIdx ) + { + SwPosFlyFrm* pFPos = new SwPosFlyFrm( pCurPam->GetPoint()->nNode, + pFmt, aFlyPos.Count() ); + aFlyPos.Insert( pFPos ); + } + } + + pFlyPos = &aFlyPos; + + // schreibe die StyleTabelle, allgemeine Angaben,Header/Footer/Footnotes + MakeHeader(); + + Out_SwDoc( pOrigPam ); + + if( bShowProgress ) + ::EndProgress( pDoc->GetDocShell() ); + } + + Strm() << '}'; + + // loesche die Tabelle mit den freifliegenden Rahmen + for( USHORT i = aFlyPos.Count(); i > 0; ) + delete aFlyPos[ --i ]; + + pFlyPos = 0; + delete pColTbl; + if( pNumRuleTbl ) + { + // don't destroy the numrule pointers in the DTOR. + pNumRuleTbl->Remove( 0, pNumRuleTbl->Count() ); + delete pNumRuleTbl; + } + delete pRedlAuthors; + + // schreibe Win-RTF-HelpFileFmt + bOutOutlineOnly = bWriteHelpFmt = FALSE; + pAttrSet = 0; + + return 0; +} + + +void SwRTFWriter::Out_SwDoc( SwPaM* pPam ) +{ + BOOL bSaveWriteAll = bWriteAll; // sichern + // suche die naechste Bookmark-Position aus der Bookmark-Tabelle + nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1; + + // gebe alle Bereiche des Pams in das RTF-File aus. + do { + bWriteAll = bSaveWriteAll; + bFirstLine = TRUE; + + // suche den ersten am Pam-auszugebenen FlyFrame + // fehlt noch: + + while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode || + (pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode && + pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) ) + { + SwNode& rNd = pCurPam->GetPoint()->nNode.GetNode(); + + if( &rNd == &pDoc->GetNodes().GetEndOfContent() ) + break; + + if( rNd.IsCntntNode() ) + { + SwCntntNode& rCNd = (SwCntntNode&)rNd; + + OutBreaks( rCNd.GetSwAttrSet() ); + OutFlyFrm(); + + if( !bFirstLine ) + pCurPam->GetPoint()->nContent.Assign( &rCNd, 0 ); + + if( !bOutOutlineOnly || + //( rCNd.IsTxtNode() && NO_NUMBERING != //#outline level,removed by zhaojianwei + //((SwTxtNode&)rCNd).GetTxtColl()->GetOutlineLevel() )) + ( rCNd.IsTxtNode() && //->add by zhaojianwei + ((SwTxtNode&)rCNd).GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()))//<-end,zhaojianwei + Out( aRTFNodeFnTab, rCNd, *this ); + + } + else if( !bOutOutlineOnly ) + { + if (rNd.IsTableNode()) + { + bool bAllOk = false; + if (const SwTableNode *pNd = rNd.GetTableNode()) + { + if (const SwFrmFmt *pFmt = pNd->GetTable().GetFrmFmt()) + { + OutBreaks(pFmt->GetAttrSet()); + bAllOk = true; + } + OutRTF_SwTblNode(*this, *pNd); + } + ASSERT(bAllOk, "Unexpected missing properties from tables"); + } + else if( rNd.IsSectionNode() ) + { + OutBreaks( ((SwSectionNode&)rNd).GetSection().GetFmt() + ->GetAttrSet() ); + OutRTF_SwSectionNode( *this, (SwSectionNode&)rNd ); + } + else if( rNd.IsEndNode() ) + CheckEndNodeForSection( rNd ); + } + + ULONG nPos = pCurPam->GetPoint()->nNode++; // Bewegen + + if( bShowProgress ) + ::SetProgressState( nPos, pDoc->GetDocShell() ); // Wie weit ? + + /* sollen nur die Selectierten Bereiche gesichert werden, so + * duerfen nur die vollstaendigen Nodes gespeichert werde, + * d.H. der 1. und n. Node teilweise, der 2. bis n-1. Node + * vollstaendig. (vollstaendig heisst mit allen Formaten! ) + */ + bWriteAll = bSaveWriteAll || + pCurPam->GetPoint()->nNode != pCurPam->GetMark()->nNode; + bFirstLine = FALSE; + } + } while( CopyNextPam( &pPam ) ); // bis alle PaM's bearbeitet + + bWriteAll = bSaveWriteAll; // wieder auf alten Wert zurueck +} + + +// schreibe die StyleTabelle, algemeine Angaben,Header/Footer/Footnotes + + +void SwRTFWriter::MakeHeader() +{ + // baue den Vorspann wie Header, ColorTbl, FontTbl + Strm() << '{' << OOO_STRING_SVTOOLS_RTF_RTF << '1' + << OOO_STRING_SVTOOLS_RTF_ANSI; + if( bWriteAll ) + { + Strm() << OOO_STRING_SVTOOLS_RTF_DEFF; + OutULong( GetId( (SvxFontItem&)pDoc->GetAttrPool().GetDefaultItem( + RES_CHRATR_FONT ) )); + } + // JP 13.02.2001 - if this not exist, MS don't understand our ansi + // characters (0x80-0xff). + Strm() << "\\adeflang1025"; + + OutRTFFontTab(); + OutRTFColorTab(); + OutRTFStyleTab(); + OutRTFListTab(); + OutRTFRevTab(); + + Strm() << SwRTFWriter::sNewLine; // ein Trenner + + // wenn teilweise ausgegeben wird, die globalen Daten nicht speichern + if( !bWriteAll ) + return; + + // Ausgeben der Doc-Info/-Statistik + OutDocInfoStat(); + + // einige globale Daten Schreiben + { // Default-TabSize + const SvxTabStopItem& rTabs = (const SvxTabStopItem&) + pDoc->GetAttrPool().GetDefaultItem( RES_PARATR_TABSTOP ); + Strm() << OOO_STRING_SVTOOLS_RTF_DEFTAB; + OutLong( rTabs[0].GetTabPos() ); + if ( !pDoc->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) ) + Strm() << OOO_STRING_SVTOOLS_RTF_LYTPRTMET; + } + + // PageDescriptor ausgeben (??nur wenn das gesamte Dokument??) + OutPageDesc(); + + // gebe die Groesse und die Raender der Seite aus + if( pDoc->GetPageDescCnt() ) + { + //JP 06.04.99: Bug 64361 - suche den ersten SwFmtPageDesc. Ist + // keiner gesetzt, so ist der Standard gueltig + 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 )) + { + // FALSE wegen schliessender Klammer !! + OutComment( *this, OOO_STRING_SVTOOLS_RTF_PGDSCNO, FALSE ); + 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-Dokument wird immer ohne Drucker angelegt, so ist + // der Std.PageDesc immer aug LONG_MAX !! Mappe dann auf DIN 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; + OutRTFPageDescription( rPageDesc, FALSE, TRUE ); // Changed bCheckForFirstPage to TRUE so headers + // following title page are correctly added - i13107 + if( pSttPgDsc ) + { + bIgnoreNextPgBreak = TRUE; + pAktPageDesc = &rPageDesc; + } + } + + + { + // schreibe die Fussnoten- und Endnoten-Info raus + 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; + } + + if( pDoc->_GetDBDesc().sDataSource.getLength() ) + { + // stelle erstmal fest, ob ueberhaupt Datenbankfelder benutzt werden! + const SwFldTypes* pTypes = pDoc->GetFldTypes(); + for( USHORT nCnt = pTypes->Count(); nCnt >= INIT_FLDTYPES; ) + if( RES_DBFLD == (*pTypes)[ --nCnt ]->Which() && + (*pTypes)[ nCnt ]->GetDepends() ) + { + Strm() << '{' << OOO_STRING_SVTOOLS_RTF_FIELD; + OutComment( *this, OOO_STRING_SVTOOLS_RTF_FLDINST ) << " DATA "; + SwDBData aData = pDoc->GetDBData(); + String sOut(aData.sDataSource); + sOut += DB_DELIM; + sOut += (String)aData.sCommand; + RTFOutFuncs::Out_String( Strm(), sOut, + eDefaultEncoding, bWriteHelpFmt ); + Strm() << "}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << " }}"; + break; + } + } + + pAttrSet = 0; + + Strm() << SwRTFWriter::sNewLine; // ein Trenner +} + +void SwRTFWriter::OutInfoDateTime( const sal_Char* i_pStr, + const util::DateTime& i_rDT ) +{ + Strm() << '{' << i_pStr << OOO_STRING_SVTOOLS_RTF_YR; + OutLong( Strm(), i_rDT.Year ) << OOO_STRING_SVTOOLS_RTF_MO; + OutLong( Strm(), i_rDT.Month ) << OOO_STRING_SVTOOLS_RTF_DY; + OutLong( Strm(), i_rDT.Day ) << OOO_STRING_SVTOOLS_RTF_HR; + OutLong( Strm(), i_rDT.Hours ) << OOO_STRING_SVTOOLS_RTF_MIN; + OutLong( Strm(), i_rDT.Minutes ) << '}'; +} + +bool CharsetSufficient(const String &rString, rtl_TextEncoding eChrSet) +{ + const sal_uInt32 nFlags = + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | + RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR; + rtl::OString sDummy; + rtl::OUString sStr(rString); + return sStr.convertToString(&sDummy, eChrSet, nFlags); +} + +void SwRTFWriter::OutUnicodeSafeRecord(const sal_Char *pToken, + const String &rContent) +{ + if (rContent.Len()) + { + bool bNeedUnicodeWrapper = !CharsetSufficient(rContent, eDefaultEncoding); + + if (bNeedUnicodeWrapper) + Strm() << '{' << OOO_STRING_SVTOOLS_RTF_UPR; + + Strm() << '{' << pToken << ' '; + OutRTF_AsByteString(*this, rContent, eDefaultEncoding); + Strm() << '}'; + + if (bNeedUnicodeWrapper) + { + OutComment(*this, OOO_STRING_SVTOOLS_RTF_UD); + Strm() << '{' << pToken << ' '; + RTFOutFuncs::Out_String(Strm(), rContent, eDefaultEncoding, + bWriteHelpFmt); + Strm() << "}}}"; + } + + } +} + +void SwRTFWriter::OutDocInfoStat() +{ + 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_THROW); + xDocProps.set(xDPS->getDocumentProperties()); + } + + // may be null (in case of copying) + if (xDocProps.is()) + { + OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle()); + OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_SUBJECT, xDocProps->getSubject()); + + OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_KEYWORDS, + ::comphelper::string::convertCommaSeparated(xDocProps->getKeywords())); + OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_DOCCOMM, xDocProps->getDescription()); + + OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getAuthor() ); + OutInfoDateTime(OOO_STRING_SVTOOLS_RTF_CREATIM, xDocProps->getCreationDate()); + + OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getModifiedBy() ); + OutInfoDateTime(OOO_STRING_SVTOOLS_RTF_REVTIM, xDocProps->getModificationDate()); + + OutInfoDateTime(OOO_STRING_SVTOOLS_RTF_PRINTIM, xDocProps->getPrintDate()); + + } + + // fuer interne Zwecke - Versionsnummer rausschreiben + Strm() << '{' << OOO_STRING_SVTOOLS_RTF_COMMENT << " StarWriter}{" << OOO_STRING_SVTOOLS_RTF_VERN; + OutLong( Strm(), SUPD*10 ) << '}'; + + Strm() << '}'; +} + +static void InsColor( RTFColorTbl& rTbl, const Color& rCol ) +{ + USHORT n; + for( n = 0; n < rTbl.Count(); ++n ) + if( rTbl[n] == rCol ) + return; // schon vorhanden, zurueck + + n = COL_AUTO == rCol.GetColor() ? 0 : rTbl.Count(); + rTbl.Insert( rCol, n ); +} + +static void InsColorLine( RTFColorTbl& rTbl, const SvxBoxItem& rBox ) +{ + const SvxBorderLine* pLine = 0; + + if( rBox.GetTop() ) + InsColor( rTbl, (pLine = rBox.GetTop())->GetColor() ); + if( rBox.GetBottom() && pLine != rBox.GetBottom() ) + InsColor( rTbl, (pLine = rBox.GetBottom())->GetColor() ); + if( rBox.GetLeft() && pLine != rBox.GetLeft() ) + InsColor( rTbl, (pLine = rBox.GetLeft())->GetColor() ); + if( rBox.GetRight() && pLine != rBox.GetRight() ) + InsColor( rTbl, rBox.GetRight()->GetColor() ); +} + +void SwRTFWriter::OutRTFColorTab() +{ + ASSERT( pColTbl, "Wo ist meine Color-Tabelle?" ); + + // dann baue die ColorTabelle aus allen Attributen, die Colors + // enthalten und im Pool angemeldet sind auf. + USHORT n, nMaxItem; + const SfxItemPool& rPool = pDoc->GetAttrPool(); + + // das Charakter - Color Attribut + { + const SvxColorItem* pCol = (const SvxColorItem*)GetDfltAttr( + RES_CHRATR_COLOR ); + InsColor( *pColTbl, pCol->GetValue() ); + if( 0 != ( pCol = (const SvxColorItem*)rPool.GetPoolDefaultItem( + RES_CHRATR_COLOR ) )) + InsColor( *pColTbl, 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( *pColTbl, pCol->GetValue() ); + } + + const SvxUnderlineItem* pUnder = (const SvxUnderlineItem*)GetDfltAttr( RES_CHRATR_UNDERLINE ); + InsColor( *pColTbl, 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( *pColTbl, pUnder->GetColor() ); + + } + + const SvxOverlineItem* pOver = (const SvxOverlineItem*)GetDfltAttr( RES_CHRATR_OVERLINE ); + InsColor( *pColTbl, 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( *pColTbl, pOver->GetColor() ); + + } + + } + + // das Frame Hintergrund - Attribut + 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( *pColTbl, pBkgrd->GetColor() ); + if( 0 != ( pBkgrd = (const SvxBrushItem*)rPool.GetPoolDefaultItem( + *pIds ) )) + { + InsColor( *pColTbl, pBkgrd->GetColor() ); + } + nMaxItem = rPool.GetItemCount( *pIds ); + for( n = 0; n < nMaxItem; ++n ) + if( 0 != (pBkgrd = (const SvxBrushItem*)rPool.GetItem( + *pIds , n ) )) + { + InsColor( *pColTbl, pBkgrd->GetColor() ); + } + } + + // das Frame Schatten - Attribut + { + const SvxShadowItem* pShadow = (const SvxShadowItem*)GetDfltAttr( + RES_SHADOW ); + InsColor( *pColTbl, pShadow->GetColor() ); + if( 0 != ( pShadow = (const SvxShadowItem*)rPool.GetPoolDefaultItem( + RES_SHADOW ) )) + { + InsColor( *pColTbl, pShadow->GetColor() ); + } + nMaxItem = rPool.GetItemCount(RES_SHADOW); + for( n = 0; n < nMaxItem; ++n ) + if( 0 != (pShadow = (const SvxShadowItem*)rPool.GetItem( + RES_SHADOW, n ) ) ) + { + InsColor( *pColTbl, pShadow->GetColor() ); + } + } + + // das Frame Umrandungs - Attribut + { + // Box muesste noch gemacht werden, aber default nie eine Line gesetzt! + const SvxBoxItem* pBox; + if( 0 != ( pBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem( + RES_BOX ) )) + InsColorLine( *pColTbl, *pBox ); + nMaxItem = rPool.GetItemCount(RES_BOX); + for( n = 0; n < nMaxItem; ++n ) + if( 0 != (pBox = (const SvxBoxItem*)rPool.GetItem( RES_BOX, n ) )) + InsColorLine( *pColTbl, *pBox ); + } + + // und raus damit + Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_COLORTBL; + + for( n = 0; n < pColTbl->Count(); n++ ) + { + const Color& rCol = (*pColTbl)[ 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() << ';'; + } + Strm() << '}'; +} + +bool FontCharsetSufficient(const String &rFntNm, const String &rAltNm, + rtl_TextEncoding eChrSet) +{ + bool bRet = CharsetSufficient(rFntNm, eChrSet); + if (bRet) + bRet = CharsetSufficient(rAltNm, eChrSet); + return bRet; +} + +static void _OutFont( SwRTFWriter& rWrt, const SvxFontItem& rFont, USHORT nNo ) +{ + rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_F; + + const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL; + switch (rFont.GetFamily()) + { + 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; + } + rWrt.OutULong(nNo) << pStr << OOO_STRING_SVTOOLS_RTF_FPRQ; + + USHORT nVal = 0; + switch (rFont.GetPitch()) + { + case PITCH_FIXED: + nVal = 1; + break; + case PITCH_VARIABLE: + nVal = 2; + break; + default: + nVal = 0; + break; + } + rWrt.OutULong(nVal); + + sw::util::FontMapExport aRes(rFont.GetFamilyName()); + + /* + #i10538# + In rtf the fontname is in the fontcharset, so if that isn't possible + then bump the charset up to unicode + */ + sal_uInt8 nChSet = 0; + rtl_TextEncoding eChrSet = rFont.GetCharSet(); + nChSet = sw::ms::rtl_TextEncodingToWinCharset(eChrSet); + eChrSet = rtl_getTextEncodingFromWindowsCharset(nChSet); + if (!FontCharsetSufficient(aRes.msPrimary, aRes.msSecondary, eChrSet)) + { + eChrSet = RTL_TEXTENCODING_UNICODE; + nChSet = sw::ms::rtl_TextEncodingToWinCharset(eChrSet); + eChrSet = rtl_getTextEncodingFromWindowsCharset(nChSet); + } + + rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FCHARSET; + rWrt.OutULong( nChSet ); + rWrt.Strm() << ' '; + if (aRes.HasDistinctSecondary()) + { + RTFOutFuncs::Out_Fontname(rWrt.Strm(), aRes.msPrimary, eChrSet, + rWrt.bWriteHelpFmt); + OutComment(rWrt, OOO_STRING_SVTOOLS_RTF_FALT) << ' '; + RTFOutFuncs::Out_Fontname(rWrt.Strm(), aRes.msSecondary, eChrSet, + rWrt.bWriteHelpFmt) << '}'; + } + else + { + RTFOutFuncs::Out_Fontname(rWrt.Strm(), aRes.msPrimary, eChrSet, + rWrt.bWriteHelpFmt); + } + rWrt.Strm() << ";}"; +} + +void SwRTFWriter::OutRTFFontTab() +{ + USHORT n = 0; + const SfxItemPool& rPool = pDoc->GetAttrPool(); + const SvxFontItem* pFont = (const SvxFontItem*)GetDfltAttr(RES_CHRATR_FONT); + + Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_FONTTBL; + _OutFont( *this, *pFont, n++ ); + + pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem(RES_CHRATR_FONT); + if (pFont) + _OutFont(*this, *pFont, n++); + + PutNumFmtFontsInAttrPool(); + PutCJKandCTLFontsInAttrPool(); + + USHORT nMaxItem = rPool.GetItemCount(RES_CHRATR_FONT); + for (USHORT nGet = 0; nGet < nMaxItem; ++nGet) + { + pFont = (const SvxFontItem*)rPool.GetItem(RES_CHRATR_FONT, nGet); + if (pFont) + _OutFont(*this, *pFont, n++); + } + + Strm() << '}'; +} + +void RTF_WrtRedlineAuthor::Write(Writer &rWrt) +{ + SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt; + + rRTFWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_REVTBL << ' '; + typedef std::vector<String>::iterator myiter; + + for(std::vector<String>::iterator aIter = maAuthors.begin(); aIter != maAuthors.end(); ++aIter) + { + rRTFWrt.Strm() << '{'; + // rWrt.bWriteHelpFmt + RTFOutFuncs::Out_String( rRTFWrt.Strm(), *aIter, rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt ) << ";}"; + } + rRTFWrt.Strm() << '}' << SwRTFWriter::sNewLine; +} + +bool SwRTFWriter::OutRTFRevTab() +{ + // Writes the revision author table + int nRevAuthors = pDoc->GetRedlineTbl().Count(); + + pRedlAuthors = new RTF_WrtRedlineAuthor; + // RTF always seems to use Unknown as the default first entry + String sUnknown(RTL_CONSTASCII_STRINGPARAM("Unknown")); + pRedlAuthors->AddName(sUnknown); + + if (nRevAuthors < 1) + return false; + + // pull out all the redlines and make a vector of all the author names + for( USHORT i = 0; i < pDoc->GetRedlineTbl().Count(); ++i ) + { + const SwRedline* pRedl = pDoc->GetRedlineTbl()[ i ]; + const String sAuthor = SW_MOD()->GetRedlineAuthor( pRedl->GetAuthor() ); + pRedlAuthors->AddName(sAuthor); + } + + pRedlAuthors->Write(*this); + return true; +} + +//Takashi Ono for CJK +const rtl::OUString SwRTFWriter::XlateFmtName( const rtl::OUString &rName, SwGetPoolIdFromName eFlags ) +{ +#define RES_NONE RES_POOLCOLL_DOC_END + + static const RES_POOL_COLLFMT_TYPE aArr[]={ + RES_POOLCOLL_STANDARD, RES_POOLCOLL_HEADLINE1, RES_POOLCOLL_HEADLINE2, + RES_POOLCOLL_HEADLINE3, RES_POOLCOLL_HEADLINE4, RES_POOLCOLL_HEADLINE5, + RES_POOLCOLL_HEADLINE6, RES_POOLCOLL_HEADLINE7, RES_POOLCOLL_HEADLINE8, + RES_POOLCOLL_HEADLINE9, + + RES_POOLCOLL_TOX_IDX1, RES_POOLCOLL_TOX_IDX2, RES_POOLCOLL_TOX_IDX3, + RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, + RES_POOLCOLL_TOX_CNTNT1, + + RES_POOLCOLL_TOX_CNTNT2, RES_POOLCOLL_TOX_CNTNT3, RES_POOLCOLL_TOX_CNTNT4, + RES_POOLCOLL_TOX_CNTNT5, RES_POOLCOLL_TOX_CNTNT6, RES_POOLCOLL_TOX_CNTNT7, + RES_POOLCOLL_TOX_CNTNT8, RES_POOLCOLL_TOX_CNTNT9, + RES_POOLCOLL_TEXT_IDENT, RES_POOLCOLL_FOOTNOTE, + + RES_NONE, RES_POOLCOLL_HEADER, RES_POOLCOLL_FOOTER, RES_POOLCOLL_TOX_IDXH, + RES_POOLCOLL_LABEL, RES_POOLCOLL_TOX_ILLUSH, RES_POOLCOLL_JAKETADRESS, RES_POOLCOLL_SENDADRESS, + RES_NONE, RES_NONE, + + RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_ENDNOTE, RES_POOLCOLL_TOX_AUTHORITIESH, RES_NONE, RES_NONE, + RES_POOLCOLL_BUL_LEVEL1, RES_POOLCOLL_BUL_LEVEL1, RES_POOLCOLL_NUM_LEVEL1, + + RES_POOLCOLL_BUL_LEVEL2, RES_POOLCOLL_BUL_LEVEL3, RES_POOLCOLL_BUL_LEVEL4, RES_POOLCOLL_BUL_LEVEL5, + RES_POOLCOLL_BUL_LEVEL2, RES_POOLCOLL_BUL_LEVEL3, RES_POOLCOLL_BUL_LEVEL4, RES_POOLCOLL_BUL_LEVEL5, + RES_POOLCOLL_NUM_LEVEL2, RES_POOLCOLL_NUM_LEVEL3, RES_POOLCOLL_NUM_LEVEL4, RES_POOLCOLL_NUM_LEVEL5, + + RES_POOLCOLL_DOC_TITEL, RES_NONE, RES_POOLCOLL_SIGNATURE, RES_NONE, + RES_POOLCOLL_TEXT, RES_POOLCOLL_TEXT_MOVE, RES_NONE, RES_NONE, + + RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_DOC_SUBTITEL }; + + static const sal_Char *stiName[] = { + "Normal", "heading 1", "heading 2", + "heading 3", "heading 4", "heading 5", + "heading 6", "heading 7", "heading 8", + "heading 9", + + "index 1", "index 2", "index 3", + "index 4", "index 5", "index 6", + "index 7", "index 8", "index 9", + + "toc 1", "toc 2", "toc 3", + "toc 4", "toc 5", "toc 6", + "toc 7", "toc 8", "toc 9", + "Normal Indent", "footnote text", + + "annotation text", "header", "footer", "index heading", + "caption", "table of figures", "envelope address", "envelope return", + "footnote reference", "annotation reference", + + "line number", "page number", "endnote reference", "endnote text", "table of authorities", "macro", "toa heading", + "List", "List Bullet", "List Number", + + "List 2", "List 3", "List 4", "List 5", + "List Bullet 2", "List Bullet 3", "List Bullet 4", "List Bullet 5", + "List Number 2", "List Number 3", "List Number 4", "List Number 5", + + "Title", "Closing", "Signature", "Default Paragraph Font", + "Body Text", "Body Text Indent", "List Continue", + + "List Continue 2", "List Continue 3", "List Continue 4", "List Continue 5", "Message Header", "Subtitle"}; + + ASSERT( ( sizeof( aArr ) / sizeof( RES_POOL_COLLFMT_TYPE ) == 75 ), + "Style-UEbersetzungstabelle hat falsche Groesse" ); + ASSERT( ( sizeof( stiName ) / sizeof( *stiName ) == 75 ), + "Style-UEbersetzungstabelle hat falsche Groesse" ); + + sal_uInt16 idcol = ::SwStyleNameMapper::GetPoolIdFromUIName( rName, eFlags ); + if (idcol==USHRT_MAX) //#i40770# user defined style names get lost + return rName; + + for (size_t i = 0; i < sizeof( aArr ) / sizeof( *aArr ); i++) + { + if ( idcol == aArr[i] ) + { + return rtl::OUString::createFromAscii(stiName[i]); + } + } + return ::SwStyleNameMapper::GetProgName( idcol, String() ); +} + +void SwRTFWriter::OutRTFStyleTab() +{ + USHORT n; + + // das 0-Style ist das Default, wird nie ausgegeben !! + USHORT nArrLen = pDoc->GetTxtFmtColls()->Count(); + if( nArrLen <= 1 && pDoc->GetCharFmts()->Count() <= 1 ) + return; + + bOutStyleTab = TRUE; + Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_STYLESHEET; + + // das Default-TextStyle wird nicht mit ausgegeben !! + for( n = 1; n < nArrLen; ++n ) + { + const SwTxtFmtColl* pColl = (*pDoc->GetTxtFmtColls())[ n ]; + pAttrSet = &pColl->GetAttrSet(); + + Strm() << '{'; + // gebe Attribute aus + OutRTF_SwFmt( *this, *pColl ); + + if( pColl->DerivedFrom() ) + // suche die Id vom "Parent" Format + for( USHORT nBasedOn=1; nBasedOn < nArrLen; nBasedOn++) + if( (*pDoc->GetTxtFmtColls())[ nBasedOn ] == + pColl->DerivedFrom() ) + { + // die Ableitung vom Format + Strm() << OOO_STRING_SVTOOLS_RTF_SBASEDON; + OutULong( nBasedOn ); + break; + } + + if( pColl == &pColl->GetNextTxtFmtColl() ) + { + Strm() << OOO_STRING_SVTOOLS_RTF_SNEXT; + OutULong( n ); + } + else + // suche die Id vom "Naechsten" Format + for( USHORT nNext=1; nNext < nArrLen; nNext++) + if( (*pDoc->GetTxtFmtColls())[ nNext ] == + &pColl->GetNextTxtFmtColl() ) + { + // die Ableitung vom Format + Strm() << OOO_STRING_SVTOOLS_RTF_SNEXT; + OutULong( nNext ); + break; + } + + //if( NO_NUMBERING != pColl->GetOutlineLevel() )//#outline level,zhaojianwei + if(pColl->IsAssignedToListLevelOfOutlineStyle())//<-end,zhaojianwei + { + Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_SOUTLVL; + //OutULong( pColl->GetOutlineLevel() ) << '}';//#outline level,zhaojianwei + OutULong( pColl->GetAssignedOutlineStyleLevel() ) << '}';//<-end,zhaojianwei + } + + Strm() << ' '; + RTFOutFuncs::Out_String( Strm(), XlateFmtName( pColl->GetName(), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ), eDefaultEncoding, + bWriteHelpFmt ) << ";}" << SwRTFWriter::sNewLine; + } + + USHORT nChrArrLen = pDoc->GetCharFmts()->Count(); + for( n = 1; n < nChrArrLen; ++n ) + { + const SwCharFmt* pFmt = (*pDoc->GetCharFmts())[ n ]; + pAttrSet = &pFmt->GetAttrSet(); + + Strm() << '{'; + // gebe Attribute aus + OutRTF_SwFmt( *this, *pFmt ); + + if( pFmt->DerivedFrom() ) + // suche die Id vom "Parent" Format + for( USHORT nBasedOn=1; nBasedOn < nChrArrLen; nBasedOn++) + if( (*pDoc->GetCharFmts())[ nBasedOn ] == + pFmt->DerivedFrom() ) + { + // die Ableitung vom Format + Strm() << OOO_STRING_SVTOOLS_RTF_SBASEDON; + OutULong( nArrLen + nBasedOn ); + break; + } + + Strm() << ' '; + RTFOutFuncs::Out_String( Strm(), XlateFmtName( pFmt->GetName(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ), eDefaultEncoding, + bWriteHelpFmt ) << ";}" << SwRTFWriter::sNewLine; + } + + Strm() << '}'; + bOutStyleTab = FALSE; +} + +bool ExportAsInline(const SwFlyFrmFmt& rFlyFrmFmt) +{ + //if not an inline element (hack in our limitations here as to only + //graphics like this!!!! + return rFlyFrmFmt.GetAnchor().GetAnchorId() == FLY_AS_CHAR; +} + +void SwRTFWriter::OutRTFFlyFrms(const SwFlyFrmFmt& rFlyFrmFmt) +{ + // ein FlyFrame wurde erkannt, gebe erstmal den aus + + // Hole vom Node und vom letzten Node die Position in der Section + const SwFmtCntnt& rFlyCntnt = rFlyFrmFmt.GetCntnt(); + + ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1; + ULONG nEnd = pDoc->GetNodes()[ nStt - 1 ]->EndOfSectionIndex(); + + if( nStt >= nEnd ) // kein Bereich, also kein gueltiger Node + return; + + if (!ExportAsInline(rFlyFrmFmt)) + Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN; + //If we are only exporting an inline graphic/object then we + //only need the its pFlyFmt for the duration of exporting it + //for floating objects its a little more complex at the moment + const SwFlyFrmFmt *pOldFlyFmt = pFlyFmt; + pFlyFmt = &rFlyFrmFmt; + + { + RTFSaveData aSaveData( *this, nStt, nEnd ); + Out_SwDoc( pCurPam ); + } + + if (!ExportAsInline(rFlyFrmFmt)) + Strm() << OOO_STRING_SVTOOLS_RTF_PARD << SwRTFWriter::sNewLine; +//#i46098#: else + pFlyFmt = pOldFlyFmt; +} + + + +void SwRTFWriter::OutRedline( xub_StrLen nCntntPos ) +{ + const SwRedline *pCurRedline = 0; + USHORT nCount = pDoc->GetRedlineTbl().Count(); + + if (nCurRedline < nCount) + { + pCurRedline = pDoc->GetRedlineTbl()[nCurRedline]; + if(pCurRedline) + { + const SwPosition* pStartPos = pCurRedline->Start(); + const SwPosition* pEndPos = pStartPos == pCurRedline->GetPoint() + ? pCurRedline->GetMark() + : pCurRedline->GetPoint(); + + USHORT nStart = pStartPos->nContent.GetIndex(); + USHORT nEnd = pEndPos->nContent.GetIndex(); + + ULONG nCurPam = pCurPam->GetPoint()->nNode.GetIndex(); + ULONG nStartIndex = pStartPos->nNode.GetIndex(); + ULONG nEndIndex = pEndPos->nNode.GetIndex(); + const String& rStr = pCurPam->GetNode()->GetTxtNode()->GetTxt(); + xub_StrLen nEnde = rStr.Len(); + + bool bSpanRedline = (nCurPam >= nStartIndex) && (nCurPam <= nEndIndex) && (nStartIndex != nEndIndex); + + if ((bSpanRedline && nCntntPos == 0) || + (nStartIndex == nCurPam && nStart == nCntntPos)) + { + // We are at the start of a redline just need to find out which type + Strm() << '{'; + if(pCurRedline->GetType() == nsRedlineType_t::REDLINE_INSERT) + { + Strm() << OOO_STRING_SVTOOLS_RTF_REVISED; + Strm() << OOO_STRING_SVTOOLS_RTF_REVAUTH; + String sName = SW_MOD()->GetRedlineAuthor(pCurRedline->GetAuthor()); + OutLong( pRedlAuthors->AddName(sName) ); + Strm() << OOO_STRING_SVTOOLS_RTF_REVDTTM; + OutLong( sw::ms::DateTime2DTTM(pCurRedline->GetTimeStamp()) ); + Strm() << ' '; + } + else if(pCurRedline->GetType() == nsRedlineType_t::REDLINE_DELETE) + { + Strm() << OOO_STRING_SVTOOLS_RTF_DELETED; + Strm() << OOO_STRING_SVTOOLS_RTF_REVAUTHDEL; + String sDelName = SW_MOD()->GetRedlineAuthor(pCurRedline->GetAuthor()); + OutLong( pRedlAuthors->AddName(sDelName) ); + Strm() << OOO_STRING_SVTOOLS_RTF_REVDTTMDEL; + OutLong( sw::ms::DateTime2DTTM(pCurRedline->GetTimeStamp()) ); + Strm() << ' '; + } + } + + // this is either then of the end of the node or the end of the redline + // time to close off this one + if( (bSpanRedline && nCntntPos == nEnde) || + (nEndIndex == nCurPam && nEnd == nCntntPos) ) + { + Strm() << '}'; + } + + // We have come to the end of a redline move to the next one + // and use resursion to see if another redline starts here + if (nEndIndex == nCurPam && nEnd == nCntntPos) + { + nCurRedline++; + OutRedline(nCntntPos); + } + } + } +} + +void SwRTFWriter::OutBookmarks( xub_StrLen nCntntPos) +{ + IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess(); + if (-1 == nBkmkTabPos) + return; + + const ::sw::mark::IMark* pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get(); + if(!pBookmark) + return; + + const SwPosition* pStartPos = &pBookmark->GetMarkStart(); + const SwPosition* pEndPos = &pBookmark->GetMarkEnd(); + + ASSERT(pStartPos && pEndPos, "Impossible"); + if (!(pStartPos && pEndPos)) + return; + + if (pStartPos->nNode.GetIndex() == pCurPam->GetPoint()->nNode.GetIndex() && + pStartPos->nContent.GetIndex() == nCntntPos) + { + // zur Zeit umspannt das SwBookmark keinen Bereich also kann + // es hier vollstaendig ausgegeben werden. + + // erst die SWG spezifischen Daten: + const ::sw::mark::IBookmark* const pAsBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark); + if(pAsBookmark && (pAsBookmark->GetShortName().getLength() || pAsBookmark->GetKeyCode().GetCode())) + { + OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKKEY ); + OutULong( ( pAsBookmark->GetKeyCode().GetCode() | + pAsBookmark->GetKeyCode().GetModifier() )); + if( !pAsBookmark->GetShortName().getLength() ) + Strm() << " " ; + else + { + Strm() << ' '; + OutRTF_AsByteString( *this, pAsBookmark->GetShortName(), eDefaultEncoding ); + } + Strm() << '}'; + } + OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKSTART ) << ' '; + RTFOutFuncs::Out_String( Strm(), pBookmark->GetName(), + eDefaultEncoding, bWriteHelpFmt ) << '}'; + } + + if (pEndPos->nNode.GetIndex() == pCurPam->GetPoint()->nNode.GetIndex() && + pEndPos->nContent.GetIndex() == nCntntPos) + { + // zur Zeit umspannt das SwBookmark keinen Bereich also kann + // es hier vollstaendig ausgegeben werden. + + // erst die SWG spezifischen Daten: + const ::sw::mark::IBookmark* const pAsBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark); + if(pAsBookmark && (pAsBookmark->GetShortName().getLength() || pAsBookmark->GetKeyCode().GetCode())) + { + OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKKEY ); + OutULong( ( pAsBookmark->GetKeyCode().GetCode() | + pAsBookmark->GetKeyCode().GetModifier() )); + if( !pAsBookmark->GetShortName().getLength() ) + Strm() << " " ; + else + { + Strm() << ' '; + OutRTF_AsByteString( *this, pAsBookmark->GetShortName(), eDefaultEncoding ); + } + Strm() << '}'; + } + OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKEND ) << ' '; + + { + ::rtl::OUString aEmpty; + ::rtl::OUString & rBookmarkName = aEmpty; + + if (pAsBookmark) + rBookmarkName = pAsBookmark->GetName(); + + RTFOutFuncs::Out_String( Strm(), rBookmarkName, + eDefaultEncoding, bWriteHelpFmt ) << '}'; + } + + if(++nBkmkTabPos >= pMarkAccess->getMarksCount()) + nBkmkTabPos = -1; + else + pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get(); + } +} + +void SwRTFWriter::OutFlyFrm() +{ + USHORT n; + + if( !pFlyPos ) + return; + + // gebe alle freifliegenden Rahmen die sich auf den akt. Absatz + // und evt. auf das aktuelle Zeichen beziehen, aus. + + // suche nach dem Anfang der FlyFrames + for( n = 0; n < pFlyPos->Count() && + (*pFlyPos)[n]->GetNdIndex().GetIndex() < + pCurPam->GetPoint()->nNode.GetIndex(); ++n ) + ; + if( n < pFlyPos->Count() ) + while( n < pFlyPos->Count() && + pCurPam->GetPoint()->nNode.GetIndex() == + (*pFlyPos)[n]->GetNdIndex().GetIndex() ) + { + // den Array-Iterator weiterschalten, damit nicht doppelt + // ausgegeben wird !! + OutRTFFlyFrms( (const SwFlyFrmFmt&)(*pFlyPos)[n++]->GetFmt() ); + } +} + + +USHORT SwRTFWriter::GetId( const Color& rColor ) const +{ + ASSERT( pColTbl, "Wo ist meine Color-Tabelle?" ); + for( USHORT n = 0; n < pColTbl->Count(); n++ ) + if( rColor == (*pColTbl)[ n ] ) + return n; + + ASSERT( FALSE, "Color nicht in der Tabelle" ); + return 0; +} + +USHORT SwRTFWriter::GetId( const SvxFontItem& rFont ) const +{ + const SfxItemPool& rPool = pDoc->GetAttrPool(); + const SvxFontItem* pFont = (const SvxFontItem*)GetDfltAttr( RES_CHRATR_FONT ); + if( rFont == *pFont ) + return 0; + + USHORT n = 1; + if( 0 != ( pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem( + RES_CHRATR_FONT ))) + { + if( rFont == *pFont ) + return 1; + ++n; + } + + USHORT nMaxItem = rPool.GetItemCount( RES_CHRATR_FONT ); + for( USHORT nGet = 0; nGet < nMaxItem; ++nGet ) + if( 0 != (pFont = (const SvxFontItem*)rPool.GetItem( + RES_CHRATR_FONT, nGet )) ) + { + if( rFont == *pFont ) + return n; + ++n; + } + + ASSERT( FALSE, "Font nicht in der Tabelle" ); + return 0; +} + +USHORT SwRTFWriter::GetId( const Font& rFont ) const +{ + return GetId( SvxFontItem( rFont.GetFamily(), rFont.GetName(), + rFont.GetStyleName(), rFont.GetPitch(), + rFont.GetCharSet(), + RES_CHRATR_FONT ) ); +} + +USHORT SwRTFWriter::GetId( const SwTxtFmtColl& rColl ) const +{ + // suche das angegebene Format + const SvPtrarr & rArr = *pDoc->GetTxtFmtColls(); + for( USHORT n = 0; n < rArr.Count(); n++ ) + if( (SwTxtFmtColl*)rArr[ n ] == &rColl ) + return n; + ASSERT( FALSE, "TextCollection nicht in der Tabelle" ); + return 0; +} + +USHORT SwRTFWriter::GetId( const SwCharFmt& rFmt ) const +{ + // suche das angegebene Format + const SvPtrarr & rArr = *pDoc->GetCharFmts(); + for( USHORT n = 0; n < rArr.Count(); n++ ) + if( (SwCharFmt*)rArr[ n ] == &rFmt ) + return n + pDoc->GetTxtFmtColls()->Count(); + ASSERT( FALSE, "CharDFFormat nicht in der Tabelle" ); + return 0; +} + +void SwRTFWriter::OutPageDesc() +{ + // Ausgabe der Page-Descriptoren + USHORT nSize = pDoc->GetPageDescCnt(); + if( !nSize ) + return; + + Strm() << SwRTFWriter::sNewLine; // ein Trenner + bOutPageDesc = bOutPageDescTbl = TRUE; + OutComment( *this, OOO_STRING_SVTOOLS_RTF_PGDSCTBL ); + for( USHORT n = 0; n < nSize; ++n ) + { + const SwPageDesc& rPageDesc = + const_cast<const SwDoc*>(pDoc)->GetPageDesc( n ); + + Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_PGDSC; + OutULong( n ) << OOO_STRING_SVTOOLS_RTF_PGDSCUSE; + OutULong( rPageDesc.ReadUseOn() ); + + OutRTFPageDescription( rPageDesc, FALSE, FALSE ); + + // suche den Folge-PageDescriptor: + USHORT i = nSize; + while( i ) + if( rPageDesc.GetFollow() == + &const_cast<const SwDoc *>(pDoc)->GetPageDesc( --i ) ) + break; + Strm() << OOO_STRING_SVTOOLS_RTF_PGDSCNXT; + OutULong( i ) << ' '; + RTFOutFuncs::Out_String( Strm(), XlateFmtName( rPageDesc.GetName(), nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC ), eDefaultEncoding, + bWriteHelpFmt ) << ";}"; + } + Strm() << '}' << SwRTFWriter::sNewLine; + bOutPageDesc = bOutPageDescTbl = FALSE; +} + +void SwRTFWriter::OutRTFBorder(const SvxBorderLine* aLine, const USHORT nSpace ) +{ + // M.M. This function writes out border lines in RTF similar to what + // WW8_BRC SwWW8Writer::TranslateBorderLine does in the winword filter + // Eventually it would be nice if all this functionality was in the one place + int nDistance = aLine->GetDistance(); + int nOutWidth = aLine->GetOutWidth(); + int nInWidth = aLine->GetInWidth(); + int nWidth = aLine->GetOutWidth(); + + if(nDistance == 0) // Single Line + Strm() << OOO_STRING_SVTOOLS_RTF_BRDRS; + else // Double Line + { + if(nOutWidth == nInWidth) + Strm() << OOO_STRING_SVTOOLS_RTF_BRDRDB; + else if (nOutWidth > nInWidth) + Strm() << OOO_STRING_SVTOOLS_RTF_BRDRTNTHSG; + else if (nOutWidth < nInWidth) + Strm() << OOO_STRING_SVTOOLS_RTF_BRDRTHTNSG; + } + Strm() << OOO_STRING_SVTOOLS_RTF_BRDRW; + OutULong(nWidth); + + Strm() << OOO_STRING_SVTOOLS_RTF_BRSP; + OutULong(nSpace); +} + +void SwRTFWriter::OutRTFBorders(SvxBoxItem aBox) +{ + const SvxBorderLine *pLine = aBox.GetTop(); + if(pLine) + { + Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRT; + OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_TOP)); + } + + pLine = aBox.GetBottom(); + if(pLine) + { + Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRB; + OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_BOTTOM)); + } + + pLine = aBox.GetRight(); + if(pLine) + { + Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRR; + OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_LEFT)); + } + + pLine = aBox.GetLeft(); + if(pLine) + { + Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRL; + OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_RIGHT)); + } +} + +void SwRTFWriter::OutRTFPageDescription( const SwPageDesc& rPgDsc, + BOOL bWriteReset, + BOOL bCheckForFirstPage ) +{ + // jetzt noch den Teil fuer alle anderen Applikationen: + const SwPageDesc *pSave = pAktPageDesc; + bool bOldOut = bOutPageDesc; + bool bOldHDFT = bOutLeftHeadFoot; + + // falls es einen Follow gibt, + pAktPageDesc = &rPgDsc; + if( bCheckForFirstPage && pAktPageDesc->GetFollow() && + pAktPageDesc->GetFollow() != pAktPageDesc ) + pAktPageDesc = pAktPageDesc->GetFollow(); + + bOutPageDesc = TRUE; + bOutLeftHeadFoot = FALSE; + + if( bWriteReset ) + { + if( bFirstLine && bWriteAll && + 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(); + OutRTF_SwFmt( *this, *pFmt ); + + SvxBoxItem aBox = pFmt->GetAttrSet().GetBox(); + OutRTFBorders(pFmt->GetAttrSet().GetBox()); + + // falls es gesharte Heaer/Footer gibt, so gebe diese auch noch aus + if ( + (nsUseOnPage::PD_MIRROR & pAktPageDesc->GetUseOn()) && + (!pAktPageDesc->IsFooterShared() || !pAktPageDesc->IsHeaderShared()) + ) + { + bOutLeftHeadFoot = TRUE; + const SfxPoolItem* pHt; + if( !pAktPageDesc->IsHeaderShared() && + SFX_ITEM_SET == pAktPageDesc->GetLeft().GetAttrSet(). + GetItemState( RES_HEADER, FALSE, &pHt )) + OutRTF_SwFmtHeader( *this, *pHt ); + + if( !pAktPageDesc->IsFooterShared() && + SFX_ITEM_SET == pAktPageDesc->GetLeft().GetAttrSet(). + GetItemState( RES_FOOTER, FALSE, &pHt )) + OutRTF_SwFmtFooter( *this, *pHt ); + bOutLeftHeadFoot = FALSE; + } + + if( pAktPageDesc != &rPgDsc ) + { + pAktPageDesc = &rPgDsc; + Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG; + + // die Header/Footer der 1. Seite ausgeben + const SfxPoolItem* pHt; + if( SFX_ITEM_SET == pAktPageDesc->GetMaster().GetAttrSet(). + GetItemState( RES_HEADER, FALSE, &pHt )) + OutRTF_SwFmtHeader( *this, *pHt ); + + if( SFX_ITEM_SET == pAktPageDesc->GetMaster().GetAttrSet(). + GetItemState( RES_FOOTER, FALSE, &pHt )) + OutRTF_SwFmtFooter( *this, *pHt ); + } + + pAktPageDesc = pSave; + bOutPageDesc = bOldOut; + bOutLeftHeadFoot = bOldHDFT; +} + +BOOL SwRTFWriter::OutBreaks( const SfxItemSet& rSet ) +{ + // dann nie Seitenumbrueche ausgeben + BOOL bPgDscWrite = FALSE; + + if( !bOutOutlineOnly && bOutPageAttr && !bIgnoreNextPgBreak) + { + const SfxPoolItem *pItem; + if( SFX_ITEM_SET == rSet.GetItemState( RES_PAGEDESC, TRUE, &pItem ) + && ((SwFmtPageDesc*)pItem)->GetPageDesc() ) + { + const SwFmtPageDesc& rPgDsc = *(SwFmtPageDesc*)pItem; + for( USHORT nPos = pDoc->GetPageDescCnt(); nPos; ) + if( &const_cast<const SwDoc *>(pDoc) + ->GetPageDesc( --nPos ) == rPgDsc.GetPageDesc() ) + { + pAktPageDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc(); + // FALSE wegen schliessender Klammer !! + OutComment( *this, OOO_STRING_SVTOOLS_RTF_PGDSCNO, FALSE ); + OutULong( nPos ) << '}'; + + // nicht weiter, in Styles gibts keine SectionControls !! + if( !bOutStyleTab ) + OutRTFPageDescription( *rPgDsc.GetPageDesc(), + TRUE, TRUE ); + bPgDscWrite = TRUE; + break; + } + } + else if( SFX_ITEM_SET == rSet.GetItemState( RES_BREAK, TRUE, &pItem ) ) + { + const SvxFmtBreakItem &rBreak = *(SvxFmtBreakItem*)pItem; + if( bWriteHelpFmt ) + { + if( SVX_BREAK_PAGE_BEFORE == rBreak.GetBreak() || + SVX_BREAK_PAGE_AFTER == rBreak.GetBreak() || + SVX_BREAK_PAGE_BOTH == rBreak.GetBreak() ) + { + bOutFmtAttr = true; + Strm() << OOO_STRING_SVTOOLS_RTF_PAGE; + } + } + else + { + switch( rBreak.GetBreak() ) + { + case SVX_BREAK_COLUMN_BEFORE: + case SVX_BREAK_COLUMN_AFTER: + case SVX_BREAK_COLUMN_BOTH: + break; + case SVX_BREAK_PAGE_BEFORE: + bOutFmtAttr = true; + Strm() << OOO_STRING_SVTOOLS_RTF_PAGE; + break; + case SVX_BREAK_PAGE_AFTER: + OutComment(*this, OOO_STRING_SVTOOLS_RTF_PGBRK, false) << "0}"; + break; + case SVX_BREAK_PAGE_BOTH: + OutComment(*this, OOO_STRING_SVTOOLS_RTF_PGBRK, false) << "1}"; + break; + default: + break; + } + } + } + } + bIgnoreNextPgBreak = false; + return bPgDscWrite; +} + + +void SwRTFWriter::CheckEndNodeForSection( const SwNode& rNd ) +{ + const SwSectionNode* pSectNd = rNd.StartOfSectionNode()->GetSectionNode(); + if( pSectNd /*&& CONTENT_SECTION == pSectNd->GetSection().GetType()*/ ) + { + const SwSectionFmt* pSectFmt = pSectNd->GetSection().GetFmt(); + + // diese Section hatte den akt. Abschnitt bestimmt + // wer bestimmt den nachsten?? + SwNodeIndex aIdx( rNd, 1 ); + pSectNd = aIdx.GetNode().GetSectionNode(); + if( !( ( pSectNd || (aIdx.GetNode().IsEndNode() && + 0 != ( pSectNd = aIdx.GetNode().StartOfSectionNode()->GetSectionNode() )) ) + /*&& CONTENT_SECTION == pSectNd->GetSection().GetType()*/ )) + { + // wer bestimmt denn nun den neuen Abschnitt? + // PageDesc oder eine uebergeordnete Section? + SwSection* pParent = pSectFmt->GetParentSection(); +// while( pParent /*&& CONTENT_SECTION != pParent->GetType()*/ ) +// pParent = pParent->GetParent(); + + if( pParent /*&& CONTENT_SECTION == pParent->GetType()*/ ) + OutRTF_SwSectionNode( *this, *pParent-> + GetFmt()->GetSectionNode( TRUE ) ); + else + { + if (! bOutPageDesc) + { + Strm() << OOO_STRING_SVTOOLS_RTF_SECT << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE; + OutRTFPageDescription( ( pAktPageDesc + ? *pAktPageDesc + : const_cast<const SwDoc *>(pDoc) + ->GetPageDesc(0) ), + FALSE, TRUE ); + Strm() << SwRTFWriter::sNewLine; + } + } + } + // else + // weiter machen, der naechste definiert den neuen Abschnitt + } +} + +// Struktur speichert die aktuellen Daten des Writers zwischen, um +// einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer +RTFSaveData::RTFSaveData( SwRTFWriter& rWriter, ULONG nStt, ULONG nEnd ) + : rWrt( rWriter ), + pOldPam( rWrt.pCurPam ), pOldEnd( rWrt.GetEndPaM() ), + pOldFlyFmt( rWrt.pFlyFmt ), pOldPageDesc( rWrt.pAktPageDesc ), + pOldAttrSet( rWrt.GetAttrSet() ) +{ + bOldWriteAll = rWrt.bWriteAll; + bOldOutTable = rWrt.bOutTable; + bOldOutPageAttr = rWrt.bOutPageAttr; + bOldAutoAttrSet = rWrt.bAutoAttrSet; + bOldOutSection = rWrt.bOutSection; + + rWrt.pCurPam = rWrt.NewSwPaM( *rWrt.pDoc, nStt, nEnd ); + + // Tabelle in Sonderbereichen erkennen + if( nStt != rWrt.pCurPam->GetMark()->nNode.GetIndex() && + rWrt.pDoc->GetNodes()[ nStt ]->IsTableNode() ) + rWrt.pCurPam->GetMark()->nNode = nStt; + + rWrt.SetEndPaM( rWrt.pCurPam ); + rWrt.pCurPam->Exchange( ); + rWrt.bWriteAll = TRUE; + rWrt.bOutTable = FALSE; + rWrt.bOutPageAttr = FALSE; + rWrt.SetAttrSet( 0 ); + rWrt.bAutoAttrSet = FALSE; + rWrt.bOutSection = FALSE; +} + + +RTFSaveData::~RTFSaveData() +{ + delete rWrt.pCurPam; // Pam wieder loeschen + + rWrt.pCurPam = pOldPam; + rWrt.SetEndPaM( pOldEnd ); + rWrt.bWriteAll = bOldWriteAll; + rWrt.bOutTable = bOldOutTable; + rWrt.pFlyFmt = pOldFlyFmt; + rWrt.pAktPageDesc = pOldPageDesc; + rWrt.SetAttrSet( pOldAttrSet ); + rWrt.bAutoAttrSet = bOldAutoAttrSet; + rWrt.bOutPageAttr = bOldOutPageAttr; + rWrt.bOutSection = bOldOutSection; +} + +extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportRTF( const String& rFltName, const String& rBaseURL, WriterRef& xRet ) +{ + xRet = new SwRTFWriter( rFltName, rBaseURL ); +} + +short SwRTFWriter::GetCurrentPageDirection() const +{ + const SwFrmFmt &rFmt = pAktPageDesc + ? pAktPageDesc->GetMaster() + : const_cast<const SwDoc *>(pDoc) + ->GetPageDesc(0).GetMaster(); + const SvxFrameDirectionItem* pItem = &rFmt.GetFrmDir(); + + if (!pItem) + { + pItem = (const SvxFrameDirectionItem*) + &pDoc->GetAttrPool().GetDefaultItem(RES_FRAMEDIR); + } + return pItem->GetValue(); +} + +short SwRTFWriter::TrueFrameDirection(const SwFrmFmt &rFlyFmt) const +{ + const SwFrmFmt *pFlyFmt2 = &rFlyFmt; + const SvxFrameDirectionItem* pItem = 0; + while (pFlyFmt2) + { + pItem = &pFlyFmt2->GetFrmDir(); + if (FRMDIR_ENVIRONMENT == pItem->GetValue()) + { + pItem = 0; + const SwFmtAnchor* pAnchor = &pFlyFmt2->GetAnchor(); + if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) && + pAnchor->GetCntntAnchor() ) + { + pFlyFmt2 = pAnchor->GetCntntAnchor()->nNode. + GetNode().GetFlyFmt(); + } + else + pFlyFmt2 = 0; + } + else + pFlyFmt2 = 0; + } + + short nRet; + if (pItem) + nRet = pItem->GetValue(); + else + nRet = GetCurrentPageDirection(); + + ASSERT(nRet != FRMDIR_ENVIRONMENT, "leaving with environment direction"); + return nRet; +} + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ |