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 20572 : AttributeOutputBase& RtfExport::AttrOutput() const
77 : {
78 20572 : return *m_pAttrOutput;
79 : }
80 :
81 16 : MSWordSections& RtfExport::Sections() const
82 : {
83 16 : return *m_pSections;
84 : }
85 :
86 5 : RtfSdrExport& RtfExport::SdrExporter() const
87 : {
88 5 : return *m_pSdrExport;
89 : }
90 :
91 4076 : bool RtfExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
92 : {
93 : // FIXME is this actually true for rtf? - this is copied from DOCX
94 4076 : 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 4076 : else if ( nScript != i18n::ScriptType::COMPLEX )
109 : {
110 : // for western in ww8, there is only one fontsize
111 : // and one fontstyle (posture/weight)
112 4076 : switch ( nWhich )
113 : {
114 : case RES_CHRATR_CJK_FONTSIZE:
115 : case RES_CHRATR_CJK_POSTURE:
116 : case RES_CHRATR_CJK_WEIGHT:
117 891 : return false;
118 : default:
119 3185 : break;
120 : }
121 : }
122 3185 : return true;
123 : }
124 :
125 1118 : void RtfExport::AppendBookmarks( const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen )
126 : {
127 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
128 :
129 1118 : std::vector< OUString > aStarts;
130 2236 : std::vector< OUString > aEnds;
131 :
132 2236 : IMarkVector aMarks;
133 1118 : if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
134 : {
135 4 : for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
136 : it != end; ++it )
137 : {
138 2 : IMark* pMark = (*it);
139 2 : const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
140 2 : const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
141 :
142 2 : if ( nStart == nAktPos )
143 1 : aStarts.push_back( pMark->GetName() );
144 :
145 2 : if ( nEnd == nAktPos )
146 1 : aEnds.push_back( pMark->GetName() );
147 : }
148 : }
149 :
150 2236 : m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
151 1118 : }
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 1118 : void RtfExport::AppendAnnotationMarks( const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen )
167 : {
168 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
169 :
170 1118 : std::vector< OUString > aStarts;
171 2236 : std::vector< OUString > aEnds;
172 :
173 2236 : IMarkVector aMarks;
174 1118 : if ( GetAnnotationMarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
175 : {
176 23 : for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
177 : it != end; ++it )
178 : {
179 12 : IMark* pMark = (*it);
180 12 : const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
181 12 : const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
182 :
183 12 : if ( nStart == nAktPos )
184 3 : aStarts.push_back( pMark->GetName() );
185 :
186 12 : if ( nEnd == nAktPos )
187 3 : aEnds.push_back( pMark->GetName() );
188 : }
189 : }
190 :
191 2236 : m_pAttrOutput->WriteAnnotationMarks_Impl( aStarts, aEnds );
192 1118 : }
193 :
194 : //For i120928,to export graphic of bullet for RTF filter
195 56 : void RtfExport::ExportGrfBullet(const SwTxtNode&)
196 : {
197 : // Noop, would be too late, see WriteNumbering() instead.
198 56 : }
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 63 : static bool IsExportNumRule( const SwNumRule& rRule, sal_uInt8* pEnd = 0 )
208 : {
209 63 : sal_uInt8 nEnd = MAXLEVEL;
210 63 : while( nEnd-- && !rRule.GetNumFmt( nEnd ))
211 : ;
212 63 : ++nEnd;
213 :
214 : const SwNumFmt* pNFmt;
215 : sal_uInt8 nLvl;
216 :
217 203 : for( nLvl = 0; nLvl < nEnd; ++nLvl )
218 580 : if( SVX_NUM_NUMBER_NONE != ( pNFmt = &rRule.Get( nLvl ))
219 435 : ->GetNumberingType() || !pNFmt->GetPrefix().isEmpty() ||
220 285 : (!pNFmt->GetSuffix().isEmpty() && !pNFmt->GetSuffix().equals(".")) )
221 5 : break;
222 :
223 63 : if( pEnd )
224 0 : *pEnd = nEnd;
225 63 : return nLvl != nEnd;
226 : }
227 :
228 56 : void RtfExport::BuildNumbering()
229 : {
230 56 : const SwNumRuleTbl& rListTbl = pDoc->GetNumRuleTbl();
231 :
232 239 : for( sal_uInt16 n = rListTbl.size()+1; n; )
233 : {
234 : SwNumRule* pRule;
235 127 : --n;
236 127 : if( n == rListTbl.size() )
237 56 : pRule = (SwNumRule*)pDoc->GetOutlineNumRule();
238 : else
239 : {
240 71 : pRule = rListTbl[ n ];
241 71 : if( !pDoc->IsUsed( *pRule ))
242 64 : continue;
243 : }
244 :
245 63 : if( IsExportNumRule( *pRule ))
246 5 : GetId( *pRule );
247 : }
248 56 : }
249 :
250 56 : void RtfExport::WriteNumbering()
251 : {
252 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
253 :
254 56 : if ( !pUsedNumTbl )
255 108 : return; // no numbering is used
256 :
257 4 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LISTTABLE );
258 :
259 4 : CollectGrfsOfBullets();
260 4 : if (!m_vecBulletPic.empty())
261 1 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( LO_STRING_SVTOOLS_RTF_LISTPICTURE );
262 4 : BulletDefinitions();
263 4 : if (!m_vecBulletPic.empty())
264 1 : Strm().WriteChar( '}' );
265 :
266 4 : AbstractNumberingDefinitions();
267 4 : Strm().WriteChar( '}' );
268 :
269 4 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LISTOVERRIDETABLE );
270 4 : NumberingDefinitions();
271 4 : Strm().WriteChar( '}' );
272 :
273 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
274 : }
275 :
276 56 : void RtfExport::WriteRevTab()
277 : {
278 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
279 :
280 56 : int nRevAuthors = pDoc->GetRedlineTbl().size();
281 :
282 56 : if (nRevAuthors < 1)
283 112 : 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 5 : 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 5 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
315 0 : WriteHeaderFooter( rLeftFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERL );
316 :
317 5 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
318 3 : WriteHeaderFooter( rFmt, true, OOO_STRING_SVTOOLS_RTF_HEADER );
319 :
320 5 : if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
321 0 : WriteHeaderFooter( rFirstPageFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERF, true );
322 :
323 : // footers
324 5 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
325 0 : WriteHeaderFooter( rLeftFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERL );
326 :
327 5 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
328 3 : WriteHeaderFooter( rFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTER );
329 :
330 5 : if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
331 0 : WriteHeaderFooter( rFirstPageFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERF, true );
332 5 : }
333 :
334 20 : 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 20 : m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
339 20 : }
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 56 : void RtfExport::WriteFonts()
400 : {
401 56 : Strm().WriteCharPtr( SAL_NEWLINE_STRING ).WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FONTTBL );
402 56 : maFontHelper.WriteFontTable( *m_pAttrOutput );
403 56 : Strm().WriteChar( '}' );
404 56 : }
405 :
406 56 : void RtfExport::WriteStyles()
407 : {
408 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
409 56 : pStyles->OutputStylesTable();
410 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
411 56 : }
412 :
413 56 : void RtfExport::WriteFootnoteSettings()
414 : {
415 56 : const SwPageFtnInfo& rFtnInfo = pDoc->GetPageDesc(0).GetFtnInfo();
416 : // Request a separator only in case the width is larger than zero.
417 56 : bool bSeparator = double(rFtnInfo.GetWidth()) > 0;
418 :
419 56 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FTNSEP );
420 56 : if (bSeparator)
421 14 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CHFTNSEP );
422 56 : Strm().WriteChar( '}' );
423 56 : }
424 :
425 56 : void RtfExport::WriteMainText()
426 : {
427 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
428 :
429 56 : SwTableNode* pTableNode = pCurPam->GetNode()->FindTableNode();
430 56 : 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 56 : pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
439 : }
440 :
441 56 : WriteText();
442 :
443 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
444 56 : }
445 :
446 56 : void RtfExport::WriteInfo()
447 : {
448 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
449 56 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_INFO );
450 :
451 56 : SwDocShell *pDocShell(pDoc->GetDocShell());
452 56 : uno::Reference<document::XDocumentProperties> xDocProps;
453 56 : if (pDocShell) {
454 : uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
455 55 : pDocShell->GetModel(), uno::UNO_QUERY);
456 55 : xDocProps.set(xDPS->getDocumentProperties());
457 : }
458 :
459 56 : if (xDocProps.is()) {
460 55 : OutUnicode(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle(), true);
461 55 : OutUnicode(OOO_STRING_SVTOOLS_RTF_SUBJECT, xDocProps->getSubject());
462 :
463 : OutUnicode(OOO_STRING_SVTOOLS_RTF_KEYWORDS,
464 55 : ::comphelper::string::convertCommaSeparated(xDocProps->getKeywords()));
465 55 : OutUnicode(OOO_STRING_SVTOOLS_RTF_DOCCOMM, xDocProps->getDescription());
466 :
467 55 : OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getAuthor());
468 55 : OutDateTime(OOO_STRING_SVTOOLS_RTF_CREATIM, xDocProps->getCreationDate());
469 :
470 55 : OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR,xDocProps->getModifiedBy());
471 55 : OutDateTime(OOO_STRING_SVTOOLS_RTF_REVTIM, xDocProps->getModificationDate());
472 :
473 55 : OutDateTime(OOO_STRING_SVTOOLS_RTF_PRINTIM, xDocProps->getPrintDate());
474 : }
475 :
476 56 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_COMMENT ).WriteCharPtr( " " );
477 56 : 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 56 : Strm().WriteNumber((sal_Int32) LIBO_VERSION_ENCODED_IN_32BITS).WriteChar( '}' );
488 56 : Strm().WriteChar( '}' );
489 56 : }
490 :
491 56 : void RtfExport::WritePageDescTable()
492 : {
493 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
494 :
495 : // Write page descriptions (page styles)
496 56 : sal_uInt16 nSize = pDoc->GetPageDescCnt();
497 56 : if( !nSize )
498 56 : return;
499 :
500 56 : Strm().WriteCharPtr( SAL_NEWLINE_STRING );
501 56 : bOutPageDescs = true;
502 56 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCTBL );
503 128 : for( sal_uInt16 n = 0; n < nSize; ++n )
504 : {
505 72 : const SwPageDesc& rPageDesc = pDoc->GetPageDesc( n );
506 :
507 72 : Strm().WriteCharPtr( SAL_NEWLINE_STRING ).WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSC );
508 72 : OutULong( n ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCUSE );
509 72 : OutULong( rPageDesc.ReadUseOn() );
510 :
511 72 : OutPageDescription( rPageDesc, false, false );
512 :
513 : // search for the next page description
514 72 : sal_uInt16 i = nSize;
515 197 : while( i )
516 125 : if( rPageDesc.GetFollow() == &pDoc->GetPageDesc( --i ) )
517 72 : break;
518 72 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCNXT );
519 72 : OutULong( i ).WriteChar( ' ' );
520 72 : Strm().WriteCharPtr( msfilter::rtfutil::OutString( rPageDesc.GetName(), eDefaultEncoding).getStr() ).WriteCharPtr( ";}" );
521 : }
522 56 : Strm().WriteChar( '}' ).WriteCharPtr( SAL_NEWLINE_STRING );
523 56 : 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 56 : mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
528 : }
529 :
530 56 : void RtfExport::ExportDocument_Impl()
531 : {
532 : // Make the header
533 56 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RTF ).WriteChar( '1' )
534 56 : .WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ANSI );
535 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_DEFF );
536 56 : OutULong( maFontHelper.GetId( (SvxFontItem&)pDoc->GetAttrPool().GetDefaultItem(
537 56 : RES_CHRATR_FONT ) ));
538 : // If this not exist, MS don't understand our ansi characters (0x80-0xff).
539 56 : Strm().WriteCharPtr( "\\adeflang1025" );
540 :
541 : // Font table
542 56 : WriteFonts();
543 :
544 56 : pStyles = new MSWordStyles( *this );
545 : // Color and stylesheet table
546 56 : WriteStyles();
547 :
548 : // List table
549 56 : BuildNumbering();
550 56 : WriteNumbering();
551 :
552 56 : WriteRevTab();
553 :
554 56 : WriteInfo();
555 : // Default TabSize
556 56 : Strm().WriteCharPtr( m_pAttrOutput->m_aTabStop.makeStringAndClear().getStr() ).WriteCharPtr( SAL_NEWLINE_STRING );
557 : // Zoom
558 56 : SwViewShell *pViewShell(pDoc->GetCurrentViewShell());
559 56 : if (pViewShell && pViewShell->GetViewOptions()->GetZoomType() == SVX_ZOOM_PERCENT)
560 : {
561 50 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_VIEWSCALE );
562 50 : OutULong(pViewShell->GetViewOptions()->GetZoom());
563 : }
564 : // Record changes?
565 56 : if (nsRedlineMode_t::REDLINE_ON & mnRedlineMode)
566 1 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_REVISIONS );
567 : // Init sections
568 56 : m_pSections = new MSWordSections( *this );
569 :
570 : // Page description
571 56 : 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 56 : const SfxItemPool& rPool = pDoc->GetAttrPool();
579 56 : sal_uInt32 const nMaxItem = rPool.GetItemCount2(RES_PROTECT);
580 56 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
581 : {
582 1 : const SvxProtectItem* pProtect = (const SvxProtectItem*)rPool.GetItem2(RES_PROTECT, n);
583 1 : if (pProtect && pProtect->IsCntntProtected())
584 : {
585 1 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FORMPROT );
586 1 : break;
587 : }
588 : }
589 : }
590 :
591 : // enable form field shading
592 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FORMSHADE );
593 :
594 : // size and empty margins of the page
595 56 : if( pDoc->GetPageDescCnt() )
596 : {
597 : // Seeking the first SwFmtPageDesc. If no set, the default is valid
598 56 : const SwFmtPageDesc* pSttPgDsc = 0;
599 : {
600 56 : const SwNode& rSttNd = *pDoc->GetNodes()[
601 112 : pDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 ];
602 56 : const SfxItemSet* pSet = 0;
603 :
604 56 : if( rSttNd.IsCntntNode() )
605 53 : pSet = &rSttNd.GetCntntNode()->GetSwAttrSet();
606 3 : else if( rSttNd.IsTableNode() )
607 3 : pSet = &rSttNd.GetTableNode()->GetTable().
608 3 : GetFrmFmt()->GetAttrSet();
609 0 : else if( rSttNd.IsSectionNode() )
610 0 : pSet = &rSttNd.GetSectionNode()->GetSection().
611 0 : GetFmt()->GetAttrSet();
612 :
613 56 : if( pSet )
614 : {
615 : sal_uInt16 nPosInDoc;
616 56 : pSttPgDsc = (SwFmtPageDesc*)&pSet->Get( RES_PAGEDESC );
617 56 : if( !pSttPgDsc->GetPageDesc() )
618 10 : pSttPgDsc = 0;
619 92 : else if( pDoc->FindPageDescByName( pSttPgDsc->
620 92 : GetPageDesc()->GetName(), &nPosInDoc ))
621 : {
622 46 : Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCNO );
623 46 : OutULong( nPosInDoc ).WriteChar( '}' );
624 : }
625 : }
626 : }
627 : const SwPageDesc& rPageDesc = pSttPgDsc ? *pSttPgDsc->GetPageDesc()
628 56 : : pDoc->GetPageDesc( 0 );
629 56 : const SwFrmFmt &rFmtPage = rPageDesc.GetMaster();
630 :
631 : {
632 56 : if( rPageDesc.GetLandscape() )
633 0 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LANDSCAPE );
634 :
635 56 : 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 56 : 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 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PAPERH );
648 56 : OutULong( rSz.GetHeight() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PAPERW );
649 56 : OutULong( rSz.GetWidth() );
650 : }
651 : }
652 :
653 : {
654 56 : const SvxLRSpaceItem& rLR = rFmtPage.GetLRSpace();
655 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGL );
656 56 : OutLong( rLR.GetLeft() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGR );
657 56 : OutLong( rLR.GetRight() );
658 : }
659 :
660 : {
661 56 : const SvxULSpaceItem& rUL = rFmtPage.GetULSpace();
662 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGT );
663 56 : OutLong( rUL.GetUpper() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGB );
664 56 : OutLong( rUL.GetLower() );
665 : }
666 :
667 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SECTD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SBKNONE );
668 : // All sections are unlocked by default
669 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED );
670 56 : OutLong(1);
671 56 : OutPageDescription( rPageDesc, false, true ); // Changed bCheckForFirstPage to sal_True so headers
672 : // following title page are correctly added - i13107
673 56 : if( pSttPgDsc )
674 : {
675 46 : pAktPageDesc = &rPageDesc;
676 : }
677 : }
678 :
679 : // line numbering
680 56 : const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo();
681 56 : if ( rLnNumInfo.IsPaintLineNumbers() )
682 1 : AttrOutput().SectionLineNumbering( 0, rLnNumInfo );
683 :
684 : {
685 : // write the footnotes and endnotes-out Info
686 56 : const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
687 :
688 56 : const char* pOut = FTNPOS_CHAPTER == rFtnInfo.ePos
689 : ? OOO_STRING_SVTOOLS_RTF_ENDDOC
690 56 : : OOO_STRING_SVTOOLS_RTF_FTNBJ;
691 56 : Strm().WriteCharPtr( pOut ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FTNSTART );
692 56 : OutLong( rFtnInfo.nFtnOffset + 1 );
693 :
694 56 : switch( rFtnInfo.eNum )
695 : {
696 1 : case FTNNUM_PAGE: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTPG; break;
697 55 : case FTNNUM_DOC: pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTCONT; break;
698 0 : default: pOut = OOO_STRING_SVTOOLS_RTF_FTNRESTART; break;
699 : }
700 56 : Strm().WriteCharPtr( pOut );
701 :
702 56 : 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 56 : default: pOut = OOO_STRING_SVTOOLS_RTF_FTNNAR; break;
712 : }
713 56 : Strm().WriteCharPtr( pOut );
714 :
715 56 : const SwEndNoteInfo& rEndNoteInfo = pDoc->GetEndNoteInfo();
716 :
717 56 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_AENDDOC ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_AFTNRSTCONT )
718 56 : .WriteCharPtr( OOO_STRING_SVTOOLS_RTF_AFTNSTART );
719 56 : OutLong( rEndNoteInfo.nFtnOffset + 1 );
720 :
721 56 : 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 55 : 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 1 : default: pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAR; break;
731 : }
732 56 : Strm().WriteCharPtr( pOut );
733 : }
734 :
735 56 : Strm().WriteCharPtr( SAL_NEWLINE_STRING );
736 :
737 56 : WriteFootnoteSettings();
738 :
739 56 : WriteMainText();
740 :
741 56 : Strm().WriteChar( '}' );
742 56 : }
743 :
744 8 : 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 8 : const SwSectionFmt* pFmt = GetSectionFormat( rNd );
750 8 : const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
751 :
752 : OSL_ENSURE( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
753 :
754 8 : if ( pNewPgDescFmt )
755 7 : m_pSections->AppendSection( *pNewPgDescFmt, rNd, pFmt, nLnNm );
756 1 : else if ( pNewPgDesc )
757 1 : 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 8 : if (!m_pAttrOutput->m_pPrevPageDesc || m_pAttrOutput->m_pPrevPageDesc->GetFollow() != pNewPgDesc)
761 5 : AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
762 8 : }
763 :
764 379 : bool RtfExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
765 : {
766 379 : bool bRet( false );
767 :
768 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
769 :
770 379 : if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
771 : {
772 378 : if (const SwFmt *pParent = rFmt.DerivedFrom())
773 : {
774 378 : 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 379 : 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 521 : void RtfExport::OutputTextNode( const SwTxtNode& rNode )
807 : {
808 521 : m_nCurrentNodeIndex = rNode.GetIndex();
809 521 : if ( !m_bOutOutlineOnly || rNode.IsOutline( ) )
810 521 : MSWordExportBase::OutputTextNode( rNode );
811 521 : m_nCurrentNodeIndex = 0;
812 521 : }
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 56 : 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 56 : sw::ms::rtl_TextEncodingToWinCharset(DEF_ENCODING))),
833 : eCurrentEncoding(eDefaultEncoding),
834 : bRTFFlySyntax(false),
835 112 : m_nCurrentNodeIndex(0)
836 : {
837 56 : mbExportModeRTF = true;
838 : // the attribute output for the document
839 56 : m_pAttrOutput.reset(new RtfAttributeOutput(*this));
840 : // that just causes problems for RTF
841 56 : bSubstituteBullets = false;
842 : // needed to have a complete font table
843 56 : maFontHelper.bLoadAllFonts = true;
844 : // the related SdrExport
845 56 : m_pSdrExport.reset(new RtfSdrExport(*this));
846 :
847 56 : if (!m_pWriter)
848 55 : m_pWriter = &m_pFilter->m_aWriter;
849 56 : }
850 :
851 56 : RtfExport::~RtfExport()
852 : {
853 56 : }
854 :
855 16396 : SvStream& RtfExport::Strm()
856 : {
857 16396 : return m_pWriter->Strm();
858 : }
859 :
860 3503 : SvStream& RtfExport::OutULong( sal_uLong nVal )
861 : {
862 3503 : return m_pWriter->OutULong( Strm(), nVal );
863 : }
864 :
865 624 : SvStream& RtfExport::OutLong( long nVal )
866 : {
867 624 : return m_pWriter->OutLong( Strm(), nVal );
868 : }
869 :
870 330 : void RtfExport::OutUnicode(const sal_Char *pToken, const OUString &rContent, bool bUpr)
871 : {
872 330 : if (!rContent.isEmpty())
873 : {
874 16 : if (!bUpr)
875 : {
876 13 : Strm().WriteChar( '{' ).WriteCharPtr( pToken ).WriteChar( ' ' );
877 13 : Strm().WriteCharPtr( msfilter::rtfutil::OutString( rContent, eCurrentEncoding ).getStr() );
878 13 : Strm().WriteChar( '}' );
879 : }
880 : else
881 3 : Strm().WriteCharPtr( msfilter::rtfutil::OutStringUpr(pToken, rContent, eCurrentEncoding).getStr() );
882 : }
883 330 : }
884 :
885 165 : void RtfExport::OutDateTime(const sal_Char* pStr, const util::DateTime& rDT )
886 : {
887 165 : Strm().WriteChar( '{' ).WriteCharPtr( pStr ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_YR );
888 165 : OutULong( rDT.Year ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MO );
889 165 : OutULong( rDT.Month ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_DY );
890 165 : OutULong( rDT.Day ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_HR );
891 165 : OutULong( rDT.Hours ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MIN );
892 165 : OutULong( rDT.Minutes ).WriteChar( '}' );
893 165 : }
894 :
895 649 : sal_uInt16 RtfExport::GetColor( const Color& rColor ) const
896 : {
897 1235 : for (RtfColorTbl::const_iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); ++it )
898 1235 : if ((*it).second == rColor) {
899 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " returning " << (*it).first << " (" << rColor.GetRed() << "," << rColor.GetGreen() << "," << rColor.GetBlue() << ")");
900 649 : return (*it).first;
901 : }
902 : OSL_FAIL( "No such Color in m_aColTbl!" );
903 0 : return 0;
904 : }
905 :
906 618 : void RtfExport::InsColor( const Color& rCol )
907 : {
908 : sal_uInt16 n;
909 618 : bool bAutoColorInTable = false;
910 1112 : for (RtfColorTbl::iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); ++it )
911 926 : if ((*it).second == rCol)
912 1050 : return; // Already in the table
913 494 : else if ((*it).second == COL_AUTO)
914 265 : bAutoColorInTable = true;
915 186 : if (rCol.GetColor() == COL_AUTO)
916 : // COL_AUTO gets value 0
917 56 : n = 0;
918 : else
919 : {
920 : // other colors get values >0
921 130 : n = m_aColTbl.size();
922 130 : if (!bAutoColorInTable)
923 : // reserve value "0" for COL_AUTO (if COL_AUTO wasn't inserted until now)
924 57 : n++;
925 : }
926 186 : m_aColTbl.insert(std::pair<sal_uInt16,Color>( n, rCol ));
927 : }
928 :
929 56 : void RtfExport::InsColorLine( const SvxBoxItem& rBox )
930 : {
931 56 : const SvxBorderLine* pLine = 0;
932 :
933 56 : if( rBox.GetTop() )
934 45 : InsColor( (pLine = rBox.GetTop())->GetColor() );
935 56 : if( rBox.GetBottom() && pLine != rBox.GetBottom() )
936 51 : InsColor( (pLine = rBox.GetBottom())->GetColor() );
937 56 : if( rBox.GetLeft() && pLine != rBox.GetLeft() )
938 50 : InsColor( (pLine = rBox.GetLeft())->GetColor() );
939 56 : if( rBox.GetRight() && pLine != rBox.GetRight() )
940 46 : InsColor( rBox.GetRight()->GetColor() );
941 56 : }
942 56 : 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 56 : const SfxItemPool& rPool = pDoc->GetAttrPool();
948 :
949 : // char color
950 : {
951 : const SvxColorItem* pCol = (const SvxColorItem*)GetDfltAttr(
952 56 : RES_CHRATR_COLOR );
953 56 : InsColor( pCol->GetValue() );
954 56 : if( 0 != ( pCol = (const SvxColorItem*)rPool.GetPoolDefaultItem(
955 : RES_CHRATR_COLOR ) ))
956 55 : InsColor( pCol->GetValue() );
957 56 : nMaxItem = rPool.GetItemCount2(RES_CHRATR_COLOR);
958 170 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
959 : {
960 114 : if( 0 != (pCol = (const SvxColorItem*)rPool.GetItem2(
961 : RES_CHRATR_COLOR, n ) ) )
962 15 : InsColor( pCol->GetValue() );
963 : }
964 :
965 56 : const SvxUnderlineItem* pUnder = (const SvxUnderlineItem*)GetDfltAttr( RES_CHRATR_UNDERLINE );
966 56 : InsColor( pUnder->GetColor() );
967 56 : nMaxItem = rPool.GetItemCount2(RES_CHRATR_UNDERLINE);
968 64 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
969 : {
970 8 : if( 0 != (pUnder = (const SvxUnderlineItem*)rPool.GetItem2( RES_CHRATR_UNDERLINE, n ) ) )
971 8 : InsColor( pUnder->GetColor() );
972 :
973 : }
974 :
975 56 : const SvxOverlineItem* pOver = (const SvxOverlineItem*)GetDfltAttr( RES_CHRATR_OVERLINE );
976 56 : InsColor( pOver->GetColor() );
977 56 : nMaxItem = rPool.GetItemCount2(RES_CHRATR_OVERLINE);
978 57 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
979 : {
980 1 : if( 0 != (pOver = (const SvxOverlineItem*)rPool.GetItem2( RES_CHRATR_OVERLINE, n ) ) )
981 1 : 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 168 : for( const sal_uInt16* pIds = aBrushIds; *pIds; ++pIds )
992 : {
993 112 : const SvxBrushItem* pBkgrd = (const SvxBrushItem*)GetDfltAttr( *pIds );
994 112 : InsColor( pBkgrd->GetColor() );
995 112 : if( 0 != ( pBkgrd = (const SvxBrushItem*)rPool.GetPoolDefaultItem(
996 112 : *pIds ) ))
997 : {
998 0 : InsColor( pBkgrd->GetColor() );
999 : }
1000 112 : nMaxItem = rPool.GetItemCount2( *pIds );
1001 117 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
1002 : {
1003 5 : if( 0 != (pBkgrd = (const SvxBrushItem*)rPool.GetItem2(
1004 5 : *pIds , n ) ))
1005 : {
1006 5 : InsColor( pBkgrd->GetColor() );
1007 : }
1008 : }
1009 : }
1010 :
1011 : // shadow color
1012 : {
1013 : const SvxShadowItem* pShadow = (const SvxShadowItem*)GetDfltAttr(
1014 56 : RES_SHADOW );
1015 56 : InsColor( pShadow->GetColor() );
1016 56 : if( 0 != ( pShadow = (const SvxShadowItem*)rPool.GetPoolDefaultItem(
1017 : RES_SHADOW ) ))
1018 : {
1019 0 : InsColor( pShadow->GetColor() );
1020 : }
1021 56 : nMaxItem = rPool.GetItemCount2(RES_SHADOW);
1022 62 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
1023 : {
1024 6 : if( 0 != (pShadow = (const SvxShadowItem*)rPool.GetItem2(
1025 : RES_SHADOW, n ) ) )
1026 : {
1027 6 : InsColor( pShadow->GetColor() );
1028 : }
1029 : }
1030 : }
1031 :
1032 : // frame border color
1033 : {
1034 : const SvxBoxItem* pBox;
1035 56 : if( 0 != ( pBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
1036 : RES_BOX ) ))
1037 0 : InsColorLine( *pBox );
1038 56 : nMaxItem = rPool.GetItemCount2(RES_BOX);
1039 118 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
1040 : {
1041 62 : if( 0 != (pBox = (const SvxBoxItem*)rPool.GetItem2( RES_BOX, n ) ))
1042 54 : InsColorLine( *pBox );
1043 : }
1044 : }
1045 :
1046 : {
1047 : const SvxBoxItem* pCharBox;
1048 56 : if( 0 != ( pCharBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
1049 : RES_CHRATR_BOX ) ))
1050 0 : InsColorLine( *pCharBox );
1051 56 : nMaxItem = rPool.GetItemCount2(RES_CHRATR_BOX);
1052 60 : for (sal_uInt32 n = 0; n < nMaxItem; ++n)
1053 : {
1054 4 : if( 0 != (pCharBox = (const SvxBoxItem*)rPool.GetItem2( RES_CHRATR_BOX, n ) ))
1055 2 : InsColorLine( *pCharBox );
1056 : }
1057 : }
1058 :
1059 242 : for (size_t n = 0; n < m_aColTbl.size(); ++n)
1060 : {
1061 186 : const Color& rCol = m_aColTbl[ n ];
1062 186 : if( n || COL_AUTO != rCol.GetColor() )
1063 : {
1064 130 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RED );
1065 130 : OutULong( rCol.GetRed() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_GREEN );
1066 130 : OutULong( rCol.GetGreen() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_BLUE );
1067 130 : OutULong( rCol.GetBlue() );
1068 : }
1069 186 : Strm().WriteChar( ';' );
1070 : }
1071 56 : }
1072 :
1073 482 : void RtfExport::InsStyle( sal_uInt16 nId, const OString& rStyle )
1074 : {
1075 482 : m_aStyTbl.insert(std::pair<sal_uInt16,OString>(nId, rStyle) );
1076 482 : }
1077 :
1078 569 : OString* RtfExport::GetStyle( sal_uInt16 nId )
1079 : {
1080 569 : std::map<sal_uInt16,OString>::iterator i = m_aStyTbl.find(nId);
1081 569 : if (i != m_aStyTbl.end())
1082 527 : return &i->second;
1083 42 : 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 128 : void RtfExport::OutPageDescription( const SwPageDesc& rPgDsc, bool bWriteReset, bool bCheckForFirstPage )
1108 : {
1109 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
1110 128 : const SwPageDesc *pSave = pAktPageDesc;
1111 :
1112 128 : pAktPageDesc = &rPgDsc;
1113 184 : if( bCheckForFirstPage && pAktPageDesc->GetFollow() &&
1114 56 : pAktPageDesc->GetFollow() != pAktPageDesc )
1115 3 : pAktPageDesc = pAktPageDesc->GetFollow();
1116 :
1117 128 : 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 128 : if( pAktPageDesc->GetLandscape() )
1126 0 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LNDSCPSXN );
1127 :
1128 128 : const SwFmt *pFmt = &pAktPageDesc->GetMaster(); //GetLeft();
1129 128 : bOutPageDescs = true;
1130 128 : OutputFormat(*pFmt, true, false);
1131 128 : bOutPageDescs = false;
1132 :
1133 : // normal header / footer (without a style)
1134 : const SfxPoolItem* pItem;
1135 256 : if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_HEADER, false,
1136 128 : &pItem ) == SFX_ITEM_SET)
1137 126 : WriteHeaderFooter(*pItem, true);
1138 256 : if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_FOOTER, false,
1139 128 : &pItem ) == SFX_ITEM_SET)
1140 126 : WriteHeaderFooter(*pItem, false);
1141 :
1142 : // title page
1143 128 : if( pAktPageDesc != &rPgDsc )
1144 : {
1145 3 : Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TITLEPG );
1146 3 : pAktPageDesc = &rPgDsc;
1147 6 : if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_HEADER,
1148 3 : false, &pItem ) == SFX_ITEM_SET )
1149 3 : WriteHeaderFooter(*pItem, true);
1150 6 : if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_FOOTER,
1151 3 : false, &pItem ) == SFX_ITEM_SET )
1152 3 : WriteHeaderFooter(*pItem, false);
1153 : }
1154 :
1155 : // numbering type
1156 128 : AttrOutput().SectionPageNumbering(pAktPageDesc->GetNumType().GetNumberingType(), boost::none);
1157 :
1158 128 : pAktPageDesc = pSave;
1159 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
1160 128 : }
1161 :
1162 258 : void RtfExport::WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader)
1163 : {
1164 258 : if (bHeader)
1165 : {
1166 129 : const SwFmtHeader& rHeader = (const SwFmtHeader&)rItem;
1167 129 : if (!rHeader.IsActive())
1168 124 : return;
1169 : }
1170 : else
1171 : {
1172 129 : const SwFmtFooter& rFooter = (const SwFmtFooter&)rItem;
1173 129 : if (!rFooter.IsActive())
1174 122 : return;
1175 : }
1176 :
1177 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
1178 :
1179 12 : const sal_Char* pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADER : OOO_STRING_SVTOOLS_RTF_FOOTER);
1180 : /* is this a title page? */
1181 12 : 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 12 : Strm().WriteChar( '{' ).WriteCharPtr( pStr );
1187 12 : WriteHeaderFooterText(pAktPageDesc->GetMaster(), bHeader);
1188 12 : Strm().WriteChar( '}' );
1189 :
1190 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
1191 : }
1192 :
1193 6 : 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 6 : m_pAttrOutput->WriteHeaderFooter_Impl( rFmt, bHeader, pStr, bTitlepg );
1198 :
1199 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
1200 6 : }
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 1 : SwRTFWriter::SwRTFWriter( const OUString& rFltName, const OUString & rBaseURL )
1215 : {
1216 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1217 1 : SetBaseURL( rBaseURL );
1218 : // export outline nodes, only (send outline to clipboard/presentation)
1219 1 : m_bOutOutlineOnly = rFltName.startsWith("O");
1220 1 : }
1221 :
1222 2 : SwRTFWriter::~SwRTFWriter()
1223 2 : {}
1224 :
1225 1 : sal_uLong SwRTFWriter::WriteStream()
1226 : {
1227 : SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1228 1 : SwPaM aPam(*pCurPam->End(), *pCurPam->Start());
1229 2 : RtfExport aExport( NULL, pDoc, &aPam, pCurPam, this, m_bOutOutlineOnly );
1230 1 : aExport.ExportDocument( true );
1231 2 : return 0;
1232 : }
1233 :
1234 1 : 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 1 : xRet = new SwRTFWriter( rFltName, rBaseURL );
1238 34 : }
1239 :
1240 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|