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