merge the formfield patch from ooo-build
[ooovba.git] / sw / source / filter / rtf / wrtrtf.cxx
blob7f2179d3ec974d785d55eb529e42912278dabe68
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: wrtrtf.cxx,v $
10 * $Revision: 1.42.208.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <stdlib.h>
34 #include <hintids.hxx>
36 #include <comphelper/string.hxx>
37 #include <tools/stream.hxx>
38 #include <tools/datetime.hxx>
39 #include <vcl/fontcvt.hxx>
40 #include <rtl/tencinfo.h>
41 #include <svtools/rtfkeywd.hxx>
42 #include <svtools/rtfout.hxx>
43 #include <svx/paperinf.hxx>
44 #include <svx/fontitem.hxx>
45 #include <svx/shaditem.hxx>
46 #include <svx/brshitem.hxx>
47 #include <svx/colritem.hxx>
48 #include <svx/boxitem.hxx>
49 #ifndef _SVX_TSTPITEM_HXX //autogen
50 #include <svx/tstpitem.hxx>
51 #endif
52 #include <svx/ulspitem.hxx>
53 #include <svx/lrspitem.hxx>
54 #include <svx/frmdiritem.hxx>
55 #include <svx/udlnitem.hxx>
56 #include <fmtpdsc.hxx>
57 #include <fmtcntnt.hxx>
58 #include <fmtfsize.hxx>
59 #include <fmthdft.hxx>
60 #include <frmatr.hxx>
61 #include <fmtanchr.hxx>
62 #include <docary.hxx>
63 #include <pam.hxx>
64 #include <doc.hxx>
65 #include <paratr.hxx>
66 #include <fldbas.hxx>
67 #include <ndtxt.hxx>
68 #include <wrtrtf.hxx>
69 #include <flypos.hxx>
70 #include <IMark.hxx>
71 #include <pagedesc.hxx> // fuer SwPageDesc...
72 #include <ftninfo.hxx>
73 #include <charfmt.hxx>
74 #include <SwStyleNameMapper.hxx>
75 #include <section.hxx>
76 #include <swtable.hxx> // fuer SwPageDesc ...
77 #include <swmodule.hxx>
78 #include <swerror.h>
79 #include <mdiexp.hxx> // ...Percent()
80 #ifndef _STATSTR_HRC
81 #include <statstr.hrc> // ResId fuer Statusleiste
82 #endif
83 #include <docsh.hxx>
85 #include <com/sun/star/document/XDocumentProperties.hpp>
86 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
88 #if defined(UNX)
89 const sal_Char SwRTFWriter::sNewLine = '\012';
90 #else
91 const sal_Char __FAR_DATA SwRTFWriter::sNewLine[] = "\015\012";
92 #endif
96 SV_DECL_VARARR( RTFColorTbl, Color, 5, 8 )
97 SV_IMPL_VARARR( RTFColorTbl, Color )
100 SwRTFWriter::SwRTFWriter( const String& rFltName, const String & rBaseURL ) :
101 eDefaultEncoding(
102 rtl_getTextEncodingFromWindowsCharset(
103 sw::ms::rtl_TextEncodingToWinCharset(DEF_ENCODING))),
104 eCurrentEncoding(eDefaultEncoding)
106 SetBaseURL( rBaseURL );
107 // schreibe Win-RTF-HelpFileFmt
108 bWriteHelpFmt = 'W' == rFltName.GetChar( 0 );
109 // schreibe nur Gliederungs Absaetze
110 bOutOutlineOnly = 'O' == rFltName.GetChar( 0 );
111 // enable non-standard tags for cut and paste
112 bNonStandard = '\0' == rFltName.GetChar( 0 );
116 SwRTFWriter::~SwRTFWriter()
120 ULONG SwRTFWriter::WriteStream()
122 bOutPageAttr = bOutSection = TRUE;
124 bOutStyleTab = bOutTable = bOutPageDesc = bOutPageDescTbl =
125 bAutoAttrSet = bOutListNumTxt = bOutLeftHeadFoot = bIgnoreNextPgBreak =
126 bTxtAttr = bAssociated = FALSE;
128 nCurScript = 1; // latin - ask the doc??
130 nCurRedline = USHRT_MAX;
131 if(pDoc->GetRedlineTbl().Count())
132 nCurRedline = 0;
135 pCurEndPosLst = 0;
136 nBkmkTabPos = -1;
137 pAktPageDesc = 0;
138 pAttrSet = 0;
139 pFlyFmt = 0; // kein FlyFrmFormat gesetzt
141 pColTbl = new RTFColorTbl;
142 pNumRuleTbl = 0;
144 BYTE nSz = (BYTE)Min( pDoc->GetSpzFrmFmts()->Count(), USHORT(255) );
145 SwPosFlyFrms aFlyPos( nSz, nSz );
147 //Abkuerzung wenn nur Gliederung ausgegeben werden soll, und keine
148 //Gliederungsabsaetze ausserhalb des Body stehen.
149 if ( bOutOutlineOnly &&
150 pDoc->GetNodes().GetOutLineNds().Count() &&
151 pDoc->GetNodes().GetOutLineNds()[0]->GetIndex() >
152 pDoc->GetNodes().GetEndOfExtras().GetIndex() )
154 nAktFlyPos = 0;
155 pFlyPos = 0;
156 MakeHeader();
158 const SwOutlineNodes &rOutLine = pDoc->GetNodes().GetOutLineNds();
159 for ( USHORT i = 0; i < rOutLine.Count(); ++i )
161 const SwNode *pNd = pDoc->GetNodes()[*rOutLine[i]];
162 ASSERT( pNd->IsCntntNode(), "Outlinenode and no CntNode!?" );
164 SwCntntNode* pCNd = (SwCntntNode*)pNd;
166 // erfrage den aktuellen PageDescriptor.
167 const SwPageDesc* pTmp = pCNd->GetSwAttrSet().GetPageDesc().GetPageDesc();
168 if( pTmp )
169 pAktPageDesc = pTmp;
170 pCurPam->GetPoint()->nContent.Assign( pCNd, 0 );
171 Out( aRTFNodeFnTab, *pCNd, *this );
174 else
176 long nMaxNode = pDoc->GetNodes().Count();
178 if( bShowProgress )
179 ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );
181 // Tabelle am Doc.-Anfang beachten
183 SwTableNode * pTNd = pCurPam->GetNode()->FindTableNode();
184 if( pTNd && bWriteAll )
186 // mit dem TabellenNode anfangen !!
187 pCurPam->GetPoint()->nNode = *pTNd;
189 if( bWriteOnlyFirstTable )
190 pCurPam->GetMark()->nNode = *pTNd->EndOfSectionNode();
194 // Tabelle fuer die freifliegenden Rahmen erzeugen, aber nur wenn
195 // das gesamte Dokument geschrieben wird
196 nAktFlyPos = 0;
197 pDoc->GetAllFlyFmts( aFlyPos, bWriteAll ? 0 : pOrigPam );
199 // sollten nur Rahmen vorhanden sein?
200 // (Moeglich, wenn eine Rahmen-Selektion ins Clipboard
201 // gestellt wurde)
202 if( bWriteAll &&
203 // keine Laenge
204 *pCurPam->GetPoint() == *pCurPam->GetMark() &&
205 // Rahmen vorhanden
206 pDoc->GetSpzFrmFmts()->Count() && !aFlyPos.Count() &&
207 // nur ein Node im Array
208 pDoc->GetNodes().GetEndOfExtras().GetIndex() + 3 ==
209 pDoc->GetNodes().GetEndOfContent().GetIndex() &&
210 // und genau der ist selektiert
211 pDoc->GetNodes().GetEndOfContent().GetIndex() - 1 ==
212 pCurPam->GetPoint()->nNode.GetIndex() )
214 // dann den Inhalt vom Rahmen ausgeben.
215 // dieser steht immer an Position 0 !!
216 SwFrmFmt* pFmt = (*pDoc->GetSpzFrmFmts())[ 0 ];
217 const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
218 if( pIdx )
220 SwPosFlyFrm* pFPos = new SwPosFlyFrm( pCurPam->GetPoint()->nNode,
221 pFmt, aFlyPos.Count() );
222 aFlyPos.Insert( pFPos );
226 pFlyPos = &aFlyPos;
228 // schreibe die StyleTabelle, allgemeine Angaben,Header/Footer/Footnotes
229 MakeHeader();
231 Out_SwDoc( pOrigPam );
233 if( bShowProgress )
234 ::EndProgress( pDoc->GetDocShell() );
237 Strm() << '}';
239 // loesche die Tabelle mit den freifliegenden Rahmen
240 for( USHORT i = aFlyPos.Count(); i > 0; )
241 delete aFlyPos[ --i ];
243 pFlyPos = 0;
244 delete pColTbl;
245 if( pNumRuleTbl )
247 // don't destroy the numrule pointers in the DTOR.
248 pNumRuleTbl->Remove( 0, pNumRuleTbl->Count() );
249 delete pNumRuleTbl;
251 delete pRedlAuthors;
253 // schreibe Win-RTF-HelpFileFmt
254 bOutOutlineOnly = bWriteHelpFmt = FALSE;
255 pAttrSet = 0;
257 return 0;
261 void SwRTFWriter::Out_SwDoc( SwPaM* pPam )
263 BOOL bSaveWriteAll = bWriteAll; // sichern
264 // suche die naechste Bookmark-Position aus der Bookmark-Tabelle
265 nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
267 // gebe alle Bereiche des Pams in das RTF-File aus.
268 do {
269 bWriteAll = bSaveWriteAll;
270 bFirstLine = TRUE;
272 // suche den ersten am Pam-auszugebenen FlyFrame
273 // fehlt noch:
275 while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode ||
276 (pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode &&
277 pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
279 SwNode& rNd = pCurPam->GetPoint()->nNode.GetNode();
281 if( &rNd == &pDoc->GetNodes().GetEndOfContent() )
282 break;
284 if( rNd.IsCntntNode() )
286 SwCntntNode& rCNd = (SwCntntNode&)rNd;
288 OutBreaks( rCNd.GetSwAttrSet() );
289 OutFlyFrm();
291 if( !bFirstLine )
292 pCurPam->GetPoint()->nContent.Assign( &rCNd, 0 );
294 if( !bOutOutlineOnly ||
295 //( rCNd.IsTxtNode() && NO_NUMBERING != //#outline level,removed by zhaojianwei
296 //((SwTxtNode&)rCNd).GetTxtColl()->GetOutlineLevel() ))
297 ( rCNd.IsTxtNode() && //->add by zhaojianwei
298 ((SwTxtNode&)rCNd).GetTxtColl()->IsAssignedToListLevelOfOutlineStyle()))//<-end,zhaojianwei
299 Out( aRTFNodeFnTab, rCNd, *this );
302 else if( !bOutOutlineOnly )
304 if (rNd.IsTableNode())
306 bool bAllOk = false;
307 if (const SwTableNode *pNd = rNd.GetTableNode())
309 if (const SwFrmFmt *pFmt = pNd->GetTable().GetFrmFmt())
311 OutBreaks(pFmt->GetAttrSet());
312 bAllOk = true;
314 OutRTF_SwTblNode(*this, *pNd);
316 ASSERT(bAllOk, "Unexpected missing properties from tables");
318 else if( rNd.IsSectionNode() )
320 OutBreaks( ((SwSectionNode&)rNd).GetSection().GetFmt()
321 ->GetAttrSet() );
322 OutRTF_SwSectionNode( *this, (SwSectionNode&)rNd );
324 else if( rNd.IsEndNode() )
325 CheckEndNodeForSection( rNd );
328 ULONG nPos = pCurPam->GetPoint()->nNode++; // Bewegen
330 if( bShowProgress )
331 ::SetProgressState( nPos, pDoc->GetDocShell() ); // Wie weit ?
333 /* sollen nur die Selectierten Bereiche gesichert werden, so
334 * duerfen nur die vollstaendigen Nodes gespeichert werde,
335 * d.H. der 1. und n. Node teilweise, der 2. bis n-1. Node
336 * vollstaendig. (vollstaendig heisst mit allen Formaten! )
338 bWriteAll = bSaveWriteAll ||
339 pCurPam->GetPoint()->nNode != pCurPam->GetMark()->nNode;
340 bFirstLine = FALSE;
342 } while( CopyNextPam( &pPam ) ); // bis alle PaM's bearbeitet
344 bWriteAll = bSaveWriteAll; // wieder auf alten Wert zurueck
348 // schreibe die StyleTabelle, algemeine Angaben,Header/Footer/Footnotes
351 void SwRTFWriter::MakeHeader()
353 // baue den Vorspann wie Header, ColorTbl, FontTbl
354 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_RTF << '1'
355 << OOO_STRING_SVTOOLS_RTF_ANSI;
356 if( bWriteAll )
358 Strm() << OOO_STRING_SVTOOLS_RTF_DEFF;
359 OutULong( GetId( (SvxFontItem&)pDoc->GetAttrPool().GetDefaultItem(
360 RES_CHRATR_FONT ) ));
362 // JP 13.02.2001 - if this not exist, MS don't understand our ansi
363 // characters (0x80-0xff).
364 Strm() << "\\adeflang1025";
366 OutRTFFontTab();
367 OutRTFColorTab();
368 OutRTFStyleTab();
369 OutRTFListTab();
370 OutRTFRevTab();
372 Strm() << SwRTFWriter::sNewLine; // ein Trenner
374 // wenn teilweise ausgegeben wird, die globalen Daten nicht speichern
375 if( !bWriteAll )
376 return;
378 // Ausgeben der Doc-Info/-Statistik
379 OutDocInfoStat();
381 // einige globale Daten Schreiben
382 { // Default-TabSize
383 const SvxTabStopItem& rTabs = (const SvxTabStopItem&)
384 pDoc->GetAttrPool().GetDefaultItem( RES_PARATR_TABSTOP );
385 Strm() << OOO_STRING_SVTOOLS_RTF_DEFTAB;
386 OutLong( rTabs[0].GetTabPos() );
387 if ( !pDoc->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) )
388 Strm() << OOO_STRING_SVTOOLS_RTF_LYTPRTMET;
391 // PageDescriptor ausgeben (??nur wenn das gesamte Dokument??)
392 OutPageDesc();
394 // gebe die Groesse und die Raender der Seite aus
395 if( pDoc->GetPageDescCnt() )
397 //JP 06.04.99: Bug 64361 - suche den ersten SwFmtPageDesc. Ist
398 // keiner gesetzt, so ist der Standard gueltig
399 const SwFmtPageDesc* pSttPgDsc = 0;
401 const SwNode& rSttNd = *pDoc->GetNodes()[
402 pDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 ];
403 const SfxItemSet* pSet = 0;
405 if( rSttNd.IsCntntNode() )
406 pSet = &rSttNd.GetCntntNode()->GetSwAttrSet();
407 else if( rSttNd.IsTableNode() )
408 pSet = &rSttNd.GetTableNode()->GetTable().
409 GetFrmFmt()->GetAttrSet();
410 else if( rSttNd.IsSectionNode() )
411 pSet = &rSttNd.GetSectionNode()->GetSection().
412 GetFmt()->GetAttrSet();
414 if( pSet )
416 USHORT nPosInDoc;
417 pSttPgDsc = (SwFmtPageDesc*)&pSet->Get( RES_PAGEDESC );
418 if( !pSttPgDsc->GetPageDesc() )
419 pSttPgDsc = 0;
420 else if( pDoc->FindPageDescByName( pSttPgDsc->
421 GetPageDesc()->GetName(), &nPosInDoc ))
423 // FALSE wegen schliessender Klammer !!
424 OutComment( *this, OOO_STRING_SVTOOLS_RTF_PGDSCNO, FALSE );
425 OutULong( nPosInDoc ) << '}';
429 const SwPageDesc& rPageDesc = pSttPgDsc ? *pSttPgDsc->GetPageDesc()
430 : const_cast<const SwDoc *>(pDoc)->GetPageDesc( 0 );
431 const SwFrmFmt &rFmtPage = rPageDesc.GetMaster();
434 if( rPageDesc.GetLandscape() )
435 Strm() << OOO_STRING_SVTOOLS_RTF_LANDSCAPE;
437 const SwFmtFrmSize& rSz = rFmtPage.GetFrmSize();
438 // Clipboard-Dokument wird immer ohne Drucker angelegt, so ist
439 // der Std.PageDesc immer aug LONG_MAX !! Mappe dann auf DIN A4
440 if( LONG_MAX == rSz.GetHeight() || LONG_MAX == rSz.GetWidth() )
442 Strm() << OOO_STRING_SVTOOLS_RTF_PAPERH;
443 Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
444 OutULong( a4.Height() ) << OOO_STRING_SVTOOLS_RTF_PAPERW;
445 OutULong( a4.Width() );
447 else
449 Strm() << OOO_STRING_SVTOOLS_RTF_PAPERH;
450 OutULong( rSz.GetHeight() ) << OOO_STRING_SVTOOLS_RTF_PAPERW;
451 OutULong( rSz.GetWidth() );
456 const SvxLRSpaceItem& rLR = rFmtPage.GetLRSpace();
457 Strm() << OOO_STRING_SVTOOLS_RTF_MARGL;
458 OutLong( rLR.GetLeft() ) << OOO_STRING_SVTOOLS_RTF_MARGR;
459 OutLong( rLR.GetRight() );
463 const SvxULSpaceItem& rUL = rFmtPage.GetULSpace();
464 Strm() << OOO_STRING_SVTOOLS_RTF_MARGT;
465 OutLong( rUL.GetUpper() ) << OOO_STRING_SVTOOLS_RTF_MARGB;
466 OutLong( rUL.GetLower() );
469 Strm() << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE;
470 OutRTFPageDescription( rPageDesc, FALSE, TRUE ); // Changed bCheckForFirstPage to TRUE so headers
471 // following title page are correctly added - i13107
472 if( pSttPgDsc )
474 bIgnoreNextPgBreak = TRUE;
475 pAktPageDesc = &rPageDesc;
481 // schreibe die Fussnoten- und Endnoten-Info raus
482 const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
484 const char* pOut = FTNPOS_CHAPTER == rFtnInfo.ePos
485 ? OOO_STRING_SVTOOLS_RTF_ENDDOC
486 : OOO_STRING_SVTOOLS_RTF_FTNBJ;
487 Strm() << pOut << OOO_STRING_SVTOOLS_RTF_FTNSTART;
488 OutLong( rFtnInfo.nFtnOffset + 1 );
490 switch( rFtnInfo.eNum )
492 case FTNNUM_PAGE: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTPG; break;
493 case FTNNUM_DOC: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTCONT; break;
494 // case FTNNUM_CHAPTER:
495 default: pOut = OOO_STRING_SVTOOLS_RTF_FTNRESTART; break;
497 Strm() << pOut;
499 switch( rFtnInfo.aFmt.GetNumberingType() )
501 case SVX_NUM_CHARS_LOWER_LETTER:
502 case SVX_NUM_CHARS_LOWER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_FTNNALC; break;
503 case SVX_NUM_CHARS_UPPER_LETTER:
504 case SVX_NUM_CHARS_UPPER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_FTNNAUC; break;
505 case SVX_NUM_ROMAN_LOWER: pOut = OOO_STRING_SVTOOLS_RTF_FTNNRLC; break;
506 case SVX_NUM_ROMAN_UPPER: pOut = OOO_STRING_SVTOOLS_RTF_FTNNRUC; break;
507 case SVX_NUM_CHAR_SPECIAL: pOut = OOO_STRING_SVTOOLS_RTF_FTNNCHI; break;
508 // case SVX_NUM_ARABIC:
509 default: pOut = OOO_STRING_SVTOOLS_RTF_FTNNAR; break;
511 Strm() << pOut;
514 const SwEndNoteInfo& rEndNoteInfo = pDoc->GetEndNoteInfo();
516 Strm() << OOO_STRING_SVTOOLS_RTF_AENDDOC << OOO_STRING_SVTOOLS_RTF_AFTNRSTCONT
517 << OOO_STRING_SVTOOLS_RTF_AFTNSTART;
518 OutLong( rEndNoteInfo.nFtnOffset + 1 );
520 switch( rEndNoteInfo.aFmt.GetNumberingType() )
522 case SVX_NUM_CHARS_LOWER_LETTER:
523 case SVX_NUM_CHARS_LOWER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNALC; break;
524 case SVX_NUM_CHARS_UPPER_LETTER:
525 case SVX_NUM_CHARS_UPPER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAUC; break;
526 case SVX_NUM_ROMAN_LOWER: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRLC; break;
527 case SVX_NUM_ROMAN_UPPER: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRUC; break;
528 case SVX_NUM_CHAR_SPECIAL: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNCHI; break;
529 // case SVX_NUM_ARABIC:
530 default: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAR; break;
532 Strm() << pOut;
535 if( pDoc->_GetDBDesc().sDataSource.getLength() )
537 // stelle erstmal fest, ob ueberhaupt Datenbankfelder benutzt werden!
538 const SwFldTypes* pTypes = pDoc->GetFldTypes();
539 for( USHORT nCnt = pTypes->Count(); nCnt >= INIT_FLDTYPES; )
540 if( RES_DBFLD == (*pTypes)[ --nCnt ]->Which() &&
541 (*pTypes)[ nCnt ]->GetDepends() )
543 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_FIELD;
544 OutComment( *this, OOO_STRING_SVTOOLS_RTF_FLDINST ) << " DATA ";
545 SwDBData aData = pDoc->GetDBData();
546 String sOut(aData.sDataSource);
547 sOut += DB_DELIM;
548 sOut += (String)aData.sCommand;
549 RTFOutFuncs::Out_String( Strm(), sOut,
550 eDefaultEncoding, bWriteHelpFmt );
551 Strm() << "}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << " }}";
552 break;
556 pAttrSet = 0;
558 Strm() << SwRTFWriter::sNewLine; // ein Trenner
561 void SwRTFWriter::OutInfoDateTime( const sal_Char* i_pStr,
562 const util::DateTime& i_rDT )
564 Strm() << '{' << i_pStr << OOO_STRING_SVTOOLS_RTF_YR;
565 OutLong( Strm(), i_rDT.Year ) << OOO_STRING_SVTOOLS_RTF_MO;
566 OutLong( Strm(), i_rDT.Month ) << OOO_STRING_SVTOOLS_RTF_DY;
567 OutLong( Strm(), i_rDT.Day ) << OOO_STRING_SVTOOLS_RTF_HR;
568 OutLong( Strm(), i_rDT.Hours ) << OOO_STRING_SVTOOLS_RTF_MIN;
569 OutLong( Strm(), i_rDT.Minutes ) << '}';
572 bool CharsetSufficient(const String &rString, rtl_TextEncoding eChrSet)
574 const sal_uInt32 nFlags =
575 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
576 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR;
577 rtl::OString sDummy;
578 rtl::OUString sStr(rString);
579 return sStr.convertToString(&sDummy, eChrSet, nFlags);
582 void SwRTFWriter::OutUnicodeSafeRecord(const sal_Char *pToken,
583 const String &rContent)
585 if (rContent.Len())
587 bool bNeedUnicodeWrapper = !CharsetSufficient(rContent, eDefaultEncoding);
589 if (bNeedUnicodeWrapper)
590 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_UPR;
592 Strm() << '{' << pToken << ' ';
593 OutRTF_AsByteString(*this, rContent, eDefaultEncoding);
594 Strm() << '}';
596 if (bNeedUnicodeWrapper)
598 OutComment(*this, OOO_STRING_SVTOOLS_RTF_UD);
599 Strm() << '{' << pToken << ' ';
600 RTFOutFuncs::Out_String(Strm(), rContent, eDefaultEncoding,
601 bWriteHelpFmt);
602 Strm() << "}}}";
608 void SwRTFWriter::OutDocInfoStat()
610 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_INFO;
612 SwDocShell *pDocShell(pDoc->GetDocShell());
613 uno::Reference<document::XDocumentProperties> xDocProps;
614 if (pDocShell) {
615 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
616 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
617 xDocProps.set(xDPS->getDocumentProperties());
620 // may be null (in case of copying)
621 if (xDocProps.is())
623 OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle());
624 OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_SUBJECT, xDocProps->getSubject());
626 OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_KEYWORDS,
627 ::comphelper::string::convertCommaSeparated(xDocProps->getKeywords()));
628 OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_DOCCOMM, xDocProps->getDescription());
630 OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getAuthor() );
631 OutInfoDateTime(OOO_STRING_SVTOOLS_RTF_CREATIM, xDocProps->getCreationDate());
633 OutUnicodeSafeRecord(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getModifiedBy() );
634 OutInfoDateTime(OOO_STRING_SVTOOLS_RTF_REVTIM, xDocProps->getModificationDate());
636 OutInfoDateTime(OOO_STRING_SVTOOLS_RTF_PRINTIM, xDocProps->getPrintDate());
640 // fuer interne Zwecke - Versionsnummer rausschreiben
641 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_COMMENT << " StarWriter}{" << OOO_STRING_SVTOOLS_RTF_VERN;
642 OutLong( Strm(), SUPD*10 ) << '}';
644 Strm() << '}';
647 static void InsColor( RTFColorTbl& rTbl, const Color& rCol )
649 USHORT n;
650 for( n = 0; n < rTbl.Count(); ++n )
651 if( rTbl[n] == rCol )
652 return; // schon vorhanden, zurueck
654 n = COL_AUTO == rCol.GetColor() ? 0 : rTbl.Count();
655 rTbl.Insert( rCol, n );
658 static void InsColorLine( RTFColorTbl& rTbl, const SvxBoxItem& rBox )
660 const SvxBorderLine* pLine = 0;
662 if( rBox.GetTop() )
663 InsColor( rTbl, (pLine = rBox.GetTop())->GetColor() );
664 if( rBox.GetBottom() && pLine != rBox.GetBottom() )
665 InsColor( rTbl, (pLine = rBox.GetBottom())->GetColor() );
666 if( rBox.GetLeft() && pLine != rBox.GetLeft() )
667 InsColor( rTbl, (pLine = rBox.GetLeft())->GetColor() );
668 if( rBox.GetRight() && pLine != rBox.GetRight() )
669 InsColor( rTbl, rBox.GetRight()->GetColor() );
672 void SwRTFWriter::OutRTFColorTab()
674 ASSERT( pColTbl, "Wo ist meine Color-Tabelle?" );
676 // dann baue die ColorTabelle aus allen Attributen, die Colors
677 // enthalten und im Pool angemeldet sind auf.
678 USHORT n, nMaxItem;
679 const SfxItemPool& rPool = pDoc->GetAttrPool();
681 // das Charakter - Color Attribut
683 const SvxColorItem* pCol = (const SvxColorItem*)GetDfltAttr(
684 RES_CHRATR_COLOR );
685 InsColor( *pColTbl, pCol->GetValue() );
686 if( 0 != ( pCol = (const SvxColorItem*)rPool.GetPoolDefaultItem(
687 RES_CHRATR_COLOR ) ))
688 InsColor( *pColTbl, pCol->GetValue() );
689 nMaxItem = rPool.GetItemCount(RES_CHRATR_COLOR);
690 for( n = 0; n < nMaxItem; ++n )
692 if( 0 != (pCol = (const SvxColorItem*)rPool.GetItem(
693 RES_CHRATR_COLOR, n ) ) )
694 InsColor( *pColTbl, pCol->GetValue() );
697 const SvxUnderlineItem* pUnder = (const SvxUnderlineItem*)GetDfltAttr( RES_CHRATR_UNDERLINE );
698 InsColor( *pColTbl, pUnder->GetColor() );
699 nMaxItem = rPool.GetItemCount(RES_CHRATR_UNDERLINE);
700 for( n = 0; n < nMaxItem;n++)
702 if( 0 != (pUnder = (const SvxUnderlineItem*)rPool.GetItem( RES_CHRATR_UNDERLINE, n ) ) )
703 InsColor( *pColTbl, pUnder->GetColor() );
707 const SvxOverlineItem* pOver = (const SvxOverlineItem*)GetDfltAttr( RES_CHRATR_OVERLINE );
708 InsColor( *pColTbl, pOver->GetColor() );
709 nMaxItem = rPool.GetItemCount(RES_CHRATR_OVERLINE);
710 for( n = 0; n < nMaxItem;n++)
712 if( 0 != (pOver = (const SvxOverlineItem*)rPool.GetItem( RES_CHRATR_OVERLINE, n ) ) )
713 InsColor( *pColTbl, pOver->GetColor() );
719 // das Frame Hintergrund - Attribut
720 static const USHORT aBrushIds[] = {
721 RES_BACKGROUND, RES_CHRATR_BACKGROUND, 0 };
723 for( const USHORT* pIds = aBrushIds; *pIds; ++pIds )
725 const SvxBrushItem* pBkgrd = (const SvxBrushItem*)GetDfltAttr( *pIds );
726 InsColor( *pColTbl, pBkgrd->GetColor() );
727 if( 0 != ( pBkgrd = (const SvxBrushItem*)rPool.GetPoolDefaultItem(
728 *pIds ) ))
730 InsColor( *pColTbl, pBkgrd->GetColor() );
732 nMaxItem = rPool.GetItemCount( *pIds );
733 for( n = 0; n < nMaxItem; ++n )
734 if( 0 != (pBkgrd = (const SvxBrushItem*)rPool.GetItem(
735 *pIds , n ) ))
737 InsColor( *pColTbl, pBkgrd->GetColor() );
741 // das Frame Schatten - Attribut
743 const SvxShadowItem* pShadow = (const SvxShadowItem*)GetDfltAttr(
744 RES_SHADOW );
745 InsColor( *pColTbl, pShadow->GetColor() );
746 if( 0 != ( pShadow = (const SvxShadowItem*)rPool.GetPoolDefaultItem(
747 RES_SHADOW ) ))
749 InsColor( *pColTbl, pShadow->GetColor() );
751 nMaxItem = rPool.GetItemCount(RES_SHADOW);
752 for( n = 0; n < nMaxItem; ++n )
753 if( 0 != (pShadow = (const SvxShadowItem*)rPool.GetItem(
754 RES_SHADOW, n ) ) )
756 InsColor( *pColTbl, pShadow->GetColor() );
760 // das Frame Umrandungs - Attribut
762 // Box muesste noch gemacht werden, aber default nie eine Line gesetzt!
763 const SvxBoxItem* pBox;
764 if( 0 != ( pBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
765 RES_BOX ) ))
766 InsColorLine( *pColTbl, *pBox );
767 nMaxItem = rPool.GetItemCount(RES_BOX);
768 for( n = 0; n < nMaxItem; ++n )
769 if( 0 != (pBox = (const SvxBoxItem*)rPool.GetItem( RES_BOX, n ) ))
770 InsColorLine( *pColTbl, *pBox );
773 // und raus damit
774 Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_COLORTBL;
776 for( n = 0; n < pColTbl->Count(); n++ )
778 const Color& rCol = (*pColTbl)[ n ];
779 if( n || COL_AUTO != rCol.GetColor() )
781 Strm() << OOO_STRING_SVTOOLS_RTF_RED;
782 OutULong( rCol.GetRed() ) << OOO_STRING_SVTOOLS_RTF_GREEN;
783 OutULong( rCol.GetGreen() ) << OOO_STRING_SVTOOLS_RTF_BLUE;
784 OutULong( rCol.GetBlue() );
786 Strm() << ';';
788 Strm() << '}';
791 bool FontCharsetSufficient(const String &rFntNm, const String &rAltNm,
792 rtl_TextEncoding eChrSet)
794 bool bRet = CharsetSufficient(rFntNm, eChrSet);
795 if (bRet)
796 bRet = CharsetSufficient(rAltNm, eChrSet);
797 return bRet;
800 static void _OutFont( SwRTFWriter& rWrt, const SvxFontItem& rFont, USHORT nNo )
802 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_F;
804 const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL;
805 switch (rFont.GetFamily())
807 case FAMILY_ROMAN:
808 pStr = OOO_STRING_SVTOOLS_RTF_FROMAN;
809 break;
810 case FAMILY_SWISS:
811 pStr = OOO_STRING_SVTOOLS_RTF_FSWISS;
812 break;
813 case FAMILY_MODERN:
814 pStr = OOO_STRING_SVTOOLS_RTF_FMODERN;
815 break;
816 case FAMILY_SCRIPT:
817 pStr = OOO_STRING_SVTOOLS_RTF_FSCRIPT;
818 break;
819 case FAMILY_DECORATIVE:
820 pStr = OOO_STRING_SVTOOLS_RTF_FDECOR;
821 break;
822 default:
823 break;
825 rWrt.OutULong(nNo) << pStr << OOO_STRING_SVTOOLS_RTF_FPRQ;
827 USHORT nVal = 0;
828 switch (rFont.GetPitch())
830 case PITCH_FIXED:
831 nVal = 1;
832 break;
833 case PITCH_VARIABLE:
834 nVal = 2;
835 break;
836 default:
837 nVal = 0;
838 break;
840 rWrt.OutULong(nVal);
842 sw::util::FontMapExport aRes(rFont.GetFamilyName());
845 #i10538#
846 In rtf the fontname is in the fontcharset, so if that isn't possible
847 then bump the charset up to unicode
849 sal_uInt8 nChSet = 0;
850 rtl_TextEncoding eChrSet = rFont.GetCharSet();
851 nChSet = sw::ms::rtl_TextEncodingToWinCharset(eChrSet);
852 eChrSet = rtl_getTextEncodingFromWindowsCharset(nChSet);
853 if (!FontCharsetSufficient(aRes.msPrimary, aRes.msSecondary, eChrSet))
855 eChrSet = RTL_TEXTENCODING_UNICODE;
856 nChSet = sw::ms::rtl_TextEncodingToWinCharset(eChrSet);
857 eChrSet = rtl_getTextEncodingFromWindowsCharset(nChSet);
860 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FCHARSET;
861 rWrt.OutULong( nChSet );
862 rWrt.Strm() << ' ';
863 if (aRes.HasDistinctSecondary())
865 RTFOutFuncs::Out_Fontname(rWrt.Strm(), aRes.msPrimary, eChrSet,
866 rWrt.bWriteHelpFmt);
867 OutComment(rWrt, OOO_STRING_SVTOOLS_RTF_FALT) << ' ';
868 RTFOutFuncs::Out_Fontname(rWrt.Strm(), aRes.msSecondary, eChrSet,
869 rWrt.bWriteHelpFmt) << '}';
871 else
873 RTFOutFuncs::Out_Fontname(rWrt.Strm(), aRes.msPrimary, eChrSet,
874 rWrt.bWriteHelpFmt);
876 rWrt.Strm() << ";}";
879 void SwRTFWriter::OutRTFFontTab()
881 USHORT n = 0;
882 const SfxItemPool& rPool = pDoc->GetAttrPool();
883 const SvxFontItem* pFont = (const SvxFontItem*)GetDfltAttr(RES_CHRATR_FONT);
885 Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_FONTTBL;
886 _OutFont( *this, *pFont, n++ );
888 pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem(RES_CHRATR_FONT);
889 if (pFont)
890 _OutFont(*this, *pFont, n++);
892 PutNumFmtFontsInAttrPool();
893 PutCJKandCTLFontsInAttrPool();
895 USHORT nMaxItem = rPool.GetItemCount(RES_CHRATR_FONT);
896 for (USHORT nGet = 0; nGet < nMaxItem; ++nGet)
898 pFont = (const SvxFontItem*)rPool.GetItem(RES_CHRATR_FONT, nGet);
899 if (pFont)
900 _OutFont(*this, *pFont, n++);
903 Strm() << '}';
906 void RTF_WrtRedlineAuthor::Write(Writer &rWrt)
908 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
910 rRTFWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_REVTBL << ' ';
911 typedef std::vector<String>::iterator myiter;
913 for(std::vector<String>::iterator aIter = maAuthors.begin(); aIter != maAuthors.end(); ++aIter)
915 rRTFWrt.Strm() << '{';
916 // rWrt.bWriteHelpFmt
917 RTFOutFuncs::Out_String( rRTFWrt.Strm(), *aIter, rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt ) << ";}";
919 rRTFWrt.Strm() << '}' << SwRTFWriter::sNewLine;
922 bool SwRTFWriter::OutRTFRevTab()
924 // Writes the revision author table
925 int nRevAuthors = pDoc->GetRedlineTbl().Count();
927 pRedlAuthors = new RTF_WrtRedlineAuthor;
928 // RTF always seems to use Unknown as the default first entry
929 String sUnknown(RTL_CONSTASCII_STRINGPARAM("Unknown"));
930 pRedlAuthors->AddName(sUnknown);
932 if (nRevAuthors < 1)
933 return false;
935 // pull out all the redlines and make a vector of all the author names
936 for( USHORT i = 0; i < pDoc->GetRedlineTbl().Count(); ++i )
938 const SwRedline* pRedl = pDoc->GetRedlineTbl()[ i ];
939 const String sAuthor = SW_MOD()->GetRedlineAuthor( pRedl->GetAuthor() );
940 pRedlAuthors->AddName(sAuthor);
943 pRedlAuthors->Write(*this);
944 return true;
947 //Takashi Ono for CJK
948 const rtl::OUString SwRTFWriter::XlateFmtName( const rtl::OUString &rName, SwGetPoolIdFromName eFlags )
950 #define RES_NONE RES_POOLCOLL_DOC_END
952 static const RES_POOL_COLLFMT_TYPE aArr[]={
953 RES_POOLCOLL_STANDARD, RES_POOLCOLL_HEADLINE1, RES_POOLCOLL_HEADLINE2,
954 RES_POOLCOLL_HEADLINE3, RES_POOLCOLL_HEADLINE4, RES_POOLCOLL_HEADLINE5,
955 RES_POOLCOLL_HEADLINE6, RES_POOLCOLL_HEADLINE7, RES_POOLCOLL_HEADLINE8,
956 RES_POOLCOLL_HEADLINE9,
958 RES_POOLCOLL_TOX_IDX1, RES_POOLCOLL_TOX_IDX2, RES_POOLCOLL_TOX_IDX3,
959 RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
960 RES_POOLCOLL_TOX_CNTNT1,
962 RES_POOLCOLL_TOX_CNTNT2, RES_POOLCOLL_TOX_CNTNT3, RES_POOLCOLL_TOX_CNTNT4,
963 RES_POOLCOLL_TOX_CNTNT5, RES_POOLCOLL_TOX_CNTNT6, RES_POOLCOLL_TOX_CNTNT7,
964 RES_POOLCOLL_TOX_CNTNT8, RES_POOLCOLL_TOX_CNTNT9,
965 RES_POOLCOLL_TEXT_IDENT, RES_POOLCOLL_FOOTNOTE,
967 RES_NONE, RES_POOLCOLL_HEADER, RES_POOLCOLL_FOOTER, RES_POOLCOLL_TOX_IDXH,
968 RES_POOLCOLL_LABEL, RES_POOLCOLL_TOX_ILLUSH, RES_POOLCOLL_JAKETADRESS, RES_POOLCOLL_SENDADRESS,
969 RES_NONE, RES_NONE,
971 RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_ENDNOTE, RES_POOLCOLL_TOX_AUTHORITIESH, RES_NONE, RES_NONE,
972 RES_POOLCOLL_BUL_LEVEL1, RES_POOLCOLL_BUL_LEVEL1, RES_POOLCOLL_NUM_LEVEL1,
974 RES_POOLCOLL_BUL_LEVEL2, RES_POOLCOLL_BUL_LEVEL3, RES_POOLCOLL_BUL_LEVEL4, RES_POOLCOLL_BUL_LEVEL5,
975 RES_POOLCOLL_BUL_LEVEL2, RES_POOLCOLL_BUL_LEVEL3, RES_POOLCOLL_BUL_LEVEL4, RES_POOLCOLL_BUL_LEVEL5,
976 RES_POOLCOLL_NUM_LEVEL2, RES_POOLCOLL_NUM_LEVEL3, RES_POOLCOLL_NUM_LEVEL4, RES_POOLCOLL_NUM_LEVEL5,
978 RES_POOLCOLL_DOC_TITEL, RES_NONE, RES_POOLCOLL_SIGNATURE, RES_NONE,
979 RES_POOLCOLL_TEXT, RES_POOLCOLL_TEXT_MOVE, RES_NONE, RES_NONE,
981 RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_DOC_SUBTITEL };
983 static const sal_Char *stiName[] = {
984 "Normal", "heading 1", "heading 2",
985 "heading 3", "heading 4", "heading 5",
986 "heading 6", "heading 7", "heading 8",
987 "heading 9",
989 "index 1", "index 2", "index 3",
990 "index 4", "index 5", "index 6",
991 "index 7", "index 8", "index 9",
993 "toc 1", "toc 2", "toc 3",
994 "toc 4", "toc 5", "toc 6",
995 "toc 7", "toc 8", "toc 9",
996 "Normal Indent", "footnote text",
998 "annotation text", "header", "footer", "index heading",
999 "caption", "table of figures", "envelope address", "envelope return",
1000 "footnote reference", "annotation reference",
1002 "line number", "page number", "endnote reference", "endnote text", "table of authorities", "macro", "toa heading",
1003 "List", "List Bullet", "List Number",
1005 "List 2", "List 3", "List 4", "List 5",
1006 "List Bullet 2", "List Bullet 3", "List Bullet 4", "List Bullet 5",
1007 "List Number 2", "List Number 3", "List Number 4", "List Number 5",
1009 "Title", "Closing", "Signature", "Default Paragraph Font",
1010 "Body Text", "Body Text Indent", "List Continue",
1012 "List Continue 2", "List Continue 3", "List Continue 4", "List Continue 5", "Message Header", "Subtitle"};
1014 ASSERT( ( sizeof( aArr ) / sizeof( RES_POOL_COLLFMT_TYPE ) == 75 ),
1015 "Style-UEbersetzungstabelle hat falsche Groesse" );
1016 ASSERT( ( sizeof( stiName ) / sizeof( *stiName ) == 75 ),
1017 "Style-UEbersetzungstabelle hat falsche Groesse" );
1019 sal_uInt16 idcol = ::SwStyleNameMapper::GetPoolIdFromUIName( rName, eFlags );
1020 if (idcol==USHRT_MAX) //#i40770# user defined style names get lost
1021 return rName;
1023 for (size_t i = 0; i < sizeof( aArr ) / sizeof( *aArr ); i++)
1025 if ( idcol == aArr[i] )
1027 return rtl::OUString::createFromAscii(stiName[i]);
1030 return ::SwStyleNameMapper::GetProgName( idcol, String() );
1033 void SwRTFWriter::OutRTFStyleTab()
1035 USHORT n;
1037 // das 0-Style ist das Default, wird nie ausgegeben !!
1038 USHORT nArrLen = pDoc->GetTxtFmtColls()->Count();
1039 if( nArrLen <= 1 && pDoc->GetCharFmts()->Count() <= 1 )
1040 return;
1042 bOutStyleTab = TRUE;
1043 Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_STYLESHEET;
1045 // das Default-TextStyle wird nicht mit ausgegeben !!
1046 for( n = 1; n < nArrLen; ++n )
1048 const SwTxtFmtColl* pColl = (*pDoc->GetTxtFmtColls())[ n ];
1049 pAttrSet = &pColl->GetAttrSet();
1051 Strm() << '{';
1052 // gebe Attribute aus
1053 OutRTF_SwFmt( *this, *pColl );
1055 if( pColl->DerivedFrom() )
1056 // suche die Id vom "Parent" Format
1057 for( USHORT nBasedOn=1; nBasedOn < nArrLen; nBasedOn++)
1058 if( (*pDoc->GetTxtFmtColls())[ nBasedOn ] ==
1059 pColl->DerivedFrom() )
1061 // die Ableitung vom Format
1062 Strm() << OOO_STRING_SVTOOLS_RTF_SBASEDON;
1063 OutULong( nBasedOn );
1064 break;
1067 if( pColl == &pColl->GetNextTxtFmtColl() )
1069 Strm() << OOO_STRING_SVTOOLS_RTF_SNEXT;
1070 OutULong( n );
1072 else
1073 // suche die Id vom "Naechsten" Format
1074 for( USHORT nNext=1; nNext < nArrLen; nNext++)
1075 if( (*pDoc->GetTxtFmtColls())[ nNext ] ==
1076 &pColl->GetNextTxtFmtColl() )
1078 // die Ableitung vom Format
1079 Strm() << OOO_STRING_SVTOOLS_RTF_SNEXT;
1080 OutULong( nNext );
1081 break;
1084 //if( NO_NUMBERING != pColl->GetOutlineLevel() )//#outline level,zhaojianwei
1085 if(pColl->IsAssignedToListLevelOfOutlineStyle())//<-end,zhaojianwei
1087 Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_SOUTLVL;
1088 //OutULong( pColl->GetOutlineLevel() ) << '}';//#outline level,zhaojianwei
1089 OutULong( pColl->GetAssignedOutlineStyleLevel() ) << '}';//<-end,zhaojianwei
1092 Strm() << ' ';
1093 RTFOutFuncs::Out_String( Strm(), XlateFmtName( pColl->GetName(), nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ), eDefaultEncoding,
1094 bWriteHelpFmt ) << ";}" << SwRTFWriter::sNewLine;
1097 USHORT nChrArrLen = pDoc->GetCharFmts()->Count();
1098 for( n = 1; n < nChrArrLen; ++n )
1100 const SwCharFmt* pFmt = (*pDoc->GetCharFmts())[ n ];
1101 pAttrSet = &pFmt->GetAttrSet();
1103 Strm() << '{';
1104 // gebe Attribute aus
1105 OutRTF_SwFmt( *this, *pFmt );
1107 if( pFmt->DerivedFrom() )
1108 // suche die Id vom "Parent" Format
1109 for( USHORT nBasedOn=1; nBasedOn < nChrArrLen; nBasedOn++)
1110 if( (*pDoc->GetCharFmts())[ nBasedOn ] ==
1111 pFmt->DerivedFrom() )
1113 // die Ableitung vom Format
1114 Strm() << OOO_STRING_SVTOOLS_RTF_SBASEDON;
1115 OutULong( nArrLen + nBasedOn );
1116 break;
1119 Strm() << ' ';
1120 RTFOutFuncs::Out_String( Strm(), XlateFmtName( pFmt->GetName(), nsSwGetPoolIdFromName::GET_POOLID_CHRFMT ), eDefaultEncoding,
1121 bWriteHelpFmt ) << ";}" << SwRTFWriter::sNewLine;
1124 Strm() << '}';
1125 bOutStyleTab = FALSE;
1128 bool ExportAsInline(const SwFlyFrmFmt& rFlyFrmFmt)
1130 //if not an inline element (hack in our limitations here as to only
1131 //graphics like this!!!!
1132 return rFlyFrmFmt.GetAnchor().GetAnchorId() == FLY_IN_CNTNT;
1135 void SwRTFWriter::OutRTFFlyFrms(const SwFlyFrmFmt& rFlyFrmFmt)
1137 // ein FlyFrame wurde erkannt, gebe erstmal den aus
1139 // Hole vom Node und vom letzten Node die Position in der Section
1140 const SwFmtCntnt& rFlyCntnt = rFlyFrmFmt.GetCntnt();
1142 ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex()+1;
1143 ULONG nEnd = pDoc->GetNodes()[ nStt - 1 ]->EndOfSectionIndex();
1145 if( nStt >= nEnd ) // kein Bereich, also kein gueltiger Node
1146 return;
1148 if (!ExportAsInline(rFlyFrmFmt))
1149 Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN;
1150 //If we are only exporting an inline graphic/object then we
1151 //only need the its pFlyFmt for the duration of exporting it
1152 //for floating objects its a little more complex at the moment
1153 const SwFlyFrmFmt *pOldFlyFmt = pFlyFmt;
1154 pFlyFmt = &rFlyFrmFmt;
1157 RTFSaveData aSaveData( *this, nStt, nEnd );
1158 Out_SwDoc( pCurPam );
1161 if (!ExportAsInline(rFlyFrmFmt))
1162 Strm() << OOO_STRING_SVTOOLS_RTF_PARD << SwRTFWriter::sNewLine;
1163 //#i46098#: else
1164 pFlyFmt = pOldFlyFmt;
1169 void SwRTFWriter::OutRedline( xub_StrLen nCntntPos )
1171 const SwRedline *pCurRedline = 0;
1172 USHORT nCount = pDoc->GetRedlineTbl().Count();
1174 if (nCurRedline < nCount)
1176 pCurRedline = pDoc->GetRedlineTbl()[nCurRedline];
1177 if(pCurRedline)
1179 const SwPosition* pStartPos = pCurRedline->Start();
1180 const SwPosition* pEndPos = pStartPos == pCurRedline->GetPoint()
1181 ? pCurRedline->GetMark()
1182 : pCurRedline->GetPoint();
1184 USHORT nStart = pStartPos->nContent.GetIndex();
1185 USHORT nEnd = pEndPos->nContent.GetIndex();
1187 ULONG nCurPam = pCurPam->GetPoint()->nNode.GetIndex();
1188 ULONG nStartIndex = pStartPos->nNode.GetIndex();
1189 ULONG nEndIndex = pEndPos->nNode.GetIndex();
1190 const String& rStr = pCurPam->GetNode()->GetTxtNode()->GetTxt();
1191 xub_StrLen nEnde = rStr.Len();
1193 bool bSpanRedline = (nCurPam >= nStartIndex) && (nCurPam <= nEndIndex) && (nStartIndex != nEndIndex);
1195 if ((bSpanRedline && nCntntPos == 0) ||
1196 (nStartIndex == nCurPam && nStart == nCntntPos))
1198 // We are at the start of a redline just need to find out which type
1199 Strm() << '{';
1200 if(pCurRedline->GetType() == nsRedlineType_t::REDLINE_INSERT)
1202 Strm() << OOO_STRING_SVTOOLS_RTF_REVISED;
1203 Strm() << OOO_STRING_SVTOOLS_RTF_REVAUTH;
1204 String sName = SW_MOD()->GetRedlineAuthor(pCurRedline->GetAuthor());
1205 OutLong( pRedlAuthors->AddName(sName) );
1206 Strm() << OOO_STRING_SVTOOLS_RTF_REVDTTM;
1207 OutLong( sw::ms::DateTime2DTTM(pCurRedline->GetTimeStamp()) );
1208 Strm() << ' ';
1210 else if(pCurRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
1212 Strm() << OOO_STRING_SVTOOLS_RTF_DELETED;
1213 Strm() << OOO_STRING_SVTOOLS_RTF_REVAUTHDEL;
1214 String sDelName = SW_MOD()->GetRedlineAuthor(pCurRedline->GetAuthor());
1215 OutLong( pRedlAuthors->AddName(sDelName) );
1216 Strm() << OOO_STRING_SVTOOLS_RTF_REVDTTMDEL;
1217 OutLong( sw::ms::DateTime2DTTM(pCurRedline->GetTimeStamp()) );
1218 Strm() << ' ';
1222 // this is either then of the end of the node or the end of the redline
1223 // time to close off this one
1224 if( (bSpanRedline && nCntntPos == nEnde) ||
1225 (nEndIndex == nCurPam && nEnd == nCntntPos) )
1227 Strm() << '}';
1230 // We have come to the end of a redline move to the next one
1231 // and use resursion to see if another redline starts here
1232 if (nEndIndex == nCurPam && nEnd == nCntntPos)
1234 nCurRedline++;
1235 OutRedline(nCntntPos);
1241 void SwRTFWriter::OutBookmarks( xub_StrLen nCntntPos)
1243 IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1244 if (-1 == nBkmkTabPos)
1245 return;
1247 const ::sw::mark::IMark* pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
1248 if(!pBookmark)
1249 return;
1251 const SwPosition* pStartPos = &pBookmark->GetMarkStart();
1252 const SwPosition* pEndPos = &pBookmark->GetMarkEnd();
1254 ASSERT(pStartPos && pEndPos, "Impossible");
1255 if (!(pStartPos && pEndPos))
1256 return;
1258 if (pStartPos->nNode.GetIndex() == pCurPam->GetPoint()->nNode.GetIndex() &&
1259 pStartPos->nContent.GetIndex() == nCntntPos)
1261 // zur Zeit umspannt das SwBookmark keinen Bereich also kann
1262 // es hier vollstaendig ausgegeben werden.
1264 // erst die SWG spezifischen Daten:
1265 const ::sw::mark::IBookmark* const pAsBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark);
1266 if(pAsBookmark && (pAsBookmark->GetShortName().getLength() || pAsBookmark->GetKeyCode().GetCode()))
1268 OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKKEY );
1269 OutULong( ( pAsBookmark->GetKeyCode().GetCode() |
1270 pAsBookmark->GetKeyCode().GetModifier() ));
1271 if( !pAsBookmark->GetShortName().getLength() )
1272 Strm() << " " ;
1273 else
1275 Strm() << ' ';
1276 OutRTF_AsByteString( *this, pAsBookmark->GetShortName(), eDefaultEncoding );
1278 Strm() << '}';
1280 OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKSTART ) << ' ';
1281 RTFOutFuncs::Out_String( Strm(), pBookmark->GetName(),
1282 eDefaultEncoding, bWriteHelpFmt ) << '}';
1285 if (pEndPos->nNode.GetIndex() == pCurPam->GetPoint()->nNode.GetIndex() &&
1286 pEndPos->nContent.GetIndex() == nCntntPos)
1288 // zur Zeit umspannt das SwBookmark keinen Bereich also kann
1289 // es hier vollstaendig ausgegeben werden.
1291 // erst die SWG spezifischen Daten:
1292 const ::sw::mark::IBookmark* const pAsBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark);
1293 if(pAsBookmark && (pAsBookmark->GetShortName().getLength() || pAsBookmark->GetKeyCode().GetCode()))
1295 OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKKEY );
1296 OutULong( ( pAsBookmark->GetKeyCode().GetCode() |
1297 pAsBookmark->GetKeyCode().GetModifier() ));
1298 if( !pAsBookmark->GetShortName().getLength() )
1299 Strm() << " " ;
1300 else
1302 Strm() << ' ';
1303 OutRTF_AsByteString( *this, pAsBookmark->GetShortName(), eDefaultEncoding );
1305 Strm() << '}';
1307 OutComment( *this, OOO_STRING_SVTOOLS_RTF_BKMKEND ) << ' ';
1308 RTFOutFuncs::Out_String( Strm(), pAsBookmark->GetName(),
1309 eDefaultEncoding, bWriteHelpFmt ) << '}';
1311 if(++nBkmkTabPos >= pMarkAccess->getMarksCount())
1312 nBkmkTabPos = -1;
1313 else
1314 pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
1318 void SwRTFWriter::OutFlyFrm()
1320 USHORT n;
1322 if( !pFlyPos )
1323 return;
1325 // gebe alle freifliegenden Rahmen die sich auf den akt. Absatz
1326 // und evt. auf das aktuelle Zeichen beziehen, aus.
1328 // suche nach dem Anfang der FlyFrames
1329 for( n = 0; n < pFlyPos->Count() &&
1330 (*pFlyPos)[n]->GetNdIndex().GetIndex() <
1331 pCurPam->GetPoint()->nNode.GetIndex(); ++n )
1333 if( n < pFlyPos->Count() )
1334 while( n < pFlyPos->Count() &&
1335 pCurPam->GetPoint()->nNode.GetIndex() ==
1336 (*pFlyPos)[n]->GetNdIndex().GetIndex() )
1338 // den Array-Iterator weiterschalten, damit nicht doppelt
1339 // ausgegeben wird !!
1340 OutRTFFlyFrms( (const SwFlyFrmFmt&)(*pFlyPos)[n++]->GetFmt() );
1345 USHORT SwRTFWriter::GetId( const Color& rColor ) const
1347 ASSERT( pColTbl, "Wo ist meine Color-Tabelle?" );
1348 for( USHORT n = 0; n < pColTbl->Count(); n++ )
1349 if( rColor == (*pColTbl)[ n ] )
1350 return n;
1352 ASSERT( FALSE, "Color nicht in der Tabelle" );
1353 return 0;
1356 USHORT SwRTFWriter::GetId( const SvxFontItem& rFont ) const
1358 const SfxItemPool& rPool = pDoc->GetAttrPool();
1359 const SvxFontItem* pFont = (const SvxFontItem*)GetDfltAttr( RES_CHRATR_FONT );
1360 if( rFont == *pFont )
1361 return 0;
1363 USHORT n = 1;
1364 if( 0 != ( pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem(
1365 RES_CHRATR_FONT )))
1367 if( rFont == *pFont )
1368 return 1;
1369 ++n;
1372 USHORT nMaxItem = rPool.GetItemCount( RES_CHRATR_FONT );
1373 for( USHORT nGet = 0; nGet < nMaxItem; ++nGet )
1374 if( 0 != (pFont = (const SvxFontItem*)rPool.GetItem(
1375 RES_CHRATR_FONT, nGet )) )
1377 if( rFont == *pFont )
1378 return n;
1379 ++n;
1382 ASSERT( FALSE, "Font nicht in der Tabelle" );
1383 return 0;
1386 USHORT SwRTFWriter::GetId( const Font& rFont ) const
1388 return GetId( SvxFontItem( rFont.GetFamily(), rFont.GetName(),
1389 rFont.GetStyleName(), rFont.GetPitch(),
1390 rFont.GetCharSet(),
1391 RES_CHRATR_FONT ) );
1394 USHORT SwRTFWriter::GetId( const SwTxtFmtColl& rColl ) const
1396 // suche das angegebene Format
1397 const SvPtrarr & rArr = *pDoc->GetTxtFmtColls();
1398 for( USHORT n = 0; n < rArr.Count(); n++ )
1399 if( (SwTxtFmtColl*)rArr[ n ] == &rColl )
1400 return n;
1401 ASSERT( FALSE, "TextCollection nicht in der Tabelle" );
1402 return 0;
1405 USHORT SwRTFWriter::GetId( const SwCharFmt& rFmt ) const
1407 // suche das angegebene Format
1408 const SvPtrarr & rArr = *pDoc->GetCharFmts();
1409 for( USHORT n = 0; n < rArr.Count(); n++ )
1410 if( (SwCharFmt*)rArr[ n ] == &rFmt )
1411 return n + pDoc->GetTxtFmtColls()->Count();
1412 ASSERT( FALSE, "CharDFFormat nicht in der Tabelle" );
1413 return 0;
1416 void SwRTFWriter::OutPageDesc()
1418 // Ausgabe der Page-Descriptoren
1419 USHORT nSize = pDoc->GetPageDescCnt();
1420 if( !nSize )
1421 return;
1423 Strm() << SwRTFWriter::sNewLine; // ein Trenner
1424 bOutPageDesc = bOutPageDescTbl = TRUE;
1425 OutComment( *this, OOO_STRING_SVTOOLS_RTF_PGDSCTBL );
1426 for( USHORT n = 0; n < nSize; ++n )
1428 const SwPageDesc& rPageDesc =
1429 const_cast<const SwDoc*>(pDoc)->GetPageDesc( n );
1431 Strm() << SwRTFWriter::sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_PGDSC;
1432 OutULong( n ) << OOO_STRING_SVTOOLS_RTF_PGDSCUSE;
1433 OutULong( rPageDesc.ReadUseOn() );
1435 OutRTFPageDescription( rPageDesc, FALSE, FALSE );
1437 // suche den Folge-PageDescriptor:
1438 USHORT i = nSize;
1439 while( i )
1440 if( rPageDesc.GetFollow() ==
1441 &const_cast<const SwDoc *>(pDoc)->GetPageDesc( --i ) )
1442 break;
1443 Strm() << OOO_STRING_SVTOOLS_RTF_PGDSCNXT;
1444 OutULong( i ) << ' ';
1445 RTFOutFuncs::Out_String( Strm(), XlateFmtName( rPageDesc.GetName(), nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC ), eDefaultEncoding,
1446 bWriteHelpFmt ) << ";}";
1448 Strm() << '}' << SwRTFWriter::sNewLine;
1449 bOutPageDesc = bOutPageDescTbl = FALSE;
1452 void SwRTFWriter::OutRTFBorder(const SvxBorderLine* aLine, const USHORT nSpace )
1454 // M.M. This function writes out border lines in RTF similar to what
1455 // WW8_BRC SwWW8Writer::TranslateBorderLine does in the winword filter
1456 // Eventually it would be nice if all this functionality was in the one place
1457 int nDistance = aLine->GetDistance();
1458 int nOutWidth = aLine->GetOutWidth();
1459 int nInWidth = aLine->GetInWidth();
1460 int nWidth = aLine->GetOutWidth();
1462 if(nDistance == 0) // Single Line
1463 Strm() << OOO_STRING_SVTOOLS_RTF_BRDRS;
1464 else // Double Line
1466 if(nOutWidth == nInWidth)
1467 Strm() << OOO_STRING_SVTOOLS_RTF_BRDRDB;
1468 else if (nOutWidth > nInWidth)
1469 Strm() << OOO_STRING_SVTOOLS_RTF_BRDRTNTHSG;
1470 else if (nOutWidth < nInWidth)
1471 Strm() << OOO_STRING_SVTOOLS_RTF_BRDRTHTNSG;
1473 Strm() << OOO_STRING_SVTOOLS_RTF_BRDRW;
1474 OutULong(nWidth);
1476 Strm() << OOO_STRING_SVTOOLS_RTF_BRSP;
1477 OutULong(nSpace);
1480 void SwRTFWriter::OutRTFBorders(SvxBoxItem aBox)
1482 const SvxBorderLine *pLine = aBox.GetTop();
1483 if(pLine)
1485 Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRT;
1486 OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_TOP));
1489 pLine = aBox.GetBottom();
1490 if(pLine)
1492 Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRB;
1493 OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_BOTTOM));
1496 pLine = aBox.GetRight();
1497 if(pLine)
1499 Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRR;
1500 OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_LEFT));
1503 pLine = aBox.GetLeft();
1504 if(pLine)
1506 Strm() << OOO_STRING_SVTOOLS_RTF_PGBRDRL;
1507 OutRTFBorder(pLine, aBox.GetDistance(BOX_LINE_RIGHT));
1511 void SwRTFWriter::OutRTFPageDescription( const SwPageDesc& rPgDsc,
1512 BOOL bWriteReset,
1513 BOOL bCheckForFirstPage )
1515 // jetzt noch den Teil fuer alle anderen Applikationen:
1516 const SwPageDesc *pSave = pAktPageDesc;
1517 bool bOldOut = bOutPageDesc;
1518 bool bOldHDFT = bOutLeftHeadFoot;
1520 // falls es einen Follow gibt,
1521 pAktPageDesc = &rPgDsc;
1522 if( bCheckForFirstPage && pAktPageDesc->GetFollow() &&
1523 pAktPageDesc->GetFollow() != pAktPageDesc )
1524 pAktPageDesc = pAktPageDesc->GetFollow();
1526 bOutPageDesc = TRUE;
1527 bOutLeftHeadFoot = FALSE;
1529 if( bWriteReset )
1531 if( bFirstLine && bWriteAll &&
1532 pCurPam->GetPoint()->nNode == pOrigPam->Start()->nNode )
1533 Strm() << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE;
1534 else
1535 Strm() << OOO_STRING_SVTOOLS_RTF_SECT << OOO_STRING_SVTOOLS_RTF_SECTD;
1538 if( pAktPageDesc->GetLandscape() )
1539 Strm() << OOO_STRING_SVTOOLS_RTF_LNDSCPSXN;
1541 const SwFmt *pFmt = &pAktPageDesc->GetMaster(); //GetLeft();
1542 OutRTF_SwFmt( *this, *pFmt );
1544 SvxBoxItem aBox = pFmt->GetAttrSet().GetBox();
1545 OutRTFBorders(pFmt->GetAttrSet().GetBox());
1547 // falls es gesharte Heaer/Footer gibt, so gebe diese auch noch aus
1548 if (
1549 (nsUseOnPage::PD_MIRROR & pAktPageDesc->GetUseOn()) &&
1550 (!pAktPageDesc->IsFooterShared() || !pAktPageDesc->IsHeaderShared())
1553 bOutLeftHeadFoot = TRUE;
1554 const SfxPoolItem* pHt;
1555 if( !pAktPageDesc->IsHeaderShared() &&
1556 SFX_ITEM_SET == pAktPageDesc->GetLeft().GetAttrSet().
1557 GetItemState( RES_HEADER, FALSE, &pHt ))
1558 OutRTF_SwFmtHeader( *this, *pHt );
1560 if( !pAktPageDesc->IsFooterShared() &&
1561 SFX_ITEM_SET == pAktPageDesc->GetLeft().GetAttrSet().
1562 GetItemState( RES_FOOTER, FALSE, &pHt ))
1563 OutRTF_SwFmtFooter( *this, *pHt );
1564 bOutLeftHeadFoot = FALSE;
1567 if( pAktPageDesc != &rPgDsc )
1569 pAktPageDesc = &rPgDsc;
1570 Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG;
1572 // die Header/Footer der 1. Seite ausgeben
1573 const SfxPoolItem* pHt;
1574 if( SFX_ITEM_SET == pAktPageDesc->GetMaster().GetAttrSet().
1575 GetItemState( RES_HEADER, FALSE, &pHt ))
1576 OutRTF_SwFmtHeader( *this, *pHt );
1578 if( SFX_ITEM_SET == pAktPageDesc->GetMaster().GetAttrSet().
1579 GetItemState( RES_FOOTER, FALSE, &pHt ))
1580 OutRTF_SwFmtFooter( *this, *pHt );
1583 pAktPageDesc = pSave;
1584 bOutPageDesc = bOldOut;
1585 bOutLeftHeadFoot = bOldHDFT;
1588 BOOL SwRTFWriter::OutBreaks( const SfxItemSet& rSet )
1590 // dann nie Seitenumbrueche ausgeben
1591 BOOL bPgDscWrite = FALSE;
1593 if( !bOutOutlineOnly && bOutPageAttr && !bIgnoreNextPgBreak)
1595 const SfxPoolItem *pItem;
1596 if( SFX_ITEM_SET == rSet.GetItemState( RES_PAGEDESC, TRUE, &pItem )
1597 && ((SwFmtPageDesc*)pItem)->GetPageDesc() )
1599 const SwFmtPageDesc& rPgDsc = *(SwFmtPageDesc*)pItem;
1600 for( USHORT nPos = pDoc->GetPageDescCnt(); nPos; )
1601 if( &const_cast<const SwDoc *>(pDoc)
1602 ->GetPageDesc( --nPos ) == rPgDsc.GetPageDesc() )
1604 pAktPageDesc = ((SwFmtPageDesc*)pItem)->GetPageDesc();
1605 // FALSE wegen schliessender Klammer !!
1606 OutComment( *this, OOO_STRING_SVTOOLS_RTF_PGDSCNO, FALSE );
1607 OutULong( nPos ) << '}';
1609 // nicht weiter, in Styles gibts keine SectionControls !!
1610 if( !bOutStyleTab )
1611 OutRTFPageDescription( *rPgDsc.GetPageDesc(),
1612 TRUE, TRUE );
1613 bPgDscWrite = TRUE;
1614 break;
1617 else if( SFX_ITEM_SET == rSet.GetItemState( RES_BREAK, TRUE, &pItem ) )
1619 const SvxFmtBreakItem &rBreak = *(SvxFmtBreakItem*)pItem;
1620 if( bWriteHelpFmt )
1622 if( SVX_BREAK_PAGE_BEFORE == rBreak.GetBreak() ||
1623 SVX_BREAK_PAGE_AFTER == rBreak.GetBreak() ||
1624 SVX_BREAK_PAGE_BOTH == rBreak.GetBreak() )
1626 bOutFmtAttr = true;
1627 Strm() << OOO_STRING_SVTOOLS_RTF_PAGE;
1630 else
1632 switch( rBreak.GetBreak() )
1634 case SVX_BREAK_COLUMN_BEFORE:
1635 case SVX_BREAK_COLUMN_AFTER:
1636 case SVX_BREAK_COLUMN_BOTH:
1637 break;
1638 case SVX_BREAK_PAGE_BEFORE:
1639 bOutFmtAttr = true;
1640 Strm() << OOO_STRING_SVTOOLS_RTF_PAGE;
1641 break;
1642 case SVX_BREAK_PAGE_AFTER:
1643 OutComment(*this, OOO_STRING_SVTOOLS_RTF_PGBRK, false) << "0}";
1644 break;
1645 case SVX_BREAK_PAGE_BOTH:
1646 OutComment(*this, OOO_STRING_SVTOOLS_RTF_PGBRK, false) << "1}";
1647 break;
1648 default:
1649 break;
1654 bIgnoreNextPgBreak = false;
1655 return bPgDscWrite;
1659 void SwRTFWriter::CheckEndNodeForSection( const SwNode& rNd )
1661 const SwSectionNode* pSectNd = rNd.StartOfSectionNode()->GetSectionNode();
1662 if( pSectNd /*&& CONTENT_SECTION == pSectNd->GetSection().GetType()*/ )
1664 const SwSectionFmt* pSectFmt = pSectNd->GetSection().GetFmt();
1666 // diese Section hatte den akt. Abschnitt bestimmt
1667 // wer bestimmt den nachsten??
1668 SwNodeIndex aIdx( rNd, 1 );
1669 pSectNd = aIdx.GetNode().GetSectionNode();
1670 if( !( ( pSectNd || (aIdx.GetNode().IsEndNode() &&
1671 0 != ( pSectNd = aIdx.GetNode().StartOfSectionNode()->GetSectionNode() )) )
1672 /*&& CONTENT_SECTION == pSectNd->GetSection().GetType()*/ ))
1674 // wer bestimmt denn nun den neuen Abschnitt?
1675 // PageDesc oder eine uebergeordnete Section?
1676 SwSection* pParent = pSectFmt->GetParentSection();
1677 // while( pParent /*&& CONTENT_SECTION != pParent->GetType()*/ )
1678 // pParent = pParent->GetParent();
1680 if( pParent /*&& CONTENT_SECTION == pParent->GetType()*/ )
1681 OutRTF_SwSectionNode( *this, *pParent->
1682 GetFmt()->GetSectionNode( TRUE ) );
1683 else
1685 if (! bOutPageDesc)
1687 Strm() << OOO_STRING_SVTOOLS_RTF_SECT << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE;
1688 OutRTFPageDescription( ( pAktPageDesc
1689 ? *pAktPageDesc
1690 : const_cast<const SwDoc *>(pDoc)
1691 ->GetPageDesc(0) ),
1692 FALSE, TRUE );
1693 Strm() << SwRTFWriter::sNewLine;
1697 // else
1698 // weiter machen, der naechste definiert den neuen Abschnitt
1702 // Struktur speichert die aktuellen Daten des Writers zwischen, um
1703 // einen anderen Dokument-Teil auszugeben, wie z.B. Header/Footer
1704 RTFSaveData::RTFSaveData( SwRTFWriter& rWriter, ULONG nStt, ULONG nEnd )
1705 : rWrt( rWriter ),
1706 pOldPam( rWrt.pCurPam ), pOldEnd( rWrt.GetEndPaM() ),
1707 pOldFlyFmt( rWrt.pFlyFmt ), pOldPageDesc( rWrt.pAktPageDesc ),
1708 pOldAttrSet( rWrt.GetAttrSet() )
1710 bOldWriteAll = rWrt.bWriteAll;
1711 bOldOutTable = rWrt.bOutTable;
1712 bOldOutPageAttr = rWrt.bOutPageAttr;
1713 bOldAutoAttrSet = rWrt.bAutoAttrSet;
1714 bOldOutSection = rWrt.bOutSection;
1716 rWrt.pCurPam = rWrt.NewSwPaM( *rWrt.pDoc, nStt, nEnd );
1718 // Tabelle in Sonderbereichen erkennen
1719 if( nStt != rWrt.pCurPam->GetMark()->nNode.GetIndex() &&
1720 rWrt.pDoc->GetNodes()[ nStt ]->IsTableNode() )
1721 rWrt.pCurPam->GetMark()->nNode = nStt;
1723 rWrt.SetEndPaM( rWrt.pCurPam );
1724 rWrt.pCurPam->Exchange( );
1725 rWrt.bWriteAll = TRUE;
1726 rWrt.bOutTable = FALSE;
1727 rWrt.bOutPageAttr = FALSE;
1728 rWrt.SetAttrSet( 0 );
1729 rWrt.bAutoAttrSet = FALSE;
1730 rWrt.bOutSection = FALSE;
1734 RTFSaveData::~RTFSaveData()
1736 delete rWrt.pCurPam; // Pam wieder loeschen
1738 rWrt.pCurPam = pOldPam;
1739 rWrt.SetEndPaM( pOldEnd );
1740 rWrt.bWriteAll = bOldWriteAll;
1741 rWrt.bOutTable = bOldOutTable;
1742 rWrt.pFlyFmt = pOldFlyFmt;
1743 rWrt.pAktPageDesc = pOldPageDesc;
1744 rWrt.SetAttrSet( pOldAttrSet );
1745 rWrt.bAutoAttrSet = bOldAutoAttrSet;
1746 rWrt.bOutPageAttr = bOldOutPageAttr;
1747 rWrt.bOutSection = bOldOutSection;
1750 extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportRTF( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
1752 xRet = new SwRTFWriter( rFltName, rBaseURL );
1755 short SwRTFWriter::GetCurrentPageDirection() const
1757 const SwFrmFmt &rFmt = pAktPageDesc
1758 ? pAktPageDesc->GetMaster()
1759 : const_cast<const SwDoc *>(pDoc)
1760 ->GetPageDesc(0).GetMaster();
1761 const SvxFrameDirectionItem* pItem = &rFmt.GetFrmDir();
1763 if (!pItem)
1765 pItem = (const SvxFrameDirectionItem*)
1766 &pDoc->GetAttrPool().GetDefaultItem(RES_FRAMEDIR);
1768 return pItem->GetValue();
1771 short SwRTFWriter::TrueFrameDirection(const SwFrmFmt &rFlyFmt) const
1773 const SwFrmFmt *pFlyFmt2 = &rFlyFmt;
1774 const SvxFrameDirectionItem* pItem = 0;
1775 while (pFlyFmt2)
1777 pItem = &pFlyFmt2->GetFrmDir();
1778 if (FRMDIR_ENVIRONMENT == pItem->GetValue())
1780 pItem = 0;
1781 const SwFmtAnchor* pAnchor = &pFlyFmt2->GetAnchor();
1782 if( FLY_PAGE != pAnchor->GetAnchorId() &&
1783 pAnchor->GetCntntAnchor() )
1785 pFlyFmt2 = pAnchor->GetCntntAnchor()->nNode.
1786 GetNode().GetFlyFmt();
1788 else
1789 pFlyFmt2 = 0;
1791 else
1792 pFlyFmt2 = 0;
1795 short nRet;
1796 if (pItem)
1797 nRet = pItem->GetValue();
1798 else
1799 nRet = GetCurrentPageDirection();
1801 ASSERT(nRet != FRMDIR_ENVIRONMENT, "leaving with environment direction");
1802 return nRet;
1805 /* vi:set tabstop=4 shiftwidth=4 expandtab: */