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