Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "rtfexportfilter.hxx"
21 : #include "rtfsdrexport.hxx"
22 : #include "rtfattributeoutput.hxx"
23 :
24 : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
25 : #include <com/sun/star/i18n/ScriptType.hpp>
26 :
27 : #include <docsh.hxx>
28 : #include <viewsh.hxx>
29 : #include <viewopt.hxx>
30 : #include <ndtxt.hxx>
31 : #include <fmtpdsc.hxx>
32 : #include <section.hxx>
33 : #include <pagedesc.hxx>
34 : #include <swtable.hxx>
35 : #include <frmatr.hxx>
36 : #include <ftninfo.hxx>
37 : #include <fmthdft.hxx>
38 : #include <editeng/colritem.hxx>
39 : #include <editeng/udlnitem.hxx>
40 : #include <editeng/boxitem.hxx>
41 : #include <editeng/brshitem.hxx>
42 : #include <editeng/shaditem.hxx>
43 : #include <editeng/ulspitem.hxx>
44 : #include <editeng/paperinf.hxx>
45 : #include <editeng/protitem.hxx>
46 :
47 : #include <docary.hxx>
48 : #include <numrule.hxx>
49 : #include <lineinfo.hxx>
50 : #include <swmodule.hxx>
51 :
52 : #include "ww8par.hxx"
53 :
54 : #include <comphelper/string.hxx>
55 : #include <rtl/ustring.hxx>
56 : #include <svtools/rtfkeywd.hxx>
57 : #include <filter/msfilter/rtfutil.hxx>
58 : #include <unotools/configmgr.hxx>
59 :
60 : #if OSL_DEBUG_LEVEL > 1
61 : #include <iostream>
62 : #endif
63 :
64 : using ::editeng::SvxBorderLine;
65 : using namespace ::comphelper;
66 : using namespace ::com::sun::star;
67 :
68 : using sw::mark::IMark;
69 :
70 : #if defined(UNX)
71 : const sal_Char RtfExport::sNewLine = '\012';
72 : #else
73 : const sal_Char* const RtfExport::sNewLine = "\015\012";
74 : #endif
75 :
76 : // the default text encoding for the export, if it doesn't fit unicode will
77 : // be used
78 : #define DEF_ENCODING RTL_TEXTENCODING_ASCII_US
79 :
80 8322 : AttributeOutputBase& RtfExport::AttrOutput() const
81 : {
82 8322 : return *m_pAttrOutput;
83 : }
84 :
85 0 : MSWordSections& RtfExport::Sections() const
86 : {
87 0 : return *m_pSections;
88 : }
89 :
90 2 : RtfSdrExport& RtfExport::SdrExporter() const
91 : {
92 2 : return *m_pSdrExport;
93 : }
94 :
95 1938 : bool RtfExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
96 : {
97 : // FIXME is this actually true for rtf? - this is copied from DOCX
98 1938 : if ( nScript == i18n::ScriptType::ASIAN )
99 : {
100 : // for asian in ww8, there is only one fontsize
101 : // and one fontstyle (posture/weight)
102 0 : switch ( nWhich )
103 : {
104 : case RES_CHRATR_FONTSIZE:
105 : case RES_CHRATR_POSTURE:
106 : case RES_CHRATR_WEIGHT:
107 0 : return false;
108 : default:
109 0 : break;
110 : }
111 : }
112 1938 : else if ( nScript != i18n::ScriptType::COMPLEX )
113 : {
114 : // for western in ww8, there is only one fontsize
115 : // and one fontstyle (posture/weight)
116 1938 : switch ( nWhich )
117 : {
118 : case RES_CHRATR_CJK_FONTSIZE:
119 : case RES_CHRATR_CJK_POSTURE:
120 : case RES_CHRATR_CJK_WEIGHT:
121 338 : return false;
122 : default:
123 1600 : break;
124 : }
125 : }
126 1600 : return true;
127 : }
128 :
129 278 : void RtfExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
130 : {
131 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
132 :
133 278 : std::vector< OUString > aStarts;
134 278 : std::vector< OUString > aEnds;
135 :
136 278 : IMarkVector aMarks;
137 278 : if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
138 : {
139 0 : for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
140 : it != end; ++it )
141 : {
142 0 : IMark* pMark = (*it);
143 0 : xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
144 0 : xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
145 :
146 0 : if ( nStart == nAktPos )
147 0 : aStarts.push_back( pMark->GetName() );
148 :
149 0 : if ( nEnd == nAktPos )
150 0 : aEnds.push_back( pMark->GetName() );
151 : }
152 : }
153 :
154 278 : m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
155 278 : }
156 :
157 0 : void RtfExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ )
158 : {
159 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
160 :
161 0 : std::vector<OUString> aStarts;
162 0 : std::vector<OUString> aEnds;
163 :
164 0 : aStarts.push_back(rName);
165 0 : aEnds.push_back(rName);
166 :
167 0 : m_pAttrOutput->WriteBookmarks_Impl(aStarts, aEnds);
168 0 : }
169 :
170 0 : void RtfExport::WriteChar( sal_Unicode )
171 : {
172 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
173 :
174 : /* WriteChar() has nothing to do for rtf. */
175 0 : }
176 :
177 56 : static bool IsExportNumRule( const SwNumRule& rRule, sal_uInt8* pEnd = 0 )
178 : {
179 56 : sal_uInt8 nEnd = MAXLEVEL;
180 56 : while( nEnd-- && !rRule.GetNumFmt( nEnd ))
181 : ;
182 56 : ++nEnd;
183 :
184 : const SwNumFmt* pNFmt;
185 : sal_uInt8 nLvl;
186 :
187 136 : for( nLvl = 0; nLvl < nEnd; ++nLvl )
188 320 : if( SVX_NUM_NUMBER_NONE != ( pNFmt = &rRule.Get( nLvl ))
189 160 : ->GetNumberingType() || !pNFmt->GetPrefix().isEmpty() ||
190 80 : (!pNFmt->GetSuffix().isEmpty() && !pNFmt->GetSuffix().equals(aDotStr)) )
191 0 : break;
192 :
193 56 : if( pEnd )
194 0 : *pEnd = nEnd;
195 56 : return nLvl != nEnd;
196 : }
197 :
198 56 : void RtfExport::BuildNumbering()
199 : {
200 56 : const SwNumRuleTbl& rListTbl = pDoc->GetNumRuleTbl();
201 :
202 224 : for( sal_uInt16 n = rListTbl.size()+1; n; )
203 : {
204 : SwNumRule* pRule;
205 112 : --n;
206 112 : if( n == rListTbl.size() )
207 56 : pRule = (SwNumRule*)pDoc->GetOutlineNumRule();
208 : else
209 : {
210 56 : pRule = rListTbl[ n ];
211 56 : if( !pDoc->IsUsed( *pRule ))
212 56 : continue;
213 : }
214 :
215 56 : if( IsExportNumRule( *pRule ))
216 0 : GetId( *pRule );
217 : }
218 56 : }
219 :
220 56 : void RtfExport::WriteNumbering()
221 : {
222 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
223 :
224 56 : if ( !pUsedNumTbl )
225 112 : return; // no numbering is used
226 :
227 0 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_LISTTABLE;
228 0 : AbstractNumberingDefinitions();
229 0 : Strm() << '}';
230 :
231 0 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDETABLE;
232 0 : NumberingDefinitions();
233 0 : Strm() << '}';
234 :
235 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
236 : }
237 :
238 56 : void RtfExport::WriteRevTab()
239 : {
240 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
241 :
242 56 : int nRevAuthors = pDoc->GetRedlineTbl().size();
243 :
244 56 : if (nRevAuthors < 1)
245 112 : return;
246 :
247 : // RTF always seems to use Unknown as the default first entry
248 0 : GetRedline(OUString("Unknown"));
249 :
250 0 : for( sal_uInt16 i = 0; i < pDoc->GetRedlineTbl().size(); ++i )
251 : {
252 0 : const SwRedline* pRedl = pDoc->GetRedlineTbl()[ i ];
253 :
254 0 : GetRedline(SW_MOD()->GetRedlineAuthor(pRedl->GetAuthor()));
255 : }
256 :
257 : // Now write the table
258 0 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_REVTBL << ' ';
259 0 : for(sal_uInt16 i = 0; i < m_aRedlineTbl.size(); ++i)
260 : {
261 0 : const String* pAuthor = GetRedline(i);
262 0 : Strm() << '{';
263 0 : if (pAuthor)
264 0 : Strm() << msfilter::rtfutil::OutString(*pAuthor, eDefaultEncoding).getStr();
265 0 : Strm() << ";}";
266 : }
267 0 : Strm() << '}' << sNewLine;
268 : }
269 :
270 2 : void RtfExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
271 : const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, sal_uInt8 /*nBreakCode*/ )
272 : {
273 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
274 :
275 : // headers
276 2 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
277 0 : WriteHeaderFooter( rLeftFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERL );
278 :
279 2 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
280 0 : WriteHeaderFooter( rFmt, true, OOO_STRING_SVTOOLS_RTF_HEADER );
281 :
282 2 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
283 0 : WriteHeaderFooter( rFirstPageFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERF, true );
284 :
285 : // footers
286 2 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
287 0 : WriteHeaderFooter( rLeftFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERL );
288 :
289 2 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
290 0 : WriteHeaderFooter( rFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTER );
291 :
292 2 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
293 0 : WriteHeaderFooter( rFirstPageFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERF, true );
294 2 : }
295 :
296 0 : void RtfExport::OutputField( const SwField* pFld, ww::eField eFldType, const String& rFldCmd, sal_uInt8 nMode )
297 : {
298 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
299 :
300 0 : m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
301 0 : }
302 :
303 0 : void RtfExport::WriteFormData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
304 : {
305 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
306 0 : }
307 :
308 0 : void RtfExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
309 : {
310 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
311 0 : }
312 :
313 0 : void RtfExport::DoComboBox(const rtl::OUString& /*rName*/,
314 : const rtl::OUString& /*rHelp*/,
315 : const rtl::OUString& /*rToolTip*/,
316 : const rtl::OUString& /*rSelected*/,
317 : uno::Sequence<rtl::OUString>& /*rListItems*/)
318 : {
319 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
320 :
321 : // this is handled in RtfAttributeOutput::OutputFlyFrame_Impl
322 0 : }
323 :
324 0 : void RtfExport::DoFormText(const SwInputField* pFld )
325 : {
326 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
327 :
328 0 : ::rtl::OUString sResult = pFld->ExpandField(pDoc->IsClipBoard());
329 0 : ::rtl::OUString sHelp( pFld->GetHelp() );
330 0 : ::rtl::OUString sName = pFld->GetPar2();
331 0 : ::rtl::OUString sStatus = pFld->GetToolTip();
332 0 : m_pAttrOutput->RunText().append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST "{ FORMTEXT }");
333 0 : m_pAttrOutput->RunText().append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD " {" OOO_STRING_SVTOOLS_RTF_FFTYPE "0" );
334 0 : if( !sHelp.isEmpty() )
335 0 : m_pAttrOutput->RunText().append( OOO_STRING_SVTOOLS_RTF_FFOWNHELP );
336 0 : if( !sStatus.isEmpty() )
337 0 : m_pAttrOutput->RunText().append( OOO_STRING_SVTOOLS_RTF_FFOWNSTAT );
338 0 : m_pAttrOutput->RunText().append( OOO_STRING_SVTOOLS_RTF_FFTYPETXT "0" );
339 :
340 0 : if( !sName.isEmpty() )
341 0 : m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ").append( msfilter::rtfutil::OutString( sName, eDefaultEncoding )).append( "}" );
342 0 : if( !sHelp.isEmpty() )
343 0 : m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ").append( msfilter::rtfutil::OutString( sHelp, eDefaultEncoding )).append( "}" );
344 0 : m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFDEFTEXT " ").append( msfilter::rtfutil::OutString( sResult, eDefaultEncoding )).append( "}" );
345 0 : if( !sStatus.isEmpty() )
346 0 : m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ").append( msfilter::rtfutil::OutString( sStatus, eDefaultEncoding )).append( "}");
347 0 : m_pAttrOutput->RunText().append( "}}}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " " );
348 0 : m_pAttrOutput->RunText().append( msfilter::rtfutil::OutString( sResult, eDefaultEncoding )).append( "}}" );
349 0 : }
350 :
351 0 : sal_uLong RtfExport::ReplaceCr( sal_uInt8 )
352 : {
353 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
354 :
355 : // Completely unused for Rtf export... only here for code sharing
356 : // purpose with binary export
357 :
358 0 : return 0;
359 : }
360 :
361 56 : void RtfExport::WriteFonts()
362 : {
363 56 : Strm() << sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_FONTTBL;
364 56 : maFontHelper.WriteFontTable( *m_pAttrOutput );
365 56 : Strm() << '}';
366 56 : }
367 :
368 56 : void RtfExport::WriteStyles()
369 : {
370 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
371 56 : pStyles->OutputStylesTable();
372 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
373 56 : }
374 :
375 56 : void RtfExport::WriteMainText()
376 : {
377 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
378 56 : pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
379 56 : WriteText();
380 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
381 56 : }
382 :
383 56 : void RtfExport::WriteInfo()
384 : {
385 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
386 56 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_INFO;
387 :
388 56 : SwDocShell *pDocShell(pDoc->GetDocShell());
389 56 : uno::Reference<document::XDocumentProperties> xDocProps;
390 56 : if (pDocShell) {
391 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
392 56 : pDocShell->GetModel(), uno::UNO_QUERY);
393 56 : xDocProps.set(xDPS->getDocumentProperties());
394 : }
395 :
396 56 : if (xDocProps.is()) {
397 56 : OutUnicode(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle());
398 56 : OutUnicode(OOO_STRING_SVTOOLS_RTF_SUBJECT, xDocProps->getSubject());
399 :
400 : OutUnicode(OOO_STRING_SVTOOLS_RTF_KEYWORDS,
401 56 : ::comphelper::string::convertCommaSeparated(xDocProps->getKeywords()));
402 56 : OutUnicode(OOO_STRING_SVTOOLS_RTF_DOCCOMM, xDocProps->getDescription());
403 :
404 56 : OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getAuthor());
405 56 : OutDateTime(OOO_STRING_SVTOOLS_RTF_CREATIM, xDocProps->getCreationDate());
406 :
407 56 : OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR,xDocProps->getModifiedBy());
408 56 : OutDateTime(OOO_STRING_SVTOOLS_RTF_REVTIM, xDocProps->getModificationDate());
409 :
410 56 : OutDateTime(OOO_STRING_SVTOOLS_RTF_PRINTIM, xDocProps->getPrintDate());
411 : }
412 :
413 56 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_COMMENT << " ";
414 56 : Strm() << OUStringToOString( utl::ConfigManager::getProductName(), eCurrentEncoding).getStr() << "}{" << OOO_STRING_SVTOOLS_RTF_VERN;
415 56 : OutULong( SUPD*10 ) << '}';
416 56 : Strm() << '}';
417 56 : }
418 :
419 56 : void RtfExport::WritePageDescTable()
420 : {
421 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
422 :
423 : // Write page descriptions (page styles)
424 56 : sal_uInt16 nSize = pDoc->GetPageDescCnt();
425 56 : if( !nSize )
426 56 : return;
427 :
428 56 : Strm() << sNewLine; // a separator
429 56 : bOutPageDescs = sal_True;
430 56 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_PGDSCTBL;
431 122 : for( sal_uInt16 n = 0; n < nSize; ++n )
432 : {
433 66 : const SwPageDesc& rPageDesc = pDoc->GetPageDesc( n );
434 :
435 66 : Strm() << sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_PGDSC;
436 66 : OutULong( n ) << OOO_STRING_SVTOOLS_RTF_PGDSCUSE;
437 66 : OutULong( rPageDesc.ReadUseOn() );
438 :
439 66 : OutPageDescription( rPageDesc, sal_False, sal_False );
440 :
441 : // search for the next page description
442 66 : sal_uInt16 i = nSize;
443 156 : while( i )
444 90 : if( rPageDesc.GetFollow() == &pDoc->GetPageDesc( --i ) )
445 66 : break;
446 66 : Strm() << OOO_STRING_SVTOOLS_RTF_PGDSCNXT;
447 66 : OutULong( i ) << ' ';
448 66 : Strm() << msfilter::rtfutil::OutString( rPageDesc.GetName(), eDefaultEncoding).getStr() << ";}";
449 : }
450 56 : Strm() << '}' << sNewLine;
451 56 : bOutPageDescs = sal_False;
452 :
453 : // reset table infos, otherwise the depth of the cells will be incorrect,
454 : // in case the page style (header or footer) had tables
455 56 : mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
456 : }
457 :
458 56 : void RtfExport::ExportDocument_Impl()
459 : {
460 : // Make the header
461 56 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_RTF << '1'
462 56 : << OOO_STRING_SVTOOLS_RTF_ANSI;
463 56 : Strm() << OOO_STRING_SVTOOLS_RTF_DEFF;
464 56 : OutULong( maFontHelper.GetId( (SvxFontItem&)pDoc->GetAttrPool().GetDefaultItem(
465 56 : RES_CHRATR_FONT ) ));
466 : // If this not exist, MS don't understand our ansi characters (0x80-0xff).
467 56 : Strm() << "\\adeflang1025";
468 :
469 : // Font table
470 56 : WriteFonts();
471 :
472 56 : pStyles = new MSWordStyles( *this );
473 : // Color and stylesheet table
474 56 : WriteStyles();
475 :
476 : // List table
477 56 : BuildNumbering();
478 56 : WriteNumbering();
479 :
480 56 : WriteRevTab();
481 :
482 56 : WriteInfo();
483 : // Default TabSize
484 56 : Strm() << m_pAttrOutput->m_aTabStop.makeStringAndClear().getStr() << sNewLine;
485 : // Zoom
486 56 : ViewShell *pViewShell(pDoc->GetCurrentViewShell());
487 56 : if (pViewShell && pViewShell->GetViewOptions()->GetZoomType() == SVX_ZOOM_PERCENT)
488 : {
489 56 : Strm() << OOO_STRING_SVTOOLS_RTF_VIEWSCALE;
490 56 : OutULong(pViewShell->GetViewOptions()->GetZoom());
491 : }
492 : // Page description
493 56 : WritePageDescTable();
494 :
495 : // Enable form protection by default if needed, as there is no switch to
496 : // enable it on a per-section basis. OTOH don't always enable it as it
497 : // breaks moving of drawings - so write it only in case there is really a
498 : // protected section in the document.
499 : {
500 56 : const SfxItemPool& rPool = pDoc->GetAttrPool();
501 56 : sal_uInt32 const nMaxItem = rPool.GetItemCount2(RES_PROTECT);
502 56 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
503 : {
504 0 : const SvxProtectItem* pProtect = (const SvxProtectItem*)rPool.GetItem2(RES_PROTECT, n);
505 0 : if (pProtect && pProtect->IsCntntProtected())
506 : {
507 0 : Strm() << OOO_STRING_SVTOOLS_RTF_FORMPROT;
508 0 : break;
509 : }
510 : }
511 : }
512 :
513 : // enable form field shading
514 56 : Strm() << OOO_STRING_SVTOOLS_RTF_FORMSHADE;
515 :
516 : // size and empty margins of the page
517 56 : if( pDoc->GetPageDescCnt() )
518 : {
519 : // Seeking the first SwFmtPageDesc. If no set, the default is valid
520 56 : const SwFmtPageDesc* pSttPgDsc = 0;
521 : {
522 56 : const SwNode& rSttNd = *pDoc->GetNodes()[
523 112 : pDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 ];
524 56 : const SfxItemSet* pSet = 0;
525 :
526 56 : if( rSttNd.IsCntntNode() )
527 56 : pSet = &rSttNd.GetCntntNode()->GetSwAttrSet();
528 0 : else if( rSttNd.IsTableNode() )
529 0 : pSet = &rSttNd.GetTableNode()->GetTable().
530 0 : GetFrmFmt()->GetAttrSet();
531 0 : else if( rSttNd.IsSectionNode() )
532 0 : pSet = &rSttNd.GetSectionNode()->GetSection().
533 0 : GetFmt()->GetAttrSet();
534 :
535 56 : if( pSet )
536 : {
537 : sal_uInt16 nPosInDoc;
538 56 : pSttPgDsc = (SwFmtPageDesc*)&pSet->Get( RES_PAGEDESC );
539 56 : if( !pSttPgDsc->GetPageDesc() )
540 6 : pSttPgDsc = 0;
541 50 : else if( pDoc->FindPageDescByName( pSttPgDsc->
542 50 : GetPageDesc()->GetName(), &nPosInDoc ))
543 : {
544 50 : Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_PGDSCNO;
545 50 : OutULong( nPosInDoc ) << '}';
546 : }
547 : }
548 : }
549 : const SwPageDesc& rPageDesc = pSttPgDsc ? *pSttPgDsc->GetPageDesc()
550 56 : : pDoc->GetPageDesc( 0 );
551 56 : const SwFrmFmt &rFmtPage = rPageDesc.GetMaster();
552 :
553 : {
554 56 : if( rPageDesc.GetLandscape() )
555 0 : Strm() << OOO_STRING_SVTOOLS_RTF_LANDSCAPE;
556 :
557 56 : const SwFmtFrmSize& rSz = rFmtPage.GetFrmSize();
558 : // Clipboard document is always created without a printer, then
559 : // the size will be always LONG_MAX! Solution then is to use A4
560 56 : if( LONG_MAX == rSz.GetHeight() || LONG_MAX == rSz.GetWidth() )
561 : {
562 0 : Strm() << OOO_STRING_SVTOOLS_RTF_PAPERH;
563 0 : Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
564 0 : OutULong( a4.Height() ) << OOO_STRING_SVTOOLS_RTF_PAPERW;
565 0 : OutULong( a4.Width() );
566 : }
567 : else
568 : {
569 56 : Strm() << OOO_STRING_SVTOOLS_RTF_PAPERH;
570 56 : OutULong( rSz.GetHeight() ) << OOO_STRING_SVTOOLS_RTF_PAPERW;
571 56 : OutULong( rSz.GetWidth() );
572 : }
573 : }
574 :
575 : {
576 56 : const SvxLRSpaceItem& rLR = rFmtPage.GetLRSpace();
577 56 : Strm() << OOO_STRING_SVTOOLS_RTF_MARGL;
578 56 : OutLong( rLR.GetLeft() ) << OOO_STRING_SVTOOLS_RTF_MARGR;
579 56 : OutLong( rLR.GetRight() );
580 : }
581 :
582 : {
583 56 : const SvxULSpaceItem& rUL = rFmtPage.GetULSpace();
584 56 : Strm() << OOO_STRING_SVTOOLS_RTF_MARGT;
585 56 : OutLong( rUL.GetUpper() ) << OOO_STRING_SVTOOLS_RTF_MARGB;
586 56 : OutLong( rUL.GetLower() );
587 : }
588 :
589 56 : Strm() << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE;
590 : // All sections are unlocked by default
591 56 : Strm() << OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED;
592 56 : OutLong(1);
593 56 : OutPageDescription( rPageDesc, sal_False, sal_True ); // Changed bCheckForFirstPage to sal_True so headers
594 : // following title page are correctly added - i13107
595 56 : if( pSttPgDsc )
596 : {
597 50 : pAktPageDesc = &rPageDesc;
598 : }
599 : }
600 :
601 : // line numbering
602 56 : const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo();
603 56 : if ( rLnNumInfo.IsPaintLineNumbers() )
604 0 : AttrOutput().SectionLineNumbering( 0, rLnNumInfo );
605 :
606 : {
607 : // write the footnotes and endnotes-out Info
608 56 : const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
609 :
610 : const char* pOut = FTNPOS_CHAPTER == rFtnInfo.ePos
611 : ? OOO_STRING_SVTOOLS_RTF_ENDDOC
612 56 : : OOO_STRING_SVTOOLS_RTF_FTNBJ;
613 56 : Strm() << pOut << OOO_STRING_SVTOOLS_RTF_FTNSTART;
614 56 : OutLong( rFtnInfo.nFtnOffset + 1 );
615 :
616 56 : switch( rFtnInfo.eNum )
617 : {
618 0 : case FTNNUM_PAGE: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTPG; break;
619 56 : case FTNNUM_DOC: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTCONT; break;
620 0 : default: pOut = OOO_STRING_SVTOOLS_RTF_FTNRESTART; break;
621 : }
622 56 : Strm() << pOut;
623 :
624 56 : switch( rFtnInfo.aFmt.GetNumberingType() )
625 : {
626 : case SVX_NUM_CHARS_LOWER_LETTER:
627 0 : case SVX_NUM_CHARS_LOWER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_FTNNALC; break;
628 : case SVX_NUM_CHARS_UPPER_LETTER:
629 0 : case SVX_NUM_CHARS_UPPER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_FTNNAUC; break;
630 0 : case SVX_NUM_ROMAN_LOWER: pOut = OOO_STRING_SVTOOLS_RTF_FTNNRLC; break;
631 0 : case SVX_NUM_ROMAN_UPPER: pOut = OOO_STRING_SVTOOLS_RTF_FTNNRUC; break;
632 0 : case SVX_NUM_CHAR_SPECIAL: pOut = OOO_STRING_SVTOOLS_RTF_FTNNCHI; break;
633 56 : default: pOut = OOO_STRING_SVTOOLS_RTF_FTNNAR; break;
634 : }
635 56 : Strm() << pOut;
636 :
637 :
638 56 : const SwEndNoteInfo& rEndNoteInfo = pDoc->GetEndNoteInfo();
639 :
640 56 : Strm() << OOO_STRING_SVTOOLS_RTF_AENDDOC << OOO_STRING_SVTOOLS_RTF_AFTNRSTCONT
641 56 : << OOO_STRING_SVTOOLS_RTF_AFTNSTART;
642 56 : OutLong( rEndNoteInfo.nFtnOffset + 1 );
643 :
644 56 : switch( rEndNoteInfo.aFmt.GetNumberingType() )
645 : {
646 : case SVX_NUM_CHARS_LOWER_LETTER:
647 0 : case SVX_NUM_CHARS_LOWER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNALC; break;
648 : case SVX_NUM_CHARS_UPPER_LETTER:
649 0 : case SVX_NUM_CHARS_UPPER_LETTER_N: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAUC; break;
650 56 : case SVX_NUM_ROMAN_LOWER: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRLC; break;
651 0 : case SVX_NUM_ROMAN_UPPER: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRUC; break;
652 0 : case SVX_NUM_CHAR_SPECIAL: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNCHI; break;
653 0 : default: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAR; break;
654 : }
655 56 : Strm() << pOut;
656 : }
657 :
658 56 : Strm() << sNewLine;
659 :
660 : // Init sections
661 56 : m_pSections = new MSWordSections( *this );
662 :
663 56 : WriteMainText();
664 :
665 56 : Strm() << '}';
666 56 : }
667 :
668 2 : void RtfExport::PrepareNewPageDesc( const SfxItemSet* pSet,
669 : const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt,
670 : const SwPageDesc* pNewPgDesc )
671 : {
672 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
673 2 : const SwSectionFmt* pFmt = GetSectionFormat( rNd );
674 2 : const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
675 :
676 : OSL_ENSURE( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
677 :
678 2 : if ( pNewPgDescFmt )
679 2 : m_pSections->AppendSection( *pNewPgDescFmt, rNd, pFmt, nLnNm );
680 0 : else if ( pNewPgDesc )
681 0 : m_pSections->AppendSection( pNewPgDesc, rNd, pFmt, nLnNm );
682 :
683 : // Don't insert a page break, when we're changing page style just because the next page has to be a different one.
684 2 : if (!m_pAttrOutput->m_pPrevPageDesc || m_pAttrOutput->m_pPrevPageDesc->GetFollow() != pNewPgDesc)
685 2 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
686 2 : }
687 :
688 340 : bool RtfExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
689 : {
690 340 : bool bRet( false );
691 :
692 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
693 :
694 340 : if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
695 : {
696 340 : if (const SwFmt *pParent = rFmt.DerivedFrom())
697 : {
698 340 : if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
699 : {
700 : // Level 9 disables the outline
701 0 : Strm() << OOO_STRING_SVTOOLS_RTF_LEVEL << sal_Int32(9);
702 :
703 0 : bRet = true;
704 : }
705 : }
706 : }
707 :
708 340 : return bRet;
709 : }
710 :
711 0 : void RtfExport::OutputGrfNode( const SwGrfNode& )
712 : {
713 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
714 :
715 : /* noop, see RtfAttributeOutput::FlyFrameGraphic */
716 0 : }
717 :
718 0 : void RtfExport::OutputOLENode( const SwOLENode& )
719 : {
720 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
721 :
722 : /* noop, see RtfAttributeOutput::FlyFrameOLE */
723 0 : }
724 :
725 0 : void RtfExport::OutputLinkedOLE( const rtl::OUString& )
726 : {
727 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
728 0 : }
729 :
730 132 : void RtfExport::OutputTextNode( const SwTxtNode& rNode )
731 : {
732 132 : if ( !m_bOutOutlineOnly || rNode.IsOutline( ) )
733 132 : MSWordExportBase::OutputTextNode( rNode );
734 132 : }
735 :
736 0 : void RtfExport::AppendSection( const SwPageDesc* pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
737 : {
738 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
739 :
740 0 : m_pSections->AppendSection( pPageDesc, pFmt, nLnNum );
741 0 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
742 0 : }
743 :
744 56 : RtfExport::RtfExport( RtfExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam, Writer* pWriter, bool bOutOutlineOnly )
745 : : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
746 : m_pFilter( pFilter ),
747 : m_pWriter( pWriter ),
748 : m_pAttrOutput( NULL ),
749 : m_pSections( NULL ),
750 : m_pSdrExport( NULL ),
751 : m_bOutOutlineOnly( bOutOutlineOnly ),
752 : eDefaultEncoding(
753 : rtl_getTextEncodingFromWindowsCharset(
754 56 : sw::ms::rtl_TextEncodingToWinCharset(DEF_ENCODING))),
755 : eCurrentEncoding(eDefaultEncoding),
756 112 : bRTFFlySyntax(false)
757 : {
758 56 : mbExportModeRTF = true;
759 : // the attribute output for the document
760 56 : m_pAttrOutput = new RtfAttributeOutput( *this );
761 : // that just causes problems for RTF
762 56 : bSubstituteBullets = false;
763 : // needed to have a complete font table
764 56 : maFontHelper.bLoadAllFonts = true;
765 : // the related SdrExport
766 56 : m_pSdrExport = new RtfSdrExport( *this );
767 :
768 56 : if (!m_pWriter)
769 56 : m_pWriter = &m_pFilter->m_aWriter;
770 56 : }
771 :
772 112 : RtfExport::~RtfExport()
773 : {
774 56 : delete m_pAttrOutput, m_pAttrOutput = NULL;
775 56 : delete m_pSdrExport, m_pSdrExport = NULL;
776 56 : }
777 :
778 10714 : SvStream& RtfExport::Strm()
779 : {
780 10714 : return m_pWriter->Strm();
781 : }
782 :
783 3210 : SvStream& RtfExport::OutULong( sal_uLong nVal )
784 : {
785 3210 : return m_pWriter->OutULong( Strm(), nVal );
786 : }
787 :
788 404 : SvStream& RtfExport::OutLong( long nVal )
789 : {
790 404 : return m_pWriter->OutLong( Strm(), nVal );
791 : }
792 :
793 336 : void RtfExport::OutUnicode(const sal_Char *pToken, const String &rContent)
794 : {
795 336 : if (rContent.Len())
796 : {
797 8 : Strm() << '{' << pToken << ' ';
798 8 : Strm() << msfilter::rtfutil::OutString( rContent, eCurrentEncoding ).getStr();
799 8 : Strm() << '}';
800 : }
801 336 : }
802 :
803 168 : void RtfExport::OutDateTime(const sal_Char* pStr, const util::DateTime& rDT )
804 : {
805 168 : Strm() << '{' << pStr << OOO_STRING_SVTOOLS_RTF_YR;
806 168 : OutULong( rDT.Year ) << OOO_STRING_SVTOOLS_RTF_MO;
807 168 : OutULong( rDT.Month ) << OOO_STRING_SVTOOLS_RTF_DY;
808 168 : OutULong( rDT.Day ) << OOO_STRING_SVTOOLS_RTF_HR;
809 168 : OutULong( rDT.Hours ) << OOO_STRING_SVTOOLS_RTF_MIN;
810 168 : OutULong( rDT.Minutes ) << '}';
811 168 : }
812 :
813 62 : sal_uInt16 RtfExport::GetColor( const Color& rColor ) const
814 : {
815 68 : for (RtfColorTbl::const_iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); ++it )
816 68 : if ((*it).second == rColor) {
817 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " returning " << (*it).first << " (" << rColor.GetRed() << "," << rColor.GetGreen() << "," << rColor.GetBlue() << ")");
818 62 : return (*it).first;
819 : }
820 : OSL_FAIL( "No such Color in m_aColTbl!" );
821 0 : return 0;
822 : }
823 :
824 536 : void RtfExport::InsColor( const Color& rCol )
825 : {
826 : sal_uInt16 n;
827 536 : bool bAutoColorInTable = false;
828 848 : for (RtfColorTbl::iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); ++it )
829 680 : if ((*it).second == rCol)
830 536 : return; // Already in the table
831 312 : else if ((*it).second == COL_AUTO)
832 200 : bAutoColorInTable = true;
833 168 : if (rCol.GetColor() == COL_AUTO)
834 : // COL_AUTO gets value 0
835 56 : n = 0;
836 : else
837 : {
838 : // other colors get values >0
839 112 : n = m_aColTbl.size();
840 112 : if (!bAutoColorInTable)
841 : // reserve value "0" for COL_AUTO (if COL_AUTO wasn't inserted until now)
842 56 : n++;
843 : }
844 168 : m_aColTbl.insert(std::pair<sal_uInt16,Color>( n, rCol ));
845 : }
846 :
847 36 : void RtfExport::InsColorLine( const SvxBoxItem& rBox )
848 : {
849 36 : const SvxBorderLine* pLine = 0;
850 :
851 36 : if( rBox.GetTop() )
852 36 : InsColor( (pLine = rBox.GetTop())->GetColor() );
853 36 : if( rBox.GetBottom() && pLine != rBox.GetBottom() )
854 36 : InsColor( (pLine = rBox.GetBottom())->GetColor() );
855 36 : if( rBox.GetLeft() && pLine != rBox.GetLeft() )
856 36 : InsColor( (pLine = rBox.GetLeft())->GetColor() );
857 36 : if( rBox.GetRight() && pLine != rBox.GetRight() )
858 36 : InsColor( rBox.GetRight()->GetColor() );
859 36 : }
860 56 : void RtfExport::OutColorTable()
861 : {
862 : // Build the table from rPool since the colors provided to
863 : // RtfAttributeOutput callbacks are too late.
864 : sal_uInt32 nMaxItem;
865 56 : const SfxItemPool& rPool = pDoc->GetAttrPool();
866 :
867 : // char color
868 : {
869 : const SvxColorItem* pCol = (const SvxColorItem*)GetDfltAttr(
870 56 : RES_CHRATR_COLOR );
871 56 : InsColor( pCol->GetValue() );
872 56 : if( 0 != ( pCol = (const SvxColorItem*)rPool.GetPoolDefaultItem(
873 : RES_CHRATR_COLOR ) ))
874 56 : InsColor( pCol->GetValue() );
875 56 : nMaxItem = rPool.GetItemCount2(RES_CHRATR_COLOR);
876 168 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
877 : {
878 112 : if( 0 != (pCol = (const SvxColorItem*)rPool.GetItem2(
879 : RES_CHRATR_COLOR, n ) ) )
880 0 : InsColor( pCol->GetValue() );
881 : }
882 :
883 56 : const SvxUnderlineItem* pUnder = (const SvxUnderlineItem*)GetDfltAttr( RES_CHRATR_UNDERLINE );
884 56 : InsColor( pUnder->GetColor() );
885 56 : nMaxItem = rPool.GetItemCount2(RES_CHRATR_UNDERLINE);
886 56 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
887 : {
888 0 : if( 0 != (pUnder = (const SvxUnderlineItem*)rPool.GetItem2( RES_CHRATR_UNDERLINE, n ) ) )
889 0 : InsColor( pUnder->GetColor() );
890 :
891 : }
892 :
893 56 : const SvxOverlineItem* pOver = (const SvxOverlineItem*)GetDfltAttr( RES_CHRATR_OVERLINE );
894 56 : InsColor( pOver->GetColor() );
895 56 : nMaxItem = rPool.GetItemCount2(RES_CHRATR_OVERLINE);
896 56 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
897 : {
898 0 : if( 0 != (pOver = (const SvxOverlineItem*)rPool.GetItem2( RES_CHRATR_OVERLINE, n ) ) )
899 0 : InsColor( pOver->GetColor() );
900 :
901 : }
902 :
903 : }
904 :
905 : // background color
906 : static const sal_uInt16 aBrushIds[] = {
907 : RES_BACKGROUND, RES_CHRATR_BACKGROUND, 0 };
908 :
909 168 : for( const sal_uInt16* pIds = aBrushIds; *pIds; ++pIds )
910 : {
911 112 : const SvxBrushItem* pBkgrd = (const SvxBrushItem*)GetDfltAttr( *pIds );
912 112 : InsColor( pBkgrd->GetColor() );
913 112 : if( 0 != ( pBkgrd = (const SvxBrushItem*)rPool.GetPoolDefaultItem(
914 112 : *pIds ) ))
915 : {
916 0 : InsColor( pBkgrd->GetColor() );
917 : }
918 112 : nMaxItem = rPool.GetItemCount2( *pIds );
919 112 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
920 : {
921 0 : if( 0 != (pBkgrd = (const SvxBrushItem*)rPool.GetItem2(
922 0 : *pIds , n ) ))
923 : {
924 0 : InsColor( pBkgrd->GetColor() );
925 : }
926 : }
927 : }
928 :
929 : // shadow color
930 : {
931 : const SvxShadowItem* pShadow = (const SvxShadowItem*)GetDfltAttr(
932 56 : RES_SHADOW );
933 56 : InsColor( pShadow->GetColor() );
934 56 : if( 0 != ( pShadow = (const SvxShadowItem*)rPool.GetPoolDefaultItem(
935 : RES_SHADOW ) ))
936 : {
937 0 : InsColor( pShadow->GetColor() );
938 : }
939 56 : nMaxItem = rPool.GetItemCount2(RES_SHADOW);
940 56 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
941 : {
942 0 : if( 0 != (pShadow = (const SvxShadowItem*)rPool.GetItem2(
943 : RES_SHADOW, n ) ) )
944 : {
945 0 : InsColor( pShadow->GetColor() );
946 : }
947 : }
948 : }
949 :
950 : // frame border color
951 : {
952 : const SvxBoxItem* pBox;
953 56 : if( 0 != ( pBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
954 : RES_BOX ) ))
955 0 : InsColorLine( *pBox );
956 56 : nMaxItem = rPool.GetItemCount2(RES_BOX);
957 94 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
958 : {
959 38 : if( 0 != (pBox = (const SvxBoxItem*)rPool.GetItem2( RES_BOX, n ) ))
960 36 : InsColorLine( *pBox );
961 : }
962 : }
963 :
964 224 : for (size_t n = 0; n < m_aColTbl.size(); ++n)
965 : {
966 168 : const Color& rCol = m_aColTbl[ n ];
967 168 : if( n || COL_AUTO != rCol.GetColor() )
968 : {
969 112 : Strm() << OOO_STRING_SVTOOLS_RTF_RED;
970 112 : OutULong( rCol.GetRed() ) << OOO_STRING_SVTOOLS_RTF_GREEN;
971 112 : OutULong( rCol.GetGreen() ) << OOO_STRING_SVTOOLS_RTF_BLUE;
972 112 : OutULong( rCol.GetBlue() );
973 : }
974 168 : Strm() << ';';
975 : }
976 56 : }
977 :
978 348 : void RtfExport::InsStyle( sal_uInt16 nId, const OString& rStyle )
979 : {
980 348 : m_aStyTbl.insert(std::pair<sal_uInt16,OString>(nId, rStyle) );
981 348 : }
982 :
983 132 : OString* RtfExport::GetStyle( sal_uInt16 nId )
984 : {
985 132 : std::map<sal_uInt16,OString>::iterator i = m_aStyTbl.find(nId);
986 132 : if (i != m_aStyTbl.end())
987 132 : return &i->second;
988 0 : return NULL;
989 : }
990 :
991 0 : sal_uInt16 RtfExport::GetRedline( const String& rAuthor )
992 : {
993 0 : std::map<String,sal_uInt16>::iterator i = m_aRedlineTbl.find(rAuthor);
994 0 : if (i != m_aRedlineTbl.end())
995 0 : return i->second;
996 : else
997 : {
998 0 : int nId = m_aRedlineTbl.size();
999 0 : m_aRedlineTbl.insert(std::pair<String,sal_uInt16>(rAuthor,nId));
1000 0 : return nId;
1001 : }
1002 : }
1003 :
1004 0 : const String* RtfExport::GetRedline( sal_uInt16 nId )
1005 : {
1006 0 : for(std::map<String,sal_uInt16>::iterator aIter = m_aRedlineTbl.begin(); aIter != m_aRedlineTbl.end(); ++aIter)
1007 0 : if ((*aIter).second == nId)
1008 0 : return &(*aIter).first;
1009 0 : return NULL;
1010 : }
1011 :
1012 122 : void RtfExport::OutPageDescription( const SwPageDesc& rPgDsc, sal_Bool bWriteReset, sal_Bool bCheckForFirstPage )
1013 : {
1014 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
1015 122 : const SwPageDesc *pSave = pAktPageDesc;
1016 :
1017 122 : pAktPageDesc = &rPgDsc;
1018 178 : if( bCheckForFirstPage && pAktPageDesc->GetFollow() &&
1019 56 : pAktPageDesc->GetFollow() != pAktPageDesc )
1020 4 : pAktPageDesc = pAktPageDesc->GetFollow();
1021 :
1022 122 : if( bWriteReset )
1023 : {
1024 0 : if( pCurPam->GetPoint()->nNode == pOrigPam->Start()->nNode )
1025 0 : Strm() << OOO_STRING_SVTOOLS_RTF_SECTD << OOO_STRING_SVTOOLS_RTF_SBKNONE;
1026 : else
1027 0 : Strm() << OOO_STRING_SVTOOLS_RTF_SECT << OOO_STRING_SVTOOLS_RTF_SECTD;
1028 : }
1029 :
1030 122 : if( pAktPageDesc->GetLandscape() )
1031 0 : Strm() << OOO_STRING_SVTOOLS_RTF_LNDSCPSXN;
1032 :
1033 122 : const SwFmt *pFmt = &pAktPageDesc->GetMaster(); //GetLeft();
1034 122 : bOutPageDescs = true;
1035 122 : OutputFormat(*pFmt, true, false);
1036 122 : bOutPageDescs = false;
1037 :
1038 : // normal header / footer (without a style)
1039 : const SfxPoolItem* pItem;
1040 244 : if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_HEADER, sal_False,
1041 122 : &pItem ) == SFX_ITEM_SET)
1042 122 : WriteHeaderFooter(*pItem, true);
1043 244 : if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_FOOTER, sal_False,
1044 122 : &pItem ) == SFX_ITEM_SET)
1045 122 : WriteHeaderFooter(*pItem, false);
1046 :
1047 : // title page
1048 122 : if( pAktPageDesc != &rPgDsc )
1049 : {
1050 4 : Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG;
1051 4 : pAktPageDesc = &rPgDsc;
1052 8 : if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_HEADER,
1053 4 : sal_False, &pItem ) == SFX_ITEM_SET )
1054 4 : WriteHeaderFooter(*pItem, true);
1055 8 : if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_FOOTER,
1056 4 : sal_False, &pItem ) == SFX_ITEM_SET )
1057 4 : WriteHeaderFooter(*pItem, false);
1058 : }
1059 :
1060 : // numbering type
1061 122 : AttrOutput().SectionPageNumbering(pAktPageDesc->GetNumType().GetNumberingType(), 0);
1062 :
1063 122 : pAktPageDesc = pSave;
1064 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
1065 122 : }
1066 :
1067 252 : void RtfExport::WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader)
1068 : {
1069 252 : if (bHeader)
1070 : {
1071 126 : const SwFmtHeader& rHeader = (const SwFmtHeader&)rItem;
1072 126 : if (!rHeader.IsActive())
1073 126 : return;
1074 : }
1075 : else
1076 : {
1077 126 : const SwFmtFooter& rFooter = (const SwFmtFooter&)rItem;
1078 126 : if (!rFooter.IsActive())
1079 126 : return;
1080 : }
1081 :
1082 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
1083 :
1084 0 : const sal_Char* pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADER : OOO_STRING_SVTOOLS_RTF_FOOTER);
1085 : /* is this a title page? */
1086 0 : if( pAktPageDesc->GetFollow() && pAktPageDesc->GetFollow() != pAktPageDesc )
1087 : {
1088 0 : Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG;
1089 0 : pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERF : OOO_STRING_SVTOOLS_RTF_FOOTERF);
1090 : }
1091 0 : Strm() << '{' << pStr;
1092 0 : WriteHeaderFooterText(pAktPageDesc->GetMaster(), bHeader);
1093 0 : Strm() << '}';
1094 :
1095 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
1096 : }
1097 :
1098 0 : void RtfExport::WriteHeaderFooter(const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr, bool bTitlepg)
1099 : {
1100 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
1101 :
1102 0 : m_pAttrOutput->WriteHeaderFooter_Impl( rFmt, bHeader, pStr, bTitlepg );
1103 :
1104 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
1105 0 : }
1106 :
1107 : /// Glue class to call RtfExport as an internal filter, needed by copy&paste support.
1108 : class SwRTFWriter : public Writer
1109 : {
1110 : private:
1111 : bool m_bOutOutlineOnly;
1112 :
1113 : public:
1114 : SwRTFWriter( const String& rFilterName, const String& rBaseURL );
1115 : virtual ~SwRTFWriter();
1116 : virtual sal_uLong WriteStream();
1117 : };
1118 :
1119 0 : SwRTFWriter::SwRTFWriter( const String& rFltName, const String & rBaseURL )
1120 : {
1121 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1122 0 : SetBaseURL( rBaseURL );
1123 : // export outline nodes, only (send outline to clipboard/presentation)
1124 0 : m_bOutOutlineOnly = 'O' == rFltName.GetChar( 0 );
1125 0 : }
1126 :
1127 0 : SwRTFWriter::~SwRTFWriter()
1128 0 : {}
1129 :
1130 0 : sal_uLong SwRTFWriter::WriteStream()
1131 : {
1132 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1133 0 : SwPaM aPam(*pCurPam->End(), *pCurPam->Start());
1134 0 : RtfExport aExport( NULL, pDoc, &aPam, pCurPam, this, m_bOutOutlineOnly );
1135 0 : aExport.ExportDocument( true );
1136 0 : return 0;
1137 : }
1138 :
1139 0 : extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportRTF( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
1140 : {
1141 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1142 0 : xRet = new SwRTFWriter( rFltName, rBaseURL );
1143 36 : }
1144 :
1145 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|