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