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 <cstring>
21 : #include "rtfattributeoutput.hxx"
22 : #include "rtfsdrexport.hxx"
23 : #include "writerwordglue.hxx"
24 : #include "ww8par.hxx"
25 : #include "fmtcntnt.hxx"
26 : #include "fchrfmt.hxx"
27 : #include <svtools/rtfkeywd.hxx>
28 : #include <editeng/fontitem.hxx>
29 : #include <editeng/tstpitem.hxx>
30 : #include <editeng/adjustitem.hxx>
31 : #include <editeng/spltitem.hxx>
32 : #include <editeng/widwitem.hxx>
33 : #include <editeng/keepitem.hxx>
34 : #include <editeng/brushitem.hxx>
35 : #include <editeng/postitem.hxx>
36 : #include <editeng/wghtitem.hxx>
37 : #include <editeng/kernitem.hxx>
38 : #include <editeng/crossedoutitem.hxx>
39 : #include <editeng/cmapitem.hxx>
40 : #include <editeng/wrlmitem.hxx>
41 : #include <editeng/udlnitem.hxx>
42 : #include <editeng/langitem.hxx>
43 : #include <editeng/escapementitem.hxx>
44 : #include <editeng/fhgtitem.hxx>
45 : #include <editeng/colritem.hxx>
46 : #include <editeng/hyphenzoneitem.hxx>
47 : #include <editeng/ulspitem.hxx>
48 : #include <editeng/boxitem.hxx>
49 : #include <editeng/contouritem.hxx>
50 : #include <editeng/shdditem.hxx>
51 : #include <editeng/autokernitem.hxx>
52 : #include <editeng/emphasismarkitem.hxx>
53 : #include <editeng/twolinesitem.hxx>
54 : #include <editeng/charscaleitem.hxx>
55 : #include <editeng/charrotateitem.hxx>
56 : #include <editeng/charreliefitem.hxx>
57 : #include <editeng/paravertalignitem.hxx>
58 : #include <editeng/frmdiritem.hxx>
59 : #include <editeng/blinkitem.hxx>
60 : #include <editeng/charhiddenitem.hxx>
61 : #include <editeng/shaditem.hxx>
62 : #include <editeng/opaqitem.hxx>
63 : #include <svx/fmglob.hxx>
64 : #include <svx/svdouno.hxx>
65 : #include <filter/msfilter/rtfutil.hxx>
66 : #include <sfx2/sfxbasemodel.hxx>
67 : #include <svx/xflgrit.hxx>
68 : #include <drawdoc.hxx>
69 : #include <docufld.hxx>
70 : #include <fmtclds.hxx>
71 : #include <fmtinfmt.hxx>
72 : #include <fmtftn.hxx>
73 : #include <fmtrowsplt.hxx>
74 : #include <fmtline.hxx>
75 : #include <fmtanchr.hxx>
76 : #include <htmltbl.hxx>
77 : #include <ndgrf.hxx>
78 : #include <ndtxt.hxx>
79 : #include <pagedesc.hxx>
80 : #include <swmodule.hxx>
81 : #include <txtftn.hxx>
82 : #include <txtinet.hxx>
83 : #include <grfatr.hxx>
84 : #include <ndole.hxx>
85 : #include <lineinfo.hxx>
86 : #include <rtf.hxx>
87 : #include <IDocumentDrawModelAccess.hxx>
88 : #include <vcl/cvtgrf.hxx>
89 : #include <oox/mathml/export.hxx>
90 : #include <com/sun/star/i18n/ScriptType.hpp>
91 :
92 : using ::editeng::SvxBorderLine;
93 : using namespace nsSwDocInfoSubType;
94 : using namespace nsFieldFlags;
95 : using namespace sw::util;
96 : using namespace ::com::sun::star;
97 :
98 906 : static OString OutTBLBorderLine(RtfExport& rExport, const SvxBorderLine* pLine, const sal_Char* pStr)
99 : {
100 906 : OStringBuffer aRet;
101 906 : if (!pLine->isEmpty())
102 : {
103 906 : aRet.append(pStr);
104 : // single line
105 906 : switch (pLine->GetBorderLineStyle())
106 : {
107 : case table::BorderLineStyle::SOLID:
108 : {
109 906 : if (DEF_LINE_WIDTH_0 == pLine->GetWidth())
110 764 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRHAIR);
111 : else
112 142 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRS);
113 : }
114 906 : break;
115 : case table::BorderLineStyle::DOTTED:
116 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDOT);
117 0 : break;
118 : case table::BorderLineStyle::DASHED:
119 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDASH);
120 0 : break;
121 : case table::BorderLineStyle::DOUBLE:
122 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDB);
123 0 : break;
124 : case table::BorderLineStyle::THINTHICK_SMALLGAP:
125 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHSG);
126 0 : break;
127 : case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
128 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHMG);
129 0 : break;
130 : case table::BorderLineStyle::THINTHICK_LARGEGAP:
131 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHLG);
132 0 : break;
133 : case table::BorderLineStyle::THICKTHIN_SMALLGAP:
134 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNSG);
135 0 : break;
136 : case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
137 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNMG);
138 0 : break;
139 : case table::BorderLineStyle::THICKTHIN_LARGEGAP:
140 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNLG);
141 0 : break;
142 : case table::BorderLineStyle::EMBOSSED:
143 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDREMBOSS);
144 0 : break;
145 : case table::BorderLineStyle::ENGRAVED:
146 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRENGRAVE);
147 0 : break;
148 : case table::BorderLineStyle::OUTSET:
149 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDROUTSET);
150 0 : break;
151 : case table::BorderLineStyle::INSET:
152 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRINSET);
153 0 : break;
154 : case table::BorderLineStyle::NONE:
155 : default:
156 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRNONE);
157 0 : break;
158 : }
159 :
160 906 : double const fConverted(::editeng::ConvertBorderWidthToWord(pLine->GetBorderLineStyle(), pLine->GetWidth()));
161 906 : if (255 >= pLine->GetWidth()) // That value comes from RTF specs
162 : {
163 906 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW).append(static_cast<sal_Int32>(fConverted));
164 : }
165 : else
166 : {
167 : // use \brdrth to double the value range...
168 0 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTH OOO_STRING_SVTOOLS_RTF_BRDRW);
169 0 : aRet.append(static_cast<sal_Int32>(fConverted) / 2);
170 : }
171 :
172 906 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRCF);
173 906 : aRet.append((sal_Int32)rExport.GetColor(pLine->GetColor()));
174 : }
175 906 : return aRet.makeStringAndClear();
176 : }
177 :
178 106 : static OString OutBorderLine(RtfExport& rExport, const SvxBorderLine* pLine,
179 : const sal_Char* pStr, sal_uInt16 nDist, SvxShadowLocation eShadowLocation = SVX_SHADOW_NONE)
180 : {
181 106 : OStringBuffer aRet;
182 106 : aRet.append(OutTBLBorderLine(rExport, pLine, pStr));
183 106 : aRet.append(OOO_STRING_SVTOOLS_RTF_BRSP);
184 106 : aRet.append((sal_Int32)nDist);
185 106 : if (eShadowLocation == SVX_SHADOW_BOTTOMRIGHT)
186 12 : aRet.append(LO_STRING_SVTOOLS_RTF_BRDRSH);
187 106 : return aRet.makeStringAndClear();
188 : }
189 :
190 1388 : void RtfAttributeOutput::RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript)
191 : {
192 : /*
193 : You would have thought that
194 : m_rExport.Strm() << (bIsRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficient here ,
195 : but looks like word needs to see the other directional token to be
196 : satisified that all is kosher, otherwise it seems in ver 2003 to go and
197 : semi-randomlyly stick strike through about the place. Perhaps
198 : strikethrough is some ms developers "something is wrong signal" debugging
199 : code that we're triggering ?
200 : */
201 1388 : if (bIsRTL)
202 : {
203 0 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
204 0 : m_aStylesEnd.append(' ');
205 0 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
206 : }
207 : else
208 : {
209 1388 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
210 1388 : m_aStylesEnd.append(' ');
211 1388 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
212 : }
213 :
214 1388 : switch (nScript)
215 : {
216 : case i18n::ScriptType::LATIN:
217 1292 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
218 1292 : break;
219 : case i18n::ScriptType::ASIAN:
220 2 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_DBCH);
221 2 : break;
222 : case i18n::ScriptType::COMPLEX:
223 : /* noop */
224 0 : break;
225 : default:
226 : /* should not happen? */
227 94 : break;
228 : }
229 1388 : }
230 :
231 1174 : void RtfAttributeOutput::StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo)
232 : {
233 : // Output table/table row/table cell starts if needed
234 1174 : if (pTextNodeInfo.get())
235 : {
236 380 : sal_uInt32 nRow = pTextNodeInfo->getRow();
237 380 : sal_uInt32 nCell = pTextNodeInfo->getCell();
238 :
239 : // New cell/row?
240 380 : if (m_nTableDepth > 0 && !m_bTableCellOpen)
241 : {
242 292 : ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner(pTextNodeInfo->getInnerForDepth(m_nTableDepth));
243 : OSL_ENSURE(pDeepInner, "TableNodeInfoInner not found");
244 : // Make sure we always start a row between ending one and starting a cell.
245 : // In case of subtables, we may not get the first cell.
246 292 : if (pDeepInner && (pDeepInner->getCell() == 0 || m_bTableRowEnded))
247 : {
248 78 : m_bTableRowEnded = false;
249 78 : StartTableRow(pDeepInner);
250 : }
251 :
252 292 : StartTableCell(pDeepInner);
253 : }
254 :
255 : // Again, if depth was incremented, start a new table even if we skipped the first cell.
256 380 : if ((nRow == 0 && nCell == 0) || (m_nTableDepth == 0 && pTextNodeInfo->getDepth()))
257 : {
258 : // Do we have to start the table?
259 : // [If we are at the right depth already, it means that we
260 : // continue the table cell]
261 40 : sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
262 :
263 40 : if (nCurrentDepth > m_nTableDepth)
264 : {
265 : // Start all the tables that begin here
266 80 : for (sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth)
267 : {
268 40 : ww8::WW8TableNodeInfoInner::Pointer_t pInner(pTextNodeInfo->getInnerForDepth(nDepth));
269 :
270 40 : m_bLastTable = (nDepth == pTextNodeInfo->getDepth());
271 40 : StartTable(pInner);
272 40 : StartTableRow(pInner);
273 40 : StartTableCell(pInner);
274 40 : }
275 :
276 40 : m_nTableDepth = nCurrentDepth;
277 : }
278 : }
279 : }
280 :
281 : OSL_ENSURE(m_aRun.getLength() == 0, "m_aRun is not empty");
282 1174 : }
283 :
284 1174 : void RtfAttributeOutput::EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)
285 : {
286 1174 : bool bLastPara = false;
287 1174 : if (m_rExport.nTxtTyp == TXT_FTN || m_rExport.nTxtTyp == TXT_EDN)
288 : {
289 : // We're ending a paragraph that is the last paragraph of a footnote or endnote.
290 6 : bLastPara = m_rExport.m_nCurrentNodeIndex && m_rExport.m_nCurrentNodeIndex == m_rExport.pCurPam->End()->nNode.GetIndex();
291 : }
292 :
293 1174 : FinishTableRowCell(pTextNodeInfoInner);
294 :
295 1174 : RtfStringBuffer aParagraph;
296 :
297 1174 : aParagraph.appendAndClear(m_aRun);
298 1174 : aParagraph->append(m_aAfterRuns.makeStringAndClear());
299 1174 : if (m_bTblAfterCell)
300 332 : m_bTblAfterCell = false;
301 : else
302 : {
303 842 : aParagraph->append(SAL_NEWLINE_STRING);
304 : // RTF_PAR at the end of the footnote would cause an additional empty paragraph.
305 842 : if (!bLastPara)
306 : {
307 836 : aParagraph->append(OOO_STRING_SVTOOLS_RTF_PAR);
308 836 : aParagraph->append(' ');
309 : }
310 : }
311 1174 : if (m_nColBreakNeeded)
312 : {
313 14 : aParagraph->append(OOO_STRING_SVTOOLS_RTF_COLUMN);
314 14 : m_nColBreakNeeded = false;
315 : }
316 :
317 1174 : if (!m_bBufferSectionHeaders)
318 1156 : aParagraph.makeStringAndClear(this);
319 : else
320 18 : m_aSectionHeaders.append(aParagraph.makeStringAndClear());
321 1174 : }
322 :
323 0 : void RtfAttributeOutput::EmptyParagraph()
324 : {
325 0 : m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PAR).WriteChar(' ');
326 0 : }
327 :
328 1174 : void RtfAttributeOutput::SectionBreaks(const SwTxtNode& rNode)
329 : {
330 : OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
331 :
332 : // output page/section breaks
333 1174 : SwNodeIndex aNextIndex(rNode, 1);
334 1174 : m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
335 1174 : m_bBufferSectionBreaks = true;
336 :
337 : // output section headers / footers
338 1174 : if (!m_bBufferSectionHeaders)
339 1156 : m_rExport.Strm().WriteCharPtr(m_aSectionHeaders.makeStringAndClear().getStr());
340 :
341 1174 : if (aNextIndex.GetNode().IsTxtNode())
342 : {
343 590 : const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >(&aNextIndex.GetNode());
344 590 : m_rExport.OutputSectionBreaks(pTxtNode->GetpSwAttrSet(), *pTxtNode);
345 : // Save the current page description for now, so later we will be able to access the previous one.
346 590 : m_pPrevPageDesc = pTxtNode->FindPageDesc(false);
347 : }
348 584 : else if (aNextIndex.GetNode().IsTableNode())
349 : {
350 20 : const SwTableNode* pTableNode = static_cast< SwTableNode* >(&aNextIndex.GetNode());
351 20 : const SwFrmFmt* pFmt = pTableNode->GetTable().GetFrmFmt();
352 20 : m_rExport.OutputSectionBreaks(&(pFmt->GetAttrSet()), *pTableNode);
353 : }
354 1174 : m_bBufferSectionBreaks = false;
355 1174 : }
356 :
357 1174 : void RtfAttributeOutput::StartParagraphProperties()
358 : {
359 1174 : OStringBuffer aPar;
360 1174 : if (!m_rExport.bRTFFlySyntax)
361 : {
362 1128 : aPar.append(OOO_STRING_SVTOOLS_RTF_PARD);
363 1128 : aPar.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
364 1128 : aPar.append(' ');
365 : }
366 1174 : if (!m_bBufferSectionHeaders)
367 1156 : m_rExport.Strm().WriteCharPtr(aPar.makeStringAndClear().getStr());
368 : else
369 18 : m_aSectionHeaders.append(aPar.makeStringAndClear());
370 1174 : }
371 :
372 1174 : void RtfAttributeOutput::EndParagraphProperties(const SfxItemSet& /*rParagraphMarkerProperties*/, const SwRedlineData* /*pRedlineData*/, const SwRedlineData* /*pRedlineParagraphMarkerDeleted*/, const SwRedlineData* /*pRedlineParagraphMarkerInserted*/)
373 : {
374 1174 : m_aStyles.append(m_aStylesEnd.makeStringAndClear());
375 1174 : m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr());
376 1174 : }
377 :
378 1398 : void RtfAttributeOutput::StartRun(const SwRedlineData* pRedlineData, bool bSingleEmptyRun)
379 : {
380 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", bSingleEmptyRun: " << bSingleEmptyRun);
381 :
382 1398 : m_bInRun = true;
383 1398 : m_bSingleEmptyRun = bSingleEmptyRun;
384 1398 : if (!m_bSingleEmptyRun)
385 896 : m_aRun->append('{');
386 :
387 : // if there is some redlining in the document, output it
388 1398 : Redline(pRedlineData);
389 :
390 : OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
391 1398 : }
392 :
393 1398 : void RtfAttributeOutput::EndRun()
394 : {
395 1398 : m_aRun->append(SAL_NEWLINE_STRING);
396 1398 : m_aRun.appendAndClear(m_aRunText);
397 1398 : if (!m_bSingleEmptyRun && m_bInRun)
398 896 : m_aRun->append('}');
399 1398 : m_bInRun = false;
400 1398 : }
401 :
402 1388 : void RtfAttributeOutput::StartRunProperties()
403 : {
404 : OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
405 1388 : }
406 :
407 1388 : void RtfAttributeOutput::EndRunProperties(const SwRedlineData* /*pRedlineData*/)
408 : {
409 1388 : m_aStyles.append(m_aStylesEnd.makeStringAndClear());
410 1388 : m_aRun->append(m_aStyles.makeStringAndClear());
411 1388 : }
412 :
413 730 : void RtfAttributeOutput::RunText(const OUString& rText, rtl_TextEncoding /*eCharSet*/)
414 : {
415 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rText: " << rText);
416 730 : RawText(rText, false, m_rExport.eCurrentEncoding);
417 730 : }
418 :
419 4836 : OStringBuffer& RtfAttributeOutput::RunText()
420 : {
421 4836 : return m_aRunText.getLastBuffer();
422 : }
423 :
424 730 : void RtfAttributeOutput::RawText(const OUString& rText, bool /*bForceUnicode*/, rtl_TextEncoding eCharSet)
425 : {
426 730 : m_aRunText->append(msfilter::rtfutil::OutString(rText, eCharSet));
427 730 : }
428 :
429 0 : void RtfAttributeOutput::StartRuby(const SwTxtNode& /*rNode*/, sal_Int32 /*nPos*/, const SwFmtRuby& /*rRuby*/)
430 : {
431 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
432 0 : }
433 :
434 0 : void RtfAttributeOutput::EndRuby()
435 : {
436 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
437 0 : }
438 :
439 6 : bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& rTarget)
440 : {
441 6 : m_aStyles.append('{');
442 6 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FIELD);
443 6 : m_aStyles.append('{');
444 6 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
445 6 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FLDINST);
446 6 : m_aStyles.append(" HYPERLINK ");
447 :
448 6 : OUString sURL(rUrl);
449 6 : if (!sURL.isEmpty())
450 : {
451 6 : m_aStyles.append("\"");
452 6 : m_aStyles.append(msfilter::rtfutil::OutString(sURL, m_rExport.eCurrentEncoding));
453 6 : m_aStyles.append("\" ");
454 : }
455 :
456 6 : if (!rTarget.isEmpty())
457 : {
458 0 : m_aStyles.append("\\\\t \"");
459 0 : m_aStyles.append(msfilter::rtfutil::OutString(rTarget, m_rExport.eCurrentEncoding));
460 0 : m_aStyles.append("\" ");
461 : }
462 :
463 6 : m_aStyles.append("}");
464 6 : m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " {");
465 6 : return true;
466 : }
467 :
468 6 : bool RtfAttributeOutput::EndURL(bool const isAtEndOfParagraph)
469 : {
470 : // UGLY: usually EndRun is called earlier, but there is an extra
471 : // call to OutAttrWithRange() when at the end of the paragraph,
472 : // so in that special case the output needs to be appended to the
473 : // new run's text instead of the previous run
474 6 : if (isAtEndOfParagraph)
475 : {
476 : // close the fldrslt group
477 2 : m_aRunText->append("}}");
478 : // close the field group
479 2 : m_aRunText->append('}');
480 : }
481 : else
482 : {
483 : // close the fldrslt group
484 4 : m_aRun->append("}}");
485 : // close the field group
486 4 : m_aRun->append('}');
487 : }
488 6 : return true;
489 : }
490 :
491 0 : void RtfAttributeOutput::FieldVanish(const OUString& /*rTxt*/, ww::eField /*eType*/)
492 : {
493 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
494 0 : }
495 :
496 1398 : void RtfAttributeOutput::Redline(const SwRedlineData* pRedline)
497 : {
498 1398 : if (!pRedline)
499 2796 : return;
500 :
501 0 : if (pRedline->GetType() == nsRedlineType_t::REDLINE_INSERT)
502 : {
503 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED);
504 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH);
505 0 : m_aRun->append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
506 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM);
507 : }
508 0 : else if (pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
509 : {
510 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_DELETED);
511 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL);
512 0 : m_aRun->append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
513 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL);
514 : }
515 0 : m_aRun->append((sal_Int32)sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()));
516 0 : m_aRun->append(' ');
517 : }
518 :
519 0 : void RtfAttributeOutput::FormatDrop(const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t /*pTextNodeInfoInner*/)
520 : {
521 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
522 0 : }
523 :
524 1174 : void RtfAttributeOutput::ParagraphStyle(sal_uInt16 nStyle)
525 : {
526 1174 : OString* pStyle = m_rExport.GetStyle(nStyle);
527 1174 : OStringBuffer aStyle;
528 1174 : aStyle.append(OOO_STRING_SVTOOLS_RTF_S);
529 1174 : aStyle.append((sal_Int32)nStyle);
530 1174 : if (pStyle)
531 1174 : aStyle.append(pStyle->getStr());
532 1174 : if (!m_bBufferSectionHeaders)
533 1156 : m_rExport.Strm().WriteCharPtr(aStyle.makeStringAndClear().getStr());
534 : else
535 18 : m_aSectionHeaders.append(aStyle.makeStringAndClear());
536 1174 : }
537 :
538 380 : void RtfAttributeOutput::TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
539 : {
540 380 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_INTBL);
541 380 : if (m_nTableDepth > 1)
542 : {
543 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ITAP);
544 0 : m_aStyles.append((sal_Int32)m_nTableDepth);
545 : }
546 380 : m_bWroteCellInfo = true;
547 380 : }
548 :
549 0 : void RtfAttributeOutput::TableInfoRow(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/)
550 : {
551 : /* noop */
552 0 : }
553 :
554 118 : void RtfAttributeOutput::TableDefinition(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
555 : {
556 118 : if (!m_pTableWrt)
557 40 : InitTableHelper(pTableTextNodeInfoInner);
558 :
559 118 : const SwTable* pTbl = pTableTextNodeInfoInner->getTable();
560 118 : SwFrmFmt* pFmt = pTbl->GetFrmFmt();
561 :
562 118 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TROWD);
563 118 : TableOrientation(pTableTextNodeInfoInner);
564 118 : TableBidi(pTableTextNodeInfoInner);
565 118 : TableHeight(pTableTextNodeInfoInner);
566 118 : TableCanSplit(pTableTextNodeInfoInner);
567 :
568 : // Cell margins
569 118 : const SvxBoxItem& rBox = pFmt->GetBox();
570 : static const sal_uInt16 aBorders[] =
571 : {
572 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
573 : };
574 :
575 : static const char* aRowPadNames[] =
576 : {
577 : OOO_STRING_SVTOOLS_RTF_TRPADDT, OOO_STRING_SVTOOLS_RTF_TRPADDL, OOO_STRING_SVTOOLS_RTF_TRPADDB, OOO_STRING_SVTOOLS_RTF_TRPADDR
578 : };
579 :
580 : static const char* aRowPadUnits[] =
581 : {
582 : OOO_STRING_SVTOOLS_RTF_TRPADDFT, OOO_STRING_SVTOOLS_RTF_TRPADDFL, OOO_STRING_SVTOOLS_RTF_TRPADDFB, OOO_STRING_SVTOOLS_RTF_TRPADDFR
583 : };
584 :
585 590 : for (int i = 0; i < 4; ++i)
586 : {
587 472 : m_aRowDefs.append(aRowPadUnits[i]);
588 472 : m_aRowDefs.append((sal_Int32)3);
589 472 : m_aRowDefs.append(aRowPadNames[i]);
590 472 : m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
591 : }
592 :
593 : // The cell-dependent properties
594 118 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
595 118 : SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
596 118 : SwTwips nSz = 0;
597 118 : Point aPt;
598 118 : SwRect aRect(pFmt->FindLayoutRect(false, &aPt));
599 118 : SwTwips nPageSize = aRect.Width();
600 :
601 : // Handle the page size when not rendered
602 118 : if (0 == nPageSize)
603 : {
604 100 : const SwNode* pNode = pTableTextNodeInfoInner->getNode();
605 104 : const SwFrmFmt* pFrmFmt = GetExport().mpParentFrame ? &GetExport().mpParentFrame->GetFrmFmt() :
606 104 : GetExport().pDoc->GetPageDesc(0).GetPageFmtOfNode(*pNode, false);
607 :
608 100 : const SvxLRSpaceItem& rLR = pFrmFmt->GetLRSpace();
609 200 : nPageSize = pFrmFmt->GetFrmSize().GetWidth() -
610 200 : rLR.GetLeft() - rLR.GetRight();
611 : }
612 118 : SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
613 : // Not using m_nTableDepth, which is not yet incremented here.
614 118 : sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
615 118 : m_aCells[nCurrentDepth] = pRow->GetCells().size();
616 512 : for (sal_uInt16 i = 0; i < m_aCells[nCurrentDepth]; i++)
617 : {
618 394 : const SwWriteTableCell* pCell = &pRow->GetCells()[ i ];
619 394 : const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
620 :
621 394 : pTableTextNodeInfoInner->setCell(i);
622 394 : TableCellProperties(pTableTextNodeInfoInner);
623 :
624 : // Right boundary: this can't be in TableCellProperties as the old
625 : // value of nSz is needed.
626 394 : nSz += pCellFmt->GetFrmSize().GetWidth();
627 394 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CELLX);
628 394 : SwTwips nCalc = nSz;
629 394 : nCalc *= nPageSize;
630 394 : nCalc /= nTblSz;
631 394 : m_aRowDefs.append((sal_Int32)(pFmt->GetLRSpace().GetLeft() + nCalc));
632 : }
633 118 : }
634 :
635 394 : void RtfAttributeOutput::TableDefaultBorders(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
636 : {
637 : /*
638 : * The function name is a bit misleading: given that we write borders
639 : * before each row, we just have borders, not default ones. Additionally,
640 : * this function actually writes borders for a specific cell only and is
641 : * called for each cell.
642 : */
643 :
644 394 : const SwTableBox* pTblBox = pTableTextNodeInfoInner->getTableBox();
645 394 : SwFrmFmt* pFmt = pTblBox->GetFrmFmt();
646 394 : const SvxBoxItem& rDefault = pFmt->GetBox();
647 394 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
648 394 : SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
649 394 : const SwWriteTableCell* pCell = &pRow->GetCells()[ pTableTextNodeInfoInner->getCell() ];
650 394 : const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
651 : const SfxPoolItem* pItem;
652 394 : if (pCellFmt->GetAttrSet().HasItem(RES_BOX, &pItem))
653 : {
654 386 : const SvxBoxItem& rBox = (SvxBoxItem&)*pItem;
655 : static const sal_uInt16 aBorders[] =
656 : {
657 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
658 : };
659 : static const char* aBorderNames[] =
660 : {
661 : OOO_STRING_SVTOOLS_RTF_CLBRDRT, OOO_STRING_SVTOOLS_RTF_CLBRDRL, OOO_STRING_SVTOOLS_RTF_CLBRDRB, OOO_STRING_SVTOOLS_RTF_CLBRDRR
662 : };
663 : //Yes left and top are swapped with eachother for cell padding! Because
664 : //that's what the thunderingly annoying rtf export/import word xp does.
665 : static const char* aCellPadNames[] =
666 : {
667 : OOO_STRING_SVTOOLS_RTF_CLPADL, OOO_STRING_SVTOOLS_RTF_CLPADT, OOO_STRING_SVTOOLS_RTF_CLPADB, OOO_STRING_SVTOOLS_RTF_CLPADR
668 : };
669 : static const char* aCellPadUnits[] =
670 : {
671 : OOO_STRING_SVTOOLS_RTF_CLPADFL, OOO_STRING_SVTOOLS_RTF_CLPADFT, OOO_STRING_SVTOOLS_RTF_CLPADFB, OOO_STRING_SVTOOLS_RTF_CLPADFR
672 : };
673 1930 : for (int i = 0; i < 4; ++i)
674 : {
675 1544 : if (const SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
676 800 : m_aRowDefs.append(OutTBLBorderLine(m_rExport, pLn, aBorderNames[i]));
677 3088 : if (rDefault.GetDistance(aBorders[i]) !=
678 1544 : rBox.GetDistance(aBorders[i]))
679 : {
680 8 : m_aRowDefs.append(aCellPadUnits[i]);
681 8 : m_aRowDefs.append((sal_Int32)3);
682 8 : m_aRowDefs.append(aCellPadNames[i]);
683 8 : m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
684 : }
685 : }
686 : }
687 394 : }
688 :
689 394 : void RtfAttributeOutput::TableBackgrounds(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
690 : {
691 394 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
692 394 : SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
693 394 : const SwWriteTableCell* pCell = &pRow->GetCells()[ pTableTextNodeInfoInner->getCell() ];
694 394 : const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
695 : const SfxPoolItem* pItem;
696 394 : if (pCellFmt->GetAttrSet().HasItem(RES_BACKGROUND, &pItem))
697 : {
698 26 : const SvxBrushItem& rBack = (SvxBrushItem&)*pItem;
699 26 : if (!rBack.GetColor().GetTransparency())
700 : {
701 6 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLCBPAT);
702 6 : m_aRowDefs.append((sal_Int32)m_rExport.GetColor(rBack.GetColor()));
703 : }
704 : }
705 394 : }
706 :
707 0 : void RtfAttributeOutput::TableRowRedline(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
708 : {
709 0 : }
710 :
711 0 : void RtfAttributeOutput::TableCellRedline(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
712 : {
713 0 : }
714 :
715 118 : void RtfAttributeOutput::TableHeight(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
716 : {
717 118 : const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
718 118 : const SwTableLine* pTabLine = pTabBox->GetUpper();
719 118 : const SwFrmFmt* pLineFmt = pTabLine->GetFrmFmt();
720 118 : const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
721 :
722 118 : if (ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight())
723 : {
724 34 : sal_Int32 nHeight = 0;
725 :
726 34 : switch (rLSz.GetHeightSizeType())
727 : {
728 : case ATT_FIX_SIZE:
729 30 : nHeight = -rLSz.GetHeight();
730 30 : break;
731 : case ATT_MIN_SIZE:
732 4 : nHeight = rLSz.GetHeight();
733 4 : break;
734 : default:
735 0 : break;
736 : }
737 :
738 34 : if (nHeight)
739 : {
740 34 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRRH);
741 34 : m_aRowDefs.append(nHeight);
742 : }
743 : }
744 118 : }
745 :
746 118 : void RtfAttributeOutput::TableCanSplit(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
747 : {
748 118 : const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
749 118 : const SwTableLine* pTabLine = pTabBox->GetUpper();
750 118 : const SwFrmFmt* pLineFmt = pTabLine->GetFrmFmt();
751 118 : const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit();
752 :
753 : // The rtf default is to allow a row to break
754 118 : if (!rSplittable.GetValue())
755 0 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRKEEP);
756 118 : }
757 :
758 118 : void RtfAttributeOutput::TableBidi(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
759 : {
760 118 : const SwTable* pTable = pTableTextNodeInfoInner->getTable();
761 118 : const SwFrmFmt* pFrmFmt = pTable->GetFrmFmt();
762 :
763 118 : if (m_rExport.TrueFrameDirection(*pFrmFmt) != FRMDIR_HORI_RIGHT_TOP)
764 118 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_LTRROW);
765 : else
766 0 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_RTLROW);
767 118 : }
768 :
769 394 : void RtfAttributeOutput::TableVerticalCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
770 : {
771 394 : const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
772 394 : SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
773 394 : const SwWriteTableCell* pCell = &pRow->GetCells()[ pTableTextNodeInfoInner->getCell() ];
774 394 : const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
775 : const SfxPoolItem* pItem;
776 :
777 : // vertical merges
778 394 : if (pCell->GetRowSpan() > 1)
779 0 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMGF);
780 394 : else if (pCell->GetRowSpan() == 0)
781 0 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMRG);
782 :
783 : // vertical alignment
784 394 : if (pCellFmt->GetAttrSet().HasItem(RES_VERT_ORIENT, &pItem))
785 330 : switch (((SwFmtVertOrient*)pItem)->GetVertOrient())
786 : {
787 : case text::VertOrientation::CENTER:
788 326 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALC);
789 326 : break;
790 : case text::VertOrientation::BOTTOM:
791 0 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALB);
792 0 : break;
793 : default:
794 4 : m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALT);
795 4 : break;
796 : }
797 394 : }
798 :
799 0 : void RtfAttributeOutput::TableNodeInfo(ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/)
800 : {
801 : /* noop */
802 0 : }
803 :
804 664 : void RtfAttributeOutput::TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner)
805 : {
806 : // This is called when the nested table ends in a cell, and there's no
807 : // paragraph benhind that; so we must check for the ends of cell, rows,
808 : // and tables
809 : // ['true' to write an empty paragraph, MS Word insists on that]
810 664 : FinishTableRowCell(pNodeInfoInner, true);
811 664 : }
812 :
813 118 : void RtfAttributeOutput::TableOrientation(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
814 : {
815 118 : const SwTable* pTable = pTableTextNodeInfoInner->getTable();
816 118 : SwFrmFmt* pFmt = pTable->GetFrmFmt();
817 :
818 118 : OStringBuffer aTblAdjust(OOO_STRING_SVTOOLS_RTF_TRQL);
819 118 : switch (pFmt->GetHoriOrient().GetHoriOrient())
820 : {
821 : case text::HoriOrientation::CENTER:
822 0 : aTblAdjust.setLength(0);
823 0 : aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQC);
824 0 : break;
825 : case text::HoriOrientation::RIGHT:
826 0 : aTblAdjust.setLength(0);
827 0 : aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQR);
828 0 : break;
829 : case text::HoriOrientation::NONE:
830 : case text::HoriOrientation::LEFT_AND_WIDTH:
831 34 : aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRLEFT);
832 34 : aTblAdjust.append((sal_Int32)pFmt->GetLRSpace().GetLeft());
833 34 : break;
834 : default:
835 84 : break;
836 : }
837 :
838 118 : m_aRowDefs.append(aTblAdjust.makeStringAndClear());
839 118 : }
840 :
841 0 : void RtfAttributeOutput::TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
842 : {
843 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
844 0 : }
845 :
846 0 : void RtfAttributeOutput::TableRowEnd(sal_uInt32 /*nDepth*/)
847 : {
848 : /* noop, see EndTableRow() */
849 0 : }
850 :
851 : /*
852 : * Our private table methods.
853 : */
854 :
855 40 : void RtfAttributeOutput::InitTableHelper(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
856 : {
857 40 : sal_uInt32 nPageSize = 0;
858 40 : bool bRelBoxSize = false;
859 :
860 : // Create the SwWriteTable instance to use col spans
861 40 : GetTablePageSize(pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize);
862 :
863 40 : const SwTable* pTable = pTableTextNodeInfoInner->getTable();
864 40 : const SwFrmFmt* pFmt = pTable->GetFrmFmt();
865 40 : SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
866 :
867 40 : const SwHTMLTableLayout* pLayout = pTable->GetHTMLTableLayout();
868 40 : if (pLayout && pLayout->IsExportable())
869 0 : m_pTableWrt = new SwWriteTable(pLayout);
870 : else
871 : m_pTableWrt = new SwWriteTable(pTable->GetTabLines(), (sal_uInt16)nPageSize,
872 40 : (sal_uInt16)nTblSz, false);
873 40 : }
874 :
875 40 : void RtfAttributeOutput::StartTable(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
876 : {
877 : // To trigger calling InitTableHelper()
878 40 : delete m_pTableWrt, m_pTableWrt = NULL;
879 40 : }
880 :
881 118 : void RtfAttributeOutput::StartTableRow(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
882 : {
883 118 : sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
884 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << nCurrentDepth << ")");
885 :
886 118 : TableDefinition(pTableTextNodeInfoInner);
887 :
888 118 : if (!m_bLastTable)
889 0 : m_aTables.push_back(m_aRowDefs.makeStringAndClear());
890 :
891 : // We'll write the table definition for nested tables later
892 118 : if (nCurrentDepth > 1)
893 118 : return;
894 : // Empty the previous row closing buffer before starting the new one,
895 : // necessary for subtables.
896 118 : m_rExport.Strm().WriteCharPtr(m_aAfterRuns.makeStringAndClear().getStr());
897 118 : m_rExport.Strm().WriteCharPtr(m_aRowDefs.makeStringAndClear().getStr());
898 : }
899 :
900 332 : void RtfAttributeOutput::StartTableCell(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
901 : {
902 332 : m_bTableCellOpen = true;
903 332 : }
904 :
905 394 : void RtfAttributeOutput::TableCellProperties(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
906 : {
907 394 : TableDefaultBorders(pTableTextNodeInfoInner);
908 394 : TableBackgrounds(pTableTextNodeInfoInner);
909 394 : TableVerticalCell(pTableTextNodeInfoInner);
910 394 : }
911 :
912 332 : void RtfAttributeOutput::EndTableCell()
913 : {
914 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
915 :
916 332 : if (!m_bWroteCellInfo)
917 : {
918 0 : m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_INTBL);
919 0 : m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ITAP);
920 0 : m_aAfterRuns.append((sal_Int32)m_nTableDepth);
921 : }
922 332 : if (m_nTableDepth > 1)
923 0 : m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTCELL);
924 : else
925 332 : m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
926 :
927 332 : m_bTableCellOpen = false;
928 332 : m_bTblAfterCell = true;
929 332 : m_bWroteCellInfo = false;
930 332 : if (m_aCells[m_nTableDepth] > 0)
931 330 : m_aCells[m_nTableDepth]--;
932 332 : }
933 :
934 92 : void RtfAttributeOutput::EndTableRow()
935 : {
936 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
937 :
938 : // Trying to end the row without writing the required number of cells? Fill with empty ones.
939 118 : for (sal_uInt16 i = 0; i < m_aCells[m_nTableDepth]; i++)
940 26 : m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
941 :
942 92 : if (m_nTableDepth > 1)
943 : {
944 0 : m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS);
945 0 : if (!m_aRowDefs.isEmpty())
946 0 : m_aAfterRuns.append(m_aRowDefs.makeStringAndClear());
947 0 : else if (!m_aTables.empty())
948 : {
949 0 : m_aAfterRuns.append(m_aTables.back());
950 0 : m_aTables.pop_back();
951 : }
952 0 : m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTROW "}" "{" OOO_STRING_SVTOOLS_RTF_NONESTTABLES OOO_STRING_SVTOOLS_RTF_PAR "}");
953 : }
954 : else
955 : {
956 92 : if (!m_aTables.empty())
957 : {
958 0 : m_aAfterRuns.append(m_aTables.back());
959 0 : m_aTables.pop_back();
960 : }
961 92 : m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD);
962 : }
963 92 : m_bTableRowEnded = true;
964 92 : }
965 :
966 40 : void RtfAttributeOutput::EndTable()
967 : {
968 40 : if (m_nTableDepth > 0)
969 : {
970 40 : m_nTableDepth--;
971 40 : delete m_pTableWrt, m_pTableWrt = NULL;
972 : }
973 :
974 : // We closed the table; if it is a nested table, the cell that contains it
975 : // still continues
976 40 : m_bTableCellOpen = true;
977 :
978 : // Cleans the table helper
979 40 : delete m_pTableWrt, m_pTableWrt = NULL;
980 40 : }
981 :
982 1838 : void RtfAttributeOutput::FinishTableRowCell(ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool /*bForceEmptyParagraph*/)
983 : {
984 1838 : if (pInner.get())
985 : {
986 : // Where are we in the table
987 1044 : sal_uInt32 nRow = pInner->getRow();
988 :
989 1044 : const SwTable* pTable = pInner->getTable();
990 1044 : const SwTableLines& rLines = pTable->GetTabLines();
991 1044 : sal_uInt16 nLinesCount = rLines.size();
992 :
993 1044 : if (pInner->isEndOfCell())
994 332 : EndTableCell();
995 :
996 : // This is a line end
997 1044 : if (pInner->isEndOfLine())
998 92 : EndTableRow();
999 :
1000 : // This is the end of the table
1001 1044 : if (pInner->isEndOfLine() && (nRow + 1) == nLinesCount)
1002 40 : EndTable();
1003 : }
1004 1838 : }
1005 :
1006 138 : void RtfAttributeOutput::StartStyles()
1007 : {
1008 138 : m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING).WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLORTBL);
1009 138 : m_rExport.OutColorTable();
1010 : OSL_ENSURE(m_aStylesheet.getLength() == 0, "m_aStylesheet is not empty");
1011 138 : m_aStylesheet.append(SAL_NEWLINE_STRING);
1012 138 : m_aStylesheet.append('{');
1013 138 : m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_STYLESHEET);
1014 138 : }
1015 :
1016 138 : void RtfAttributeOutput::EndStyles(sal_uInt16 /*nNumberOfStyles*/)
1017 : {
1018 138 : m_rExport.Strm().WriteChar('}');
1019 138 : m_rExport.Strm().WriteCharPtr(m_aStylesheet.makeStringAndClear().getStr());
1020 138 : m_rExport.Strm().WriteChar('}');
1021 138 : }
1022 :
1023 1904 : void RtfAttributeOutput::DefaultStyle(sal_uInt16 /*nStyle*/)
1024 : {
1025 : /* noop, the default style is always 0 in RTF */
1026 1904 : }
1027 :
1028 1320 : void RtfAttributeOutput::StartStyle(const OUString& rName, StyleType eType,
1029 : sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId,
1030 : bool /* bAutoUpdate */)
1031 : {
1032 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rName = '" << rName << "'");
1033 :
1034 1320 : m_aStylesheet.append('{');
1035 1320 : if (eType == STYLE_TYPE_PARA)
1036 1054 : m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
1037 : else
1038 266 : m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_CS);
1039 1320 : m_aStylesheet.append((sal_Int32)nId);
1040 :
1041 1320 : if (nBase != 0x0FFF)
1042 : {
1043 936 : m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SBASEDON);
1044 936 : m_aStylesheet.append((sal_Int32)nBase);
1045 : }
1046 :
1047 1320 : m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SNEXT);
1048 1320 : m_aStylesheet.append((sal_Int32)nNext);
1049 :
1050 1320 : m_rStyleName = rName;
1051 1320 : m_nStyleId = nId;
1052 1320 : }
1053 :
1054 1320 : void RtfAttributeOutput::EndStyle()
1055 : {
1056 1320 : m_aStyles.append(m_aStylesEnd.makeStringAndClear());
1057 1320 : OString aStyles = m_aStyles.makeStringAndClear();
1058 1320 : m_rExport.InsStyle(m_nStyleId, aStyles);
1059 1320 : m_aStylesheet.append(aStyles);
1060 1320 : m_aStylesheet.append(' ');
1061 1320 : m_aStylesheet.append(msfilter::rtfutil::OutString(m_rStyleName, m_rExport.eCurrentEncoding));
1062 1320 : m_aStylesheet.append(";}");
1063 1320 : m_aStylesheet.append(SAL_NEWLINE_STRING);
1064 1320 : }
1065 :
1066 2374 : void RtfAttributeOutput::StartStyleProperties(bool /*bParProp*/, sal_uInt16 /*nStyle*/)
1067 : {
1068 : /* noop */
1069 2374 : }
1070 :
1071 2374 : void RtfAttributeOutput::EndStyleProperties(bool /*bParProp*/)
1072 : {
1073 : /* noop */
1074 2374 : }
1075 :
1076 24 : void RtfAttributeOutput::OutlineNumbering(sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/)
1077 : {
1078 24 : if (nLvl >= WW8ListManager::nMaxLevel)
1079 2 : nLvl = WW8ListManager::nMaxLevel - 1;
1080 :
1081 24 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
1082 24 : m_aStyles.append((sal_Int32)nLvl);
1083 24 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL);
1084 24 : m_aStyles.append((sal_Int32)nLvl);
1085 24 : }
1086 :
1087 12 : void RtfAttributeOutput::PageBreakBefore(bool bBreak)
1088 : {
1089 12 : if (bBreak)
1090 : {
1091 10 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PAGEBB);
1092 : }
1093 12 : }
1094 :
1095 24 : void RtfAttributeOutput::SectionBreak(sal_uInt8 nC, const WW8_SepInfo* pSectionInfo)
1096 : {
1097 24 : switch (nC)
1098 : {
1099 : case msword::ColumnBreak:
1100 14 : m_nColBreakNeeded = true;
1101 14 : break;
1102 : case msword::PageBreak:
1103 10 : if (pSectionInfo)
1104 10 : m_rExport.SectionProperties(*pSectionInfo);
1105 10 : break;
1106 : }
1107 24 : }
1108 :
1109 10 : void RtfAttributeOutput::StartSection()
1110 : {
1111 10 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECT OOO_STRING_SVTOOLS_RTF_SECTD);
1112 10 : if (!m_bBufferSectionBreaks)
1113 0 : m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
1114 10 : }
1115 :
1116 10 : void RtfAttributeOutput::EndSection()
1117 : {
1118 : /*
1119 : * noop, \sect must go to StartSection or Word won't notice multiple
1120 : * columns...
1121 : */
1122 10 : }
1123 :
1124 10 : void RtfAttributeOutput::SectionFormProtection(bool bProtected)
1125 : {
1126 10 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED);
1127 10 : m_aSectionBreaks.append((sal_Int32)!bProtected);
1128 10 : }
1129 :
1130 2 : void RtfAttributeOutput::SectionLineNumbering(sal_uLong /*nRestartNo*/, const SwLineNumberInfo& rLnNumInfo)
1131 : {
1132 2 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEMOD);
1133 2 : m_rExport.OutLong(rLnNumInfo.GetCountBy());
1134 2 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEX);
1135 2 : m_rExport.OutLong(rLnNumInfo.GetPosFromLeft());
1136 2 : if (!rLnNumInfo.IsRestartEachPage())
1137 2 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINECONT);
1138 2 : }
1139 :
1140 0 : void RtfAttributeOutput::SectionTitlePage()
1141 : {
1142 : /*
1143 : * noop, handled in RtfExport::WriteHeaderFooter()
1144 : */
1145 0 : }
1146 :
1147 10 : void RtfAttributeOutput::SectionPageBorders(const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/)
1148 : {
1149 10 : const SvxBoxItem& rBox = pFmt->GetBox();
1150 10 : const SvxBorderLine* pLine = rBox.GetTop();
1151 10 : if (pLine)
1152 : m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
1153 : OOO_STRING_SVTOOLS_RTF_PGBRDRT,
1154 6 : rBox.GetDistance(BOX_LINE_TOP)));
1155 10 : pLine = rBox.GetBottom();
1156 10 : if (pLine)
1157 : m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
1158 : OOO_STRING_SVTOOLS_RTF_PGBRDRB,
1159 6 : rBox.GetDistance(BOX_LINE_BOTTOM)));
1160 10 : pLine = rBox.GetLeft();
1161 10 : if (pLine)
1162 : m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
1163 : OOO_STRING_SVTOOLS_RTF_PGBRDRL,
1164 6 : rBox.GetDistance(BOX_LINE_LEFT)));
1165 10 : pLine = rBox.GetRight();
1166 10 : if (pLine)
1167 : m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
1168 : OOO_STRING_SVTOOLS_RTF_PGBRDRR,
1169 6 : rBox.GetDistance(BOX_LINE_RIGHT)));
1170 10 : }
1171 :
1172 0 : void RtfAttributeOutput::SectionBiDi(bool bBiDi)
1173 : {
1174 0 : m_rExport.Strm().WriteCharPtr((bBiDi ? OOO_STRING_SVTOOLS_RTF_RTLSECT : OOO_STRING_SVTOOLS_RTF_LTRSECT));
1175 0 : }
1176 :
1177 330 : void RtfAttributeOutput::SectionPageNumbering(sal_uInt16 nNumType, ::boost::optional<sal_uInt16> oPageRestartNumber)
1178 : {
1179 330 : if (oPageRestartNumber)
1180 : {
1181 0 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNSTARTS);
1182 0 : m_aSectionBreaks.append((sal_Int32)oPageRestartNumber.get());
1183 0 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNRESTART);
1184 : }
1185 :
1186 330 : const char* pStr = 0;
1187 330 : switch (nNumType)
1188 : {
1189 : case SVX_NUM_CHARS_UPPER_LETTER:
1190 : case SVX_NUM_CHARS_UPPER_LETTER_N:
1191 0 : pStr = OOO_STRING_SVTOOLS_RTF_PGNUCLTR;
1192 0 : break;
1193 : case SVX_NUM_CHARS_LOWER_LETTER:
1194 : case SVX_NUM_CHARS_LOWER_LETTER_N:
1195 0 : pStr = OOO_STRING_SVTOOLS_RTF_PGNLCLTR;
1196 0 : break;
1197 : case SVX_NUM_ROMAN_UPPER:
1198 0 : pStr = OOO_STRING_SVTOOLS_RTF_PGNUCRM;
1199 0 : break;
1200 : case SVX_NUM_ROMAN_LOWER:
1201 0 : pStr = OOO_STRING_SVTOOLS_RTF_PGNLCRM;
1202 0 : break;
1203 :
1204 : case SVX_NUM_ARABIC:
1205 330 : pStr = OOO_STRING_SVTOOLS_RTF_PGNDEC;
1206 330 : break;
1207 : }
1208 330 : if (pStr)
1209 330 : m_aSectionBreaks.append(pStr);
1210 330 : }
1211 :
1212 10 : void RtfAttributeOutput::SectionType(sal_uInt8 nBreakCode)
1213 : {
1214 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", nBreakCode = " << int(nBreakCode));
1215 :
1216 : /*
1217 : * break code: 0 No break, 1 New column
1218 : * 2 New page, 3 Even page, 4 Odd page
1219 : */
1220 10 : const char* sType = NULL;
1221 10 : switch (nBreakCode)
1222 : {
1223 : case 1:
1224 0 : sType = OOO_STRING_SVTOOLS_RTF_SBKCOL;
1225 0 : break;
1226 : case 2:
1227 10 : sType = OOO_STRING_SVTOOLS_RTF_SBKPAGE;
1228 10 : break;
1229 : case 3:
1230 0 : sType = OOO_STRING_SVTOOLS_RTF_SBKEVEN;
1231 0 : break;
1232 : case 4:
1233 0 : sType = OOO_STRING_SVTOOLS_RTF_SBKODD;
1234 0 : break;
1235 : default:
1236 0 : sType = OOO_STRING_SVTOOLS_RTF_SBKNONE;
1237 0 : break;
1238 : }
1239 10 : m_aSectionBreaks.append(sType);
1240 10 : if (!m_bBufferSectionBreaks)
1241 0 : m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
1242 10 : }
1243 :
1244 34 : void RtfAttributeOutput::NumberingDefinition(sal_uInt16 nId, const SwNumRule& /*rRule*/)
1245 : {
1246 34 : m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE);
1247 34 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
1248 34 : m_rExport.OutULong(nId);
1249 34 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT).WriteChar('0');
1250 34 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LS);
1251 34 : m_rExport.OutULong(nId).WriteChar('}');
1252 34 : }
1253 :
1254 34 : void RtfAttributeOutput::StartAbstractNumbering(sal_uInt16 nId)
1255 : {
1256 34 : m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LIST).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID);
1257 34 : m_rExport.OutULong(nId);
1258 34 : m_nListId = nId;
1259 34 : }
1260 :
1261 34 : void RtfAttributeOutput::EndAbstractNumbering()
1262 : {
1263 34 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
1264 34 : m_rExport.OutULong(m_nListId).WriteChar('}').WriteCharPtr(SAL_NEWLINE_STRING);
1265 34 : }
1266 :
1267 306 : void RtfAttributeOutput::NumberingLevel(sal_uInt8 nLevel,
1268 : sal_uInt16 nStart,
1269 : sal_uInt16 nNumberingType,
1270 : SvxAdjust eAdjust,
1271 : const sal_uInt8* pNumLvlPos,
1272 : sal_uInt8 nFollow,
1273 : const wwFont* pFont,
1274 : const SfxItemSet* pOutSet,
1275 : sal_Int16 nIndentAt,
1276 : sal_Int16 nFirstLineIndex,
1277 : sal_Int16 /*nListTabPos*/,
1278 : const OUString& rNumberingString,
1279 : const SvxBrushItem* pBrush)
1280 : {
1281 306 : m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
1282 306 : if (nLevel > 8) // RTF knows only 9 levels
1283 0 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_IGNORE).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SOUTLVL);
1284 :
1285 306 : m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTLEVEL);
1286 :
1287 306 : sal_uInt16 nVal = 0;
1288 306 : switch (nNumberingType)
1289 : {
1290 : case SVX_NUM_ROMAN_UPPER:
1291 0 : nVal = 1;
1292 0 : break;
1293 : case SVX_NUM_ROMAN_LOWER:
1294 2 : nVal = 2;
1295 2 : break;
1296 : case SVX_NUM_CHARS_UPPER_LETTER:
1297 : case SVX_NUM_CHARS_UPPER_LETTER_N:
1298 2 : nVal = 3;
1299 2 : break;
1300 : case SVX_NUM_CHARS_LOWER_LETTER:
1301 : case SVX_NUM_CHARS_LOWER_LETTER_N:
1302 2 : nVal = 4;
1303 2 : break;
1304 :
1305 : case SVX_NUM_BITMAP:
1306 : case SVX_NUM_CHAR_SPECIAL:
1307 38 : nVal = 23;
1308 38 : break;
1309 : case SVX_NUM_NUMBER_NONE:
1310 120 : nVal = 255;
1311 120 : break;
1312 : }
1313 306 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNFC);
1314 306 : m_rExport.OutULong(nVal);
1315 :
1316 306 : switch (eAdjust)
1317 : {
1318 : case SVX_ADJUST_CENTER:
1319 0 : nVal = 1;
1320 0 : break;
1321 : case SVX_ADJUST_RIGHT:
1322 0 : nVal = 2;
1323 0 : break;
1324 : default:
1325 306 : nVal = 0;
1326 306 : break;
1327 : }
1328 306 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELJC);
1329 306 : m_rExport.OutULong(nVal);
1330 :
1331 : // bullet
1332 306 : if (nNumberingType == SVX_NUM_BITMAP && pBrush)
1333 : {
1334 2 : int nIndex = m_rExport.GetGrfIndex(*pBrush);
1335 2 : if (nIndex != -1)
1336 : {
1337 2 : m_rExport.Strm().WriteCharPtr(LO_STRING_SVTOOLS_RTF_LEVELPICTURE);
1338 2 : m_rExport.OutULong(nIndex);
1339 : }
1340 : }
1341 :
1342 306 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT);
1343 306 : m_rExport.OutULong(nStart);
1344 :
1345 306 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW);
1346 306 : m_rExport.OutULong(nFollow);
1347 :
1348 : // leveltext group
1349 306 : m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELTEXT).WriteChar(' ');
1350 :
1351 306 : if (SVX_NUM_CHAR_SPECIAL == nNumberingType ||
1352 : SVX_NUM_BITMAP == nNumberingType)
1353 : {
1354 38 : m_rExport.Strm().WriteCharPtr("\\'01");
1355 38 : sal_Unicode cChar = rNumberingString[0];
1356 38 : m_rExport.Strm().WriteCharPtr("\\u");
1357 38 : m_rExport.OutULong(cChar);
1358 38 : m_rExport.Strm().WriteCharPtr(" ?");
1359 : }
1360 : else
1361 : {
1362 268 : m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(msfilter::rtfutil::OutHex(rNumberingString.getLength(), 2).getStr());
1363 268 : m_rExport.Strm().WriteCharPtr(msfilter::rtfutil::OutString(rNumberingString, m_rExport.eDefaultEncoding, /*bUnicode =*/ false).getStr());
1364 : }
1365 :
1366 306 : m_rExport.Strm().WriteCharPtr(";}");
1367 :
1368 : // write the levelnumbers
1369 306 : m_rExport.Strm().WriteCharPtr("{").WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS);
1370 460 : for (sal_uInt8 i = 0; i <= nLevel && pNumLvlPos[ i ]; ++i)
1371 : {
1372 154 : m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(msfilter::rtfutil::OutHex(pNumLvlPos[ i ], 2).getStr());
1373 : }
1374 306 : m_rExport.Strm().WriteCharPtr(";}");
1375 :
1376 306 : if (pOutSet)
1377 : {
1378 94 : if (pFont)
1379 : {
1380 38 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_F);
1381 38 : m_rExport.OutULong(m_rExport.maFontHelper.GetId(*pFont));
1382 : }
1383 94 : m_rExport.OutputItemSet(*pOutSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF);
1384 94 : m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr());
1385 : }
1386 :
1387 306 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FI);
1388 306 : m_rExport.OutLong(nFirstLineIndex).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LI);
1389 306 : m_rExport.OutLong(nIndentAt);
1390 :
1391 306 : m_rExport.Strm().WriteChar('}');
1392 306 : if (nLevel > 8)
1393 0 : m_rExport.Strm().WriteChar('}');
1394 306 : }
1395 :
1396 70 : void RtfAttributeOutput::WriteField_Impl(const SwField* pFld, ww::eField /*eType*/, const OUString& rFldCmd, sal_uInt8 /*nMode*/)
1397 : {
1398 : // If there are no field instructions, don't export it as a field.
1399 70 : bool bHasInstructions = !rFldCmd.isEmpty();
1400 70 : if (bHasInstructions)
1401 : {
1402 68 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1403 68 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " ");
1404 68 : m_aRunText->append(msfilter::rtfutil::OutString(rFldCmd, m_rExport.eCurrentEncoding));
1405 68 : m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1406 : }
1407 70 : if (pFld)
1408 66 : m_aRunText->append(msfilter::rtfutil::OutString(pFld->ExpandField(true), m_rExport.eDefaultEncoding));
1409 70 : if (bHasInstructions)
1410 68 : m_aRunText->append("}}");
1411 70 : }
1412 :
1413 2560 : void RtfAttributeOutput::WriteBookmarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds)
1414 : {
1415 2562 : for (std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it)
1416 : {
1417 2 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKSTART " ");
1418 2 : m_aRun->append(msfilter::rtfutil::OutString(*it, m_rExport.eCurrentEncoding));
1419 2 : m_aRun->append('}');
1420 : }
1421 2560 : rStarts.clear();
1422 :
1423 2562 : for (std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it)
1424 : {
1425 2 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKEND " ");
1426 2 : m_aRun->append(msfilter::rtfutil::OutString(*it, m_rExport.eCurrentEncoding));
1427 2 : m_aRun->append('}');
1428 : }
1429 2560 : rEnds.clear();
1430 2560 : }
1431 :
1432 2560 : void RtfAttributeOutput::WriteAnnotationMarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds)
1433 : {
1434 2566 : for (std::vector< OUString >::const_iterator i = rStarts.begin(), end = rStarts.end(); i != end; ++i)
1435 : {
1436 6 : OString rName = OUStringToOString(*i, RTL_TEXTENCODING_UTF8);
1437 :
1438 : // Output the annotation mark
1439 6 : sal_uInt16 nId = m_nNextAnnotationMarkId++;
1440 6 : m_rOpenedAnnotationMarksIds[rName] = nId;
1441 6 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFSTART " ");
1442 6 : m_aRun->append(OString::number(nId).getStr());
1443 6 : m_aRun->append('}');
1444 6 : }
1445 2560 : rStarts.clear();
1446 :
1447 2566 : for (std::vector< OUString >::const_iterator i = rEnds.begin(), end = rEnds.end(); i != end; ++i)
1448 : {
1449 6 : OString rName = OUStringToOString(*i, RTL_TEXTENCODING_UTF8);
1450 :
1451 : // Get the id of the annotation mark
1452 6 : std::map<OString, sal_uInt16>::iterator it = m_rOpenedAnnotationMarksIds.find(rName);
1453 6 : if (it != m_rOpenedAnnotationMarksIds.end())
1454 : {
1455 6 : sal_uInt16 nId = it->second;
1456 6 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFEND " ");
1457 6 : m_aRun->append(OString::number(nId).getStr());
1458 6 : m_aRun->append('}');
1459 6 : m_rOpenedAnnotationMarksIds.erase(rName);
1460 :
1461 6 : if (m_aPostitFields.find(nId) != m_aPostitFields.end())
1462 : {
1463 6 : m_aRunText->append("{");
1464 6 : m_nCurrentAnnotationMarkId = nId;
1465 6 : PostitField(m_aPostitFields[nId]);
1466 6 : m_nCurrentAnnotationMarkId = -1;
1467 6 : m_aRunText->append("}");
1468 : }
1469 : }
1470 6 : }
1471 2560 : rEnds.clear();
1472 2560 : }
1473 :
1474 12 : void RtfAttributeOutput::WriteHeaderFooter_Impl(const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr, bool bTitlepg)
1475 : {
1476 12 : OStringBuffer aSectionBreaks = m_aSectionBreaks;
1477 12 : m_aSectionBreaks.setLength(0);
1478 24 : RtfStringBuffer aRun = m_aRun;
1479 12 : m_aRun.clear();
1480 :
1481 12 : m_aSectionHeaders.append(bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY : OOO_STRING_SVTOOLS_RTF_FOOTERY);
1482 12 : m_aSectionHeaders.append((sal_Int32)m_rExport.pAktPageDesc->GetMaster().GetULSpace().GetUpper());
1483 12 : if (bTitlepg)
1484 0 : m_aSectionHeaders.append(OOO_STRING_SVTOOLS_RTF_TITLEPG);
1485 12 : m_aSectionHeaders.append('{');
1486 12 : m_aSectionHeaders.append(pStr);
1487 12 : m_bBufferSectionHeaders = true;
1488 12 : m_rExport.WriteHeaderFooterText(rFmt, bHeader);
1489 12 : m_bBufferSectionHeaders = false;
1490 12 : m_aSectionHeaders.append('}');
1491 :
1492 12 : m_aSectionBreaks = aSectionBreaks;
1493 24 : m_aRun = aRun;
1494 12 : }
1495 :
1496 24 : void lcl_TextFrameShadow(std::vector< std::pair<OString, OString> >& rFlyProperties, const SwFrmFmt& rFrmFmt)
1497 : {
1498 24 : SvxShadowItem aShadowItem = rFrmFmt.GetShadow();
1499 24 : if (aShadowItem.GetLocation() == SVX_SHADOW_NONE)
1500 42 : return;
1501 :
1502 6 : rFlyProperties.push_back(std::make_pair<OString, OString>("fShadow", OString::number(1)));
1503 :
1504 6 : const Color& rColor = aShadowItem.GetColor();
1505 : // We in fact need RGB to BGR, but the transformation is symmetric.
1506 6 : rFlyProperties.push_back(std::make_pair<OString, OString>("shadowColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
1507 :
1508 : // Twips -> points -> EMUs -- hacky, the intermediate step hides rounding errors on roundtrip.
1509 12 : OString aShadowWidth = OString::number(sal_Int32(aShadowItem.GetWidth() / 20) * 12700);
1510 12 : OString aOffsetX;
1511 12 : OString aOffsetY;
1512 6 : switch (aShadowItem.GetLocation())
1513 : {
1514 : case SVX_SHADOW_TOPLEFT:
1515 0 : aOffsetX = "-" + aShadowWidth;
1516 0 : aOffsetY = "-" + aShadowWidth;
1517 0 : break;
1518 : case SVX_SHADOW_TOPRIGHT:
1519 0 : aOffsetX = aShadowWidth;
1520 0 : aOffsetY = "-" + aShadowWidth;
1521 0 : break;
1522 : case SVX_SHADOW_BOTTOMLEFT:
1523 0 : aOffsetX = "-" + aShadowWidth;
1524 0 : aOffsetY = aShadowWidth;
1525 0 : break;
1526 : case SVX_SHADOW_BOTTOMRIGHT:
1527 6 : aOffsetX = aShadowWidth;
1528 6 : aOffsetY = aShadowWidth;
1529 6 : break;
1530 : case SVX_SHADOW_NONE:
1531 : case SVX_SHADOW_END:
1532 0 : break;
1533 : }
1534 6 : if (!aOffsetX.isEmpty())
1535 6 : rFlyProperties.push_back(std::make_pair<OString, OString>("shadowOffsetX", OString(aOffsetX)));
1536 6 : if (!aOffsetY.isEmpty())
1537 12 : rFlyProperties.push_back(std::make_pair<OString, OString>("shadowOffsetY", OString(aOffsetY)));
1538 : }
1539 :
1540 24 : void lcl_TextFrameRelativeSize(std::vector< std::pair<OString, OString> >& rFlyProperties, const SwFrmFmt& rFrmFmt)
1541 : {
1542 24 : const SwFmtFrmSize& rSize = rFrmFmt.GetFrmSize();
1543 :
1544 : // Relative size of the Text Frame.
1545 24 : if (rSize.GetWidthPercent())
1546 : {
1547 2 : rFlyProperties.push_back(std::make_pair<OString, OString>("pctHoriz", OString::number(rSize.GetWidthPercent() * 10)));
1548 :
1549 2 : OString aRelation;
1550 2 : switch (rSize.GetWidthPercentRelation())
1551 : {
1552 : case text::RelOrientation::PAGE_FRAME:
1553 2 : aRelation = "1"; // page
1554 2 : break;
1555 : default:
1556 0 : aRelation = "0"; // margin
1557 0 : break;
1558 : }
1559 2 : rFlyProperties.push_back(std::make_pair("sizerelh", aRelation));
1560 : }
1561 24 : if (rSize.GetHeightPercent())
1562 : {
1563 2 : rFlyProperties.push_back(std::make_pair<OString, OString>("pctVert", OString::number(rSize.GetHeightPercent() * 10)));
1564 :
1565 2 : OString aRelation;
1566 2 : switch (rSize.GetHeightPercentRelation())
1567 : {
1568 : case text::RelOrientation::PAGE_FRAME:
1569 0 : aRelation = "1"; // page
1570 0 : break;
1571 : default:
1572 2 : aRelation = "0"; // margin
1573 2 : break;
1574 : }
1575 2 : rFlyProperties.push_back(std::make_pair("sizerelv", aRelation));
1576 : }
1577 24 : }
1578 :
1579 26 : void RtfAttributeOutput::writeTextFrame(const sw::Frame& rFrame, bool bTextBox)
1580 : {
1581 26 : RtfStringBuffer aRunText;
1582 26 : if (bTextBox)
1583 : {
1584 2 : m_rExport.setStream();
1585 2 : aRunText = m_aRunText;
1586 2 : m_aRunText.clear();
1587 : }
1588 :
1589 26 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHPTXT);
1590 :
1591 : {
1592 : // Save table state, in case the inner text also contains a table.
1593 26 : ww8::WW8TableInfo::Pointer_t pTableInfoOrig = m_rExport.mpTableInfo;
1594 26 : m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
1595 26 : SwWriteTable* pTableWrt = m_pTableWrt;
1596 26 : m_pTableWrt = 0;
1597 26 : sal_uInt32 nTableDepth = m_nTableDepth;
1598 :
1599 26 : m_nTableDepth = 0;
1600 : /*
1601 : * Save m_aRun as we should not lose the opening brace.
1602 : * OTOH, just drop the contents of m_aRunText in case something
1603 : * would be there, causing a problem later.
1604 : */
1605 52 : OString aSave = m_aRun.makeStringAndClear();
1606 : // Also back m_bInRun and m_bSingleEmptyRun up.
1607 26 : bool bInRunOrig = m_bInRun;
1608 26 : m_bInRun = false;
1609 26 : bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
1610 26 : m_bSingleEmptyRun = false;
1611 26 : m_rExport.bRTFFlySyntax = true;
1612 :
1613 26 : const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
1614 26 : const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
1615 26 : sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
1616 26 : sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1617 26 : m_rExport.SaveData(nStt, nEnd);
1618 26 : m_rExport.mpParentFrame = &rFrame;
1619 26 : m_rExport.WriteText();
1620 26 : m_rExport.RestoreData();
1621 :
1622 26 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PARD);
1623 26 : m_rExport.bRTFFlySyntax = false;
1624 26 : m_aRun->append(aSave);
1625 26 : m_aRunText.clear();
1626 26 : m_bInRun = bInRunOrig;
1627 26 : m_bSingleEmptyRun = bSingleEmptyRunOrig;
1628 :
1629 : // Restore table state.
1630 26 : m_rExport.mpTableInfo = pTableInfoOrig;
1631 26 : delete m_pTableWrt;
1632 26 : m_pTableWrt = pTableWrt;
1633 52 : m_nTableDepth = nTableDepth;
1634 : }
1635 :
1636 26 : m_rExport.mpParentFrame = NULL;
1637 :
1638 26 : m_rExport.Strm().WriteChar('}'); // shptxt
1639 :
1640 26 : if (bTextBox)
1641 : {
1642 2 : m_aRunText = aRunText;
1643 2 : m_aRunText->append(m_rExport.getStream());
1644 2 : m_rExport.resetStream();
1645 26 : }
1646 26 : }
1647 :
1648 118 : void RtfAttributeOutput::OutputFlyFrame_Impl(const sw::Frame& rFrame, const Point& /*rNdTopLeft*/)
1649 : {
1650 118 : const SwNode* pNode = rFrame.GetContent();
1651 118 : const SwGrfNode* pGrfNode = pNode ? pNode->GetGrfNode() : 0;
1652 :
1653 118 : switch (rFrame.GetWriterType())
1654 : {
1655 : case sw::Frame::eTxtBox:
1656 : {
1657 : // If this is a TextBox of a shape, then ignore: it's handled in RtfSdrExport::StartShape().
1658 26 : if (m_rExport.SdrExporter().isTextBox(rFrame.GetFrmFmt()))
1659 2 : break;
1660 :
1661 : OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
1662 24 : m_rExport.mpParentFrame = &rFrame;
1663 :
1664 24 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHP);
1665 24 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPINST);
1666 :
1667 : // Shape properties.
1668 24 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("shapeType", OString::number(ESCHER_ShpInst_TextBox)));
1669 :
1670 : // When a frame has some low height, but automatically expanded due
1671 : // to lots of contents, this size contains the real size.
1672 24 : const Size aSize = rFrame.GetSize();
1673 24 : m_pFlyFrameSize = &aSize;
1674 :
1675 24 : m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = true;
1676 24 : m_rExport.OutputFormat(rFrame.GetFrmFmt(), false, false, true);
1677 24 : m_rExport.Strm().WriteCharPtr(m_aRunText.makeStringAndClear().getStr());
1678 24 : m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr());
1679 24 : m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = false;
1680 24 : m_pFlyFrameSize = 0;
1681 :
1682 24 : const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
1683 24 : lcl_TextFrameShadow(m_aFlyProperties, rFrmFmt);
1684 24 : lcl_TextFrameRelativeSize(m_aFlyProperties, rFrmFmt);
1685 :
1686 400 : for (size_t i = 0; i < m_aFlyProperties.size(); ++i)
1687 : {
1688 376 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{");
1689 376 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SN " ");
1690 376 : m_rExport.Strm().WriteCharPtr(m_aFlyProperties[i].first.getStr());
1691 376 : m_rExport.Strm().WriteCharPtr("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
1692 376 : m_rExport.Strm().WriteCharPtr(m_aFlyProperties[i].second.getStr());
1693 376 : m_rExport.Strm().WriteCharPtr("}}");
1694 : }
1695 24 : m_aFlyProperties.clear();
1696 :
1697 24 : writeTextFrame(rFrame);
1698 :
1699 24 : m_rExport.Strm().WriteChar('}'); // shpinst
1700 24 : m_rExport.Strm().WriteChar('}'); // shp
1701 :
1702 24 : m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
1703 : }
1704 24 : break;
1705 : case sw::Frame::eGraphic:
1706 14 : if (!rFrame.IsInline())
1707 : {
1708 8 : m_rExport.mpParentFrame = &rFrame;
1709 8 : m_rExport.bRTFFlySyntax = true;
1710 8 : m_rExport.OutputFormat(rFrame.GetFrmFmt(), false, false, true);
1711 8 : m_rExport.bRTFFlySyntax = false;
1712 8 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
1713 8 : m_rExport.OutputFormat(rFrame.GetFrmFmt(), false, false, true);
1714 8 : m_aRunText->append('}');
1715 8 : m_rExport.mpParentFrame = NULL;
1716 : }
1717 :
1718 14 : if (pGrfNode)
1719 14 : m_aRunText.append(dynamic_cast<const SwFlyFrmFmt*>(&rFrame.GetFrmFmt()), pGrfNode);
1720 14 : break;
1721 : case sw::Frame::eDrawing:
1722 : {
1723 18 : const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
1724 18 : if (pSdrObj)
1725 : {
1726 18 : bool bSwapInPage = false;
1727 18 : if (!pSdrObj->GetPage())
1728 : {
1729 0 : if (SwDrawModel* pModel = m_rExport.pDoc->getIDocumentDrawModelAccess().GetDrawModel())
1730 : {
1731 0 : if (SdrPage* pPage = pModel->GetPage(0))
1732 : {
1733 0 : bSwapInPage = true;
1734 0 : const_cast< SdrObject* >(pSdrObj)->SetPage(pPage);
1735 : }
1736 : }
1737 : }
1738 :
1739 18 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{");
1740 18 : m_aRunText->append(OOO_STRING_SVTOOLS_RTF_IGNORE);
1741 18 : m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLDINST);
1742 18 : m_aRunText->append(" SHAPE ");
1743 18 : m_aRunText->append("}" "{" OOO_STRING_SVTOOLS_RTF_FLDRSLT);
1744 :
1745 18 : m_rExport.SdrExporter().AddSdrObject(*pSdrObj);
1746 :
1747 18 : m_aRunText->append('}');
1748 18 : m_aRunText->append('}');
1749 :
1750 18 : if (bSwapInPage)
1751 0 : const_cast< SdrObject* >(pSdrObj)->SetPage(0);
1752 : }
1753 : }
1754 18 : break;
1755 : case sw::Frame::eFormControl:
1756 : {
1757 0 : const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
1758 0 : const SdrObject* pObject = rFrmFmt.FindRealSdrObject();
1759 :
1760 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1761 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST);
1762 :
1763 0 : if (pObject && pObject->GetObjInventor() == FmFormInventor)
1764 : {
1765 0 : if (const SdrUnoObj* pFormObj = PTR_CAST(SdrUnoObj,pObject))
1766 : {
1767 : uno::Reference< awt::XControlModel > xControlModel =
1768 0 : pFormObj->GetUnoControlModel();
1769 0 : uno::Reference< lang::XServiceInfo > xInfo(xControlModel, uno::UNO_QUERY);
1770 0 : uno::Reference<beans::XPropertySet> xPropSet(xControlModel, uno::UNO_QUERY);
1771 0 : uno::Reference<beans::XPropertySetInfo> xPropSetInfo = xPropSet->getPropertySetInfo();
1772 0 : OUString sName;
1773 0 : if (xInfo->supportsService("com.sun.star.form.component.CheckBox"))
1774 : {
1775 :
1776 0 : m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMCHECKBOX)), m_rExport.eCurrentEncoding));
1777 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
1778 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "1"); // 1 = checkbox
1779 : // checkbox size in half points, this seems to be always 20, see WW8Export::DoCheckBox()
1780 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHPS "20");
1781 :
1782 0 : OUString aStr;
1783 0 : sName = "Name";
1784 0 : if (xPropSetInfo->hasPropertyByName(sName))
1785 : {
1786 0 : xPropSet->getPropertyValue(sName) >>= aStr;
1787 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
1788 0 : m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1789 0 : m_aRun->append('}');
1790 : }
1791 :
1792 0 : sName = "HelpText";
1793 0 : if (xPropSetInfo->hasPropertyByName(sName))
1794 : {
1795 0 : xPropSet->getPropertyValue(sName) >>= aStr;
1796 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
1797 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
1798 0 : m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1799 0 : m_aRun->append('}');
1800 : }
1801 :
1802 0 : sName = "HelpF1Text";
1803 0 : if (xPropSetInfo->hasPropertyByName(sName))
1804 : {
1805 0 : xPropSet->getPropertyValue(sName) >>= aStr;
1806 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
1807 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
1808 0 : m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1809 0 : m_aRun->append('}');
1810 : }
1811 :
1812 0 : sal_Int16 nTemp = 0;
1813 0 : xPropSet->getPropertyValue("DefaultState") >>= nTemp;
1814 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
1815 0 : m_aRun->append((sal_Int32)nTemp);
1816 0 : xPropSet->getPropertyValue("State") >>= nTemp;
1817 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
1818 0 : m_aRun->append((sal_Int32)nTemp);
1819 :
1820 0 : m_aRun->append("}}");
1821 :
1822 : // field result is empty, ffres already contains the form result
1823 0 : m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1824 : }
1825 0 : else if (xInfo->supportsService("com.sun.star.form.component.TextField"))
1826 : {
1827 0 : OStringBuffer aBuf;
1828 0 : OString aStr;
1829 0 : OUString aTmp;
1830 : const sal_Char* pStr;
1831 :
1832 0 : m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMTEXT)), m_rExport.eCurrentEncoding));
1833 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_DATAFIELD " ");
1834 0 : for (int i = 0; i < 8; i++) aBuf.append((sal_Char)0x00);
1835 0 : xPropSet->getPropertyValue("Name") >>= aTmp;
1836 0 : aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
1837 0 : aBuf.append((sal_Char)aStr.getLength());
1838 0 : aBuf.append(aStr);
1839 0 : aBuf.append((sal_Char)0x00);
1840 0 : xPropSet->getPropertyValue("DefaultText") >>= aTmp;
1841 0 : aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
1842 0 : aBuf.append((sal_Char)aStr.getLength());
1843 0 : aBuf.append(aStr);
1844 0 : for (int i = 0; i < 11; i++) aBuf.append((sal_Char)0x00);
1845 0 : aStr = aBuf.makeStringAndClear();
1846 0 : pStr = aStr.getStr();
1847 0 : for (int i = 0; i < aStr.getLength(); i++, pStr++)
1848 0 : m_aRun->append(msfilter::rtfutil::OutHex(*pStr, 2));
1849 0 : m_aRun->append('}');
1850 0 : m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1851 0 : xPropSet->getPropertyValue("Text") >>= aTmp;
1852 0 : m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
1853 0 : m_aRun->append('}');
1854 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
1855 0 : sName = "HelpText";
1856 0 : if (xPropSetInfo->hasPropertyByName(sName))
1857 : {
1858 0 : xPropSet->getPropertyValue(sName) >>= aTmp;
1859 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
1860 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
1861 0 : m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
1862 0 : m_aRun->append('}');
1863 : }
1864 :
1865 0 : sName = "HelpF1Text";
1866 0 : if (xPropSetInfo->hasPropertyByName(sName))
1867 : {
1868 0 : xPropSet->getPropertyValue(sName) >>= aTmp;
1869 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
1870 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
1871 0 : m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
1872 0 : m_aRun->append('}');
1873 : }
1874 0 : m_aRun->append("}");
1875 : }
1876 0 : else if (xInfo->supportsService("com.sun.star.form.component.ListBox"))
1877 : {
1878 0 : OUString aStr;
1879 0 : uno::Sequence<sal_Int16> aIntSeq;
1880 0 : uno::Sequence<OUString> aStrSeq;
1881 :
1882 0 : m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMDROPDOWN)), m_rExport.eCurrentEncoding));
1883 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
1884 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "2"); // 2 = list
1885 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX);
1886 :
1887 0 : xPropSet->getPropertyValue("DefaultSelection") >>= aIntSeq;
1888 0 : if (aIntSeq.getLength())
1889 : {
1890 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
1891 : // a dropdown list can have only one 'selected item by default'
1892 0 : m_aRun->append((sal_Int32)aIntSeq[0]);
1893 : }
1894 :
1895 0 : xPropSet->getPropertyValue("SelectedItems") >>= aIntSeq;
1896 0 : if (aIntSeq.getLength())
1897 : {
1898 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
1899 : // a dropdown list can have only one 'currently selected item'
1900 0 : m_aRun->append((sal_Int32)aIntSeq[0]);
1901 : }
1902 :
1903 0 : sName = "Name";
1904 0 : if (xPropSetInfo->hasPropertyByName(sName))
1905 : {
1906 0 : xPropSet->getPropertyValue(sName) >>= aStr;
1907 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
1908 0 : m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1909 0 : m_aRun->append('}');
1910 : }
1911 :
1912 0 : sName = "HelpText";
1913 0 : if (xPropSetInfo->hasPropertyByName(sName))
1914 : {
1915 0 : xPropSet->getPropertyValue(sName) >>= aStr;
1916 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
1917 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
1918 0 : m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1919 0 : m_aRun->append('}');
1920 : }
1921 :
1922 0 : sName = "HelpF1Text";
1923 0 : if (xPropSetInfo->hasPropertyByName(sName))
1924 : {
1925 0 : xPropSet->getPropertyValue(sName) >>= aStr;
1926 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
1927 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
1928 0 : m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1929 0 : m_aRun->append('}');
1930 : }
1931 :
1932 0 : xPropSet->getPropertyValue("StringItemList") >>= aStrSeq;
1933 0 : sal_uInt32 nListItems = aStrSeq.getLength();
1934 0 : for (sal_uInt32 i = 0; i < nListItems; i++)
1935 0 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFL " ")
1936 0 : .append(OUStringToOString(aStrSeq[i], m_rExport.eCurrentEncoding)).append('}');
1937 :
1938 0 : m_aRun->append("}}");
1939 :
1940 : // field result is empty, ffres already contains the form result
1941 0 : m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1942 : }
1943 : else
1944 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " unhandled form control: '" << xInfo->getImplementationName()<< "'");
1945 0 : m_aRun->append('}');
1946 : }
1947 : }
1948 :
1949 0 : m_aRun->append('}');
1950 : }
1951 0 : break;
1952 : case sw::Frame::eOle:
1953 : {
1954 60 : const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
1955 60 : const SdrObject* pSdrObj = rFrmFmt.FindRealSdrObject();
1956 60 : if (pSdrObj)
1957 : {
1958 60 : SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
1959 60 : SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
1960 60 : FlyFrameOLE(dynamic_cast<const SwFlyFrmFmt*>(&rFrmFmt), rOLENd, rFrame.GetLayoutSize());
1961 : }
1962 : }
1963 60 : break;
1964 : default:
1965 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << ": unknown type (" << (int)rFrame.GetWriterType() << ")");
1966 0 : break;
1967 : }
1968 118 : }
1969 :
1970 22 : void RtfAttributeOutput::CharCaseMap(const SvxCaseMapItem& rCaseMap)
1971 : {
1972 22 : switch (rCaseMap.GetValue())
1973 : {
1974 : case SVX_CASEMAP_KAPITAELCHEN:
1975 8 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
1976 8 : break;
1977 : case SVX_CASEMAP_VERSALIEN:
1978 10 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
1979 10 : break;
1980 : default: // Something that rtf does not support
1981 4 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
1982 4 : m_aStyles.append((sal_Int32)0);
1983 4 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
1984 4 : m_aStyles.append((sal_Int32)0);
1985 4 : break;
1986 : }
1987 22 : }
1988 :
1989 436 : void RtfAttributeOutput::CharColor(const SvxColorItem& rColor)
1990 : {
1991 436 : const Color aColor(rColor.GetValue());
1992 :
1993 436 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CF);
1994 436 : m_aStyles.append((sal_Int32)m_rExport.GetColor(aColor));
1995 436 : }
1996 :
1997 6 : void RtfAttributeOutput::CharContour(const SvxContourItem& rContour)
1998 : {
1999 6 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTL);
2000 6 : if (!rContour.GetValue())
2001 6 : m_aStyles.append((sal_Int32)0);
2002 6 : }
2003 :
2004 0 : void RtfAttributeOutput::CharCrossedOut(const SvxCrossedOutItem& rCrossedOut)
2005 : {
2006 0 : switch (rCrossedOut.GetStrikeout())
2007 : {
2008 : case STRIKEOUT_NONE:
2009 0 : if (!m_bStrikeDouble)
2010 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
2011 : else
2012 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
2013 0 : m_aStyles.append((sal_Int32)0);
2014 0 : break;
2015 : case STRIKEOUT_DOUBLE:
2016 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
2017 0 : m_aStyles.append((sal_Int32)1);
2018 0 : break;
2019 : default:
2020 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
2021 0 : break;
2022 : }
2023 0 : }
2024 :
2025 24 : void RtfAttributeOutput::CharEscapement(const SvxEscapementItem& rEsc)
2026 : {
2027 24 : short nEsc = rEsc.GetEsc();
2028 24 : if (rEsc.GetProp() == DFLT_ESC_PROP)
2029 : {
2030 24 : if (DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc)
2031 2 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUB);
2032 22 : else if (DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc)
2033 22 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUPER);
2034 48 : return;
2035 : }
2036 :
2037 : const char* pUpDn;
2038 :
2039 0 : SwTwips nH = ((SvxFontHeightItem&)m_rExport.GetItem(RES_CHRATR_FONTSIZE)).GetHeight();
2040 :
2041 0 : if (0 < rEsc.GetEsc())
2042 0 : pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
2043 0 : else if (0 > rEsc.GetEsc())
2044 : {
2045 0 : pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
2046 0 : nH = -nH;
2047 : }
2048 : else
2049 0 : return;
2050 :
2051 0 : short nProp = rEsc.GetProp() * 100;
2052 0 : if (DFLT_ESC_AUTO_SUPER == nEsc)
2053 : {
2054 0 : nEsc = 100 - rEsc.GetProp();
2055 0 : ++nProp;
2056 : }
2057 0 : else if (DFLT_ESC_AUTO_SUB == nEsc)
2058 : {
2059 0 : nEsc = - 100 + rEsc.GetProp();
2060 0 : ++nProp;
2061 : }
2062 :
2063 0 : m_aStyles.append('{');
2064 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
2065 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_UPDNPROP);
2066 0 : m_aStyles.append((sal_Int32)nProp);
2067 0 : m_aStyles.append('}');
2068 0 : m_aStyles.append(pUpDn);
2069 :
2070 : /*
2071 : * Calculate the act. FontSize and the percentage of the displacement;
2072 : * RTF file expects half points, while internally it's in twips.
2073 : * Formally : (FontSize * 1/20 ) pts x * 2
2074 : * ----------------------- = ------------
2075 : * 100% Escapement
2076 : */
2077 :
2078 0 : m_aStyles.append((sal_Int32)((long(nEsc) * nH) + 500L) / 1000L);
2079 : // 500L to round !!
2080 : }
2081 :
2082 1148 : void RtfAttributeOutput::CharFont(const SvxFontItem& rFont)
2083 : {
2084 1148 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
2085 1148 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_F);
2086 1148 : m_aStylesEnd.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
2087 : // FIXME: this may be a tad expensive... but the charset needs to be
2088 : // consistent with what wwFont::WriteRtf() does
2089 1148 : FontMapExport aTmp(rFont.GetFamilyName());
2090 1148 : sal_uInt8 nWindowsCharset = sw::ms::rtl_TextEncodingToWinCharsetRTF(aTmp.msPrimary, aTmp.msSecondary, rFont.GetCharSet());
2091 1148 : m_rExport.eCurrentEncoding = rtl_getTextEncodingFromWindowsCharset(nWindowsCharset);
2092 1148 : if (m_rExport.eCurrentEncoding == RTL_TEXTENCODING_DONTKNOW)
2093 0 : m_rExport.eCurrentEncoding = m_rExport.eDefaultEncoding;
2094 1148 : }
2095 :
2096 2502 : void RtfAttributeOutput::CharFontSize(const SvxFontHeightItem& rFontSize)
2097 : {
2098 2502 : switch (rFontSize.Which())
2099 : {
2100 : case RES_CHRATR_FONTSIZE:
2101 1338 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_FS);
2102 1338 : m_aStylesEnd.append((sal_Int32)(rFontSize.GetHeight() / 10));
2103 1338 : break;
2104 : case RES_CHRATR_CJK_FONTSIZE:
2105 2 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FS);
2106 2 : m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10));
2107 2 : break;
2108 : case RES_CHRATR_CTL_FONTSIZE:
2109 1162 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AFS);
2110 1162 : m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10));
2111 1162 : break;
2112 : }
2113 2502 : }
2114 :
2115 12 : void RtfAttributeOutput::CharKerning(const SvxKerningItem& rKerning)
2116 : {
2117 : // in quarter points then in twips
2118 12 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPND);
2119 12 : m_aStyles.append((sal_Int32)(rKerning.GetValue() / 5));
2120 12 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPNDTW);
2121 12 : m_aStyles.append((sal_Int32)(rKerning.GetValue()));
2122 12 : }
2123 :
2124 888 : void RtfAttributeOutput::CharLanguage(const SvxLanguageItem& rLanguage)
2125 : {
2126 888 : switch (rLanguage.Which())
2127 : {
2128 : case RES_CHRATR_LANGUAGE:
2129 266 : m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LANG);
2130 266 : m_aStylesEnd.append((sal_Int32)rLanguage.GetLanguage());
2131 266 : break;
2132 : case RES_CHRATR_CJK_LANGUAGE:
2133 318 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANGFE);
2134 318 : m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
2135 318 : break;
2136 : case RES_CHRATR_CTL_LANGUAGE:
2137 304 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ALANG);
2138 304 : m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
2139 304 : break;
2140 : }
2141 888 : }
2142 :
2143 266 : void RtfAttributeOutput::CharPosture(const SvxPostureItem& rPosture)
2144 : {
2145 266 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
2146 266 : if (rPosture.GetPosture() == ITALIC_NONE)
2147 78 : m_aStyles.append((sal_Int32)0);
2148 266 : }
2149 :
2150 0 : void RtfAttributeOutput::CharShadow(const SvxShadowedItem& rShadow)
2151 : {
2152 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SHAD);
2153 0 : if (!rShadow.GetValue())
2154 0 : m_aStyles.append((sal_Int32)0);
2155 0 : }
2156 :
2157 104 : void RtfAttributeOutput::CharUnderline(const SvxUnderlineItem& rUnderline)
2158 : {
2159 104 : const char* pStr = 0;
2160 104 : const SfxPoolItem* pItem = m_rExport.HasItem(RES_CHRATR_WORDLINEMODE);
2161 104 : bool bWord = false;
2162 104 : if (pItem)
2163 0 : bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;
2164 104 : switch (rUnderline.GetLineStyle())
2165 : {
2166 : case UNDERLINE_SINGLE:
2167 28 : pStr = bWord ? OOO_STRING_SVTOOLS_RTF_ULW : OOO_STRING_SVTOOLS_RTF_UL;
2168 28 : break;
2169 : case UNDERLINE_DOUBLE:
2170 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULDB;
2171 0 : break;
2172 : case UNDERLINE_NONE:
2173 70 : pStr = OOO_STRING_SVTOOLS_RTF_ULNONE;
2174 70 : break;
2175 : case UNDERLINE_DOTTED:
2176 6 : pStr = OOO_STRING_SVTOOLS_RTF_ULD;
2177 6 : break;
2178 : case UNDERLINE_DASH:
2179 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULDASH;
2180 0 : break;
2181 : case UNDERLINE_DASHDOT:
2182 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULDASHD;
2183 0 : break;
2184 : case UNDERLINE_DASHDOTDOT:
2185 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULDASHDD;
2186 0 : break;
2187 : case UNDERLINE_BOLD:
2188 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULTH;
2189 0 : break;
2190 : case UNDERLINE_WAVE:
2191 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULWAVE;
2192 0 : break;
2193 : case UNDERLINE_BOLDDOTTED:
2194 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULTHD;
2195 0 : break;
2196 : case UNDERLINE_BOLDDASH:
2197 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASH;
2198 0 : break;
2199 : case UNDERLINE_LONGDASH:
2200 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULLDASH;
2201 0 : break;
2202 : case UNDERLINE_BOLDLONGDASH:
2203 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULTHLDASH;
2204 0 : break;
2205 : case UNDERLINE_BOLDDASHDOT:
2206 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHD;
2207 0 : break;
2208 : case UNDERLINE_BOLDDASHDOTDOT:
2209 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHDD;
2210 0 : break;
2211 : case UNDERLINE_BOLDWAVE:
2212 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULHWAVE;
2213 0 : break;
2214 : case UNDERLINE_DOUBLEWAVE:
2215 0 : pStr = OOO_STRING_SVTOOLS_RTF_ULULDBWAVE;
2216 0 : break;
2217 : default:
2218 0 : break;
2219 : }
2220 :
2221 104 : if (pStr)
2222 : {
2223 104 : m_aStyles.append(pStr);
2224 : // NEEDSWORK looks like here rUnderline.GetColor() is always black,
2225 : // even if the color in the odt is for example green...
2226 104 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ULC);
2227 104 : m_aStyles.append((sal_Int32)m_rExport.GetColor(rUnderline.GetColor()));
2228 : }
2229 104 : }
2230 :
2231 434 : void RtfAttributeOutput::CharWeight(const SvxWeightItem& rWeight)
2232 : {
2233 434 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
2234 434 : if (rWeight.GetWeight() != WEIGHT_BOLD)
2235 182 : m_aStyles.append((sal_Int32)0);
2236 434 : }
2237 :
2238 170 : void RtfAttributeOutput::CharAutoKern(const SvxAutoKernItem& rAutoKern)
2239 : {
2240 170 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KERNING);
2241 170 : m_aStyles.append((sal_Int32)(rAutoKern.GetValue() ? 1 : 0));
2242 170 : }
2243 :
2244 0 : void RtfAttributeOutput::CharAnimatedText(const SvxBlinkItem& rBlink)
2245 : {
2246 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ANIMTEXT);
2247 0 : m_aStyles.append((sal_Int32)(rBlink.GetValue() ? 2 : 0));
2248 0 : }
2249 :
2250 158 : void RtfAttributeOutput::CharBackground(const SvxBrushItem& rBrush)
2251 : {
2252 158 : if (!rBrush.GetColor().GetTransparency())
2253 : {
2254 50 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HIGHLIGHT);
2255 50 : m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
2256 : }
2257 158 : }
2258 :
2259 524 : void RtfAttributeOutput::CharFontCJK(const SvxFontItem& rFont)
2260 : {
2261 524 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2262 524 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
2263 524 : m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
2264 524 : }
2265 :
2266 2 : void RtfAttributeOutput::CharFontSizeCJK(const SvxFontHeightItem& rFontSize)
2267 : {
2268 2 : CharFontSize(rFontSize);
2269 2 : }
2270 :
2271 318 : void RtfAttributeOutput::CharLanguageCJK(const SvxLanguageItem& rLanguageItem)
2272 : {
2273 318 : CharLanguage(rLanguageItem);
2274 318 : }
2275 :
2276 0 : void RtfAttributeOutput::CharPostureCJK(const SvxPostureItem& rPosture)
2277 : {
2278 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
2279 0 : if (rPosture.GetPosture() == ITALIC_NONE)
2280 0 : m_aStyles.append((sal_Int32)0);
2281 0 : }
2282 :
2283 0 : void RtfAttributeOutput::CharWeightCJK(const SvxWeightItem& rWeight)
2284 : {
2285 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
2286 0 : if (rWeight.GetWeight() != WEIGHT_BOLD)
2287 0 : m_aStyles.append((sal_Int32)0);
2288 0 : }
2289 :
2290 720 : void RtfAttributeOutput::CharFontCTL(const SvxFontItem& rFont)
2291 : {
2292 720 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2293 720 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
2294 720 : m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
2295 720 : }
2296 :
2297 1162 : void RtfAttributeOutput::CharFontSizeCTL(const SvxFontHeightItem& rFontSize)
2298 : {
2299 1162 : CharFontSize(rFontSize);
2300 1162 : }
2301 :
2302 304 : void RtfAttributeOutput::CharLanguageCTL(const SvxLanguageItem& rLanguageItem)
2303 : {
2304 304 : CharLanguage(rLanguageItem);
2305 304 : }
2306 :
2307 242 : void RtfAttributeOutput::CharPostureCTL(const SvxPostureItem& rPosture)
2308 : {
2309 242 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AI);
2310 242 : if (rPosture.GetPosture() == ITALIC_NONE)
2311 50 : m_aStyles.append((sal_Int32)0);
2312 242 : }
2313 :
2314 374 : void RtfAttributeOutput::CharWeightCTL(const SvxWeightItem& rWeight)
2315 : {
2316 374 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AB);
2317 374 : if (rWeight.GetWeight() != WEIGHT_BOLD)
2318 174 : m_aStyles.append((sal_Int32)0);
2319 374 : }
2320 :
2321 0 : void RtfAttributeOutput::CharBidiRTL(const SfxPoolItem&)
2322 : {
2323 0 : }
2324 :
2325 6 : void RtfAttributeOutput::CharIdctHint(const SfxPoolItem&)
2326 : {
2327 6 : }
2328 :
2329 4 : void RtfAttributeOutput::CharRotate(const SvxCharRotateItem& rRotate)
2330 : {
2331 4 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HORZVERT);
2332 4 : m_aStyles.append((sal_Int32)(rRotate.IsFitToLine() ? 1 : 0));
2333 4 : }
2334 :
2335 12 : void RtfAttributeOutput::CharEmphasisMark(const SvxEmphasisMarkItem& rEmphasisMark)
2336 : {
2337 12 : switch (rEmphasisMark.GetEmphasisMark())
2338 : {
2339 : case EMPHASISMARK_NONE:
2340 4 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCNONE);
2341 4 : break;
2342 : case EMPHASISMARK_DOT | EMPHASISMARK_POS_ABOVE:
2343 2 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCDOT);
2344 2 : break;
2345 : case EMPHASISMARK_ACCENT | EMPHASISMARK_POS_ABOVE:
2346 2 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCOMMA);
2347 2 : break;
2348 : case EMPHASISMARK_CIRCLE | EMPHASISMARK_POS_ABOVE:
2349 2 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCIRCLE);
2350 2 : break;
2351 : case EMPHASISMARK_DOT|EMPHASISMARK_POS_BELOW:
2352 2 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCUNDERDOT);
2353 2 : break;
2354 : }
2355 12 : }
2356 :
2357 0 : void RtfAttributeOutput::CharTwoLines(const SvxTwoLinesItem& rTwoLines)
2358 : {
2359 0 : if (rTwoLines.GetValue())
2360 : {
2361 0 : sal_Unicode cStart = rTwoLines.GetStartBracket();
2362 0 : sal_Unicode cEnd = rTwoLines.GetEndBracket();
2363 :
2364 : sal_uInt16 nType;
2365 0 : if (!cStart && !cEnd)
2366 0 : nType = 0;
2367 0 : else if ('{' == cStart || '}' == cEnd)
2368 0 : nType = 4;
2369 0 : else if ('<' == cStart || '>' == cEnd)
2370 0 : nType = 3;
2371 0 : else if ('[' == cStart || ']' == cEnd)
2372 0 : nType = 2;
2373 : else // all other kind of brackets
2374 0 : nType = 1;
2375 :
2376 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TWOINONE);
2377 0 : m_aStyles.append((sal_Int32)nType);
2378 : }
2379 0 : }
2380 :
2381 0 : void RtfAttributeOutput::CharScaleWidth(const SvxCharScaleWidthItem& rScaleWidth)
2382 : {
2383 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHARSCALEX);
2384 0 : m_aStyles.append((sal_Int32)rScaleWidth.GetValue());
2385 0 : }
2386 :
2387 10 : void RtfAttributeOutput::CharRelief(const SvxCharReliefItem& rRelief)
2388 : {
2389 : const sal_Char* pStr;
2390 10 : switch (rRelief.GetValue())
2391 : {
2392 : case RELIEF_EMBOSSED:
2393 0 : pStr = OOO_STRING_SVTOOLS_RTF_EMBO;
2394 0 : break;
2395 : case RELIEF_ENGRAVED:
2396 0 : pStr = OOO_STRING_SVTOOLS_RTF_IMPR;
2397 0 : break;
2398 : default:
2399 10 : pStr = 0;
2400 10 : break;
2401 : }
2402 :
2403 10 : if (pStr)
2404 0 : m_aStyles.append(pStr);
2405 10 : }
2406 :
2407 0 : void RtfAttributeOutput::CharHidden(const SvxCharHiddenItem& rHidden)
2408 : {
2409 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_V);
2410 0 : if (!rHidden.GetValue())
2411 0 : m_aStyles.append((sal_Int32)0);
2412 0 : }
2413 :
2414 4 : void RtfAttributeOutput::CharBorder(const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow)
2415 : {
2416 4 : m_aStyles.append(OutBorderLine(m_rExport, pAllBorder, OOO_STRING_SVTOOLS_RTF_CHBRDR, nDist, bShadow ? SVX_SHADOW_BOTTOMRIGHT : SVX_SHADOW_NONE));
2417 4 : }
2418 :
2419 10 : void RtfAttributeOutput::TextINetFormat(const SwFmtINetFmt& rURL)
2420 : {
2421 10 : if (!rURL.GetValue().isEmpty())
2422 : {
2423 : const SwCharFmt* pFmt;
2424 10 : const SwTxtINetFmt* pTxtAtr = rURL.GetTxtINetFmt();
2425 :
2426 10 : if (pTxtAtr && 0 != (pFmt = pTxtAtr->GetCharFmt()))
2427 : {
2428 10 : sal_uInt16 nStyle = m_rExport.GetId(pFmt);
2429 10 : OString* pString = m_rExport.GetStyle(nStyle);
2430 10 : if (pString)
2431 10 : m_aStyles.append(*pString);
2432 : }
2433 : }
2434 10 : }
2435 :
2436 0 : void RtfAttributeOutput::TextCharFormat(const SwFmtCharFmt& rCharFmt)
2437 : {
2438 0 : sal_uInt16 nStyle = m_rExport.GetId(rCharFmt.GetCharFmt());
2439 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CS);
2440 0 : m_aStyles.append((sal_Int32)nStyle);
2441 0 : OString* pString = m_rExport.GetStyle(nStyle);
2442 0 : if (pString)
2443 0 : m_aStyles.append(*pString);
2444 0 : }
2445 :
2446 12 : void RtfAttributeOutput::WriteTextFootnoteNumStr(const SwFmtFtn& rFootnote)
2447 : {
2448 12 : if (rFootnote.GetNumStr().isEmpty())
2449 12 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_CHFTN);
2450 : else
2451 0 : m_aRun->append(msfilter::rtfutil::OutString(rFootnote.GetNumStr(), m_rExport.eCurrentEncoding));
2452 12 : }
2453 :
2454 6 : void RtfAttributeOutput::TextFootnote_Impl(const SwFmtFtn& rFootnote)
2455 : {
2456 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
2457 :
2458 6 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_SUPER " ");
2459 6 : WriteTextFootnoteNumStr(rFootnote);
2460 6 : m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FOOTNOTE);
2461 6 : if (rFootnote.IsEndNote())
2462 0 : m_aRun->append(OOO_STRING_SVTOOLS_RTF_FTNALT);
2463 6 : m_aRun->append(' ');
2464 6 : WriteTextFootnoteNumStr(rFootnote);
2465 :
2466 : /*
2467 : * The footnote contains a whole paragraph, so we have to:
2468 : * 1) Reset, then later restore the contents of our run buffer and run state.
2469 : * 2) Buffer the output of the whole paragraph, as we do so for section headers already.
2470 : */
2471 6 : const SwNodeIndex* pIndex = rFootnote.GetTxtFtn()->GetStartNode();
2472 6 : RtfStringBuffer aRun = m_aRun;
2473 6 : m_aRun.clear();
2474 6 : bool bInRunOrig = m_bInRun;
2475 6 : m_bInRun = false;
2476 6 : bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
2477 6 : m_bSingleEmptyRun = false;
2478 6 : m_bBufferSectionHeaders = true;
2479 6 : m_rExport.WriteSpecialText(pIndex->GetIndex() + 1,
2480 6 : pIndex->GetNode().EndOfSectionIndex(),
2481 18 : !rFootnote.IsEndNote() ? TXT_FTN : TXT_EDN);
2482 6 : m_bBufferSectionHeaders = false;
2483 6 : m_bInRun = bInRunOrig;
2484 6 : m_bSingleEmptyRun = bSingleEmptyRunOrig;
2485 6 : m_aRun = aRun;
2486 6 : m_aRun->append(m_aSectionHeaders.makeStringAndClear());
2487 :
2488 6 : m_aRun->append("}");
2489 6 : m_aRun->append("}");
2490 :
2491 6 : SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
2492 6 : }
2493 :
2494 296 : void RtfAttributeOutput::ParaLineSpacing_Impl(short nSpace, short nMulti)
2495 : {
2496 296 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SL);
2497 296 : m_aStyles.append((sal_Int32)nSpace);
2498 296 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SLMULT);
2499 296 : m_aStyles.append((sal_Int32)nMulti);
2500 :
2501 296 : }
2502 :
2503 788 : void RtfAttributeOutput::ParaAdjust(const SvxAdjustItem& rAdjust)
2504 : {
2505 788 : switch (rAdjust.GetAdjust())
2506 : {
2507 : case SVX_ADJUST_LEFT:
2508 312 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QL);
2509 312 : break;
2510 : case SVX_ADJUST_RIGHT:
2511 12 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QR);
2512 12 : break;
2513 : case SVX_ADJUST_BLOCKLINE:
2514 : case SVX_ADJUST_BLOCK:
2515 90 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QJ);
2516 90 : break;
2517 : case SVX_ADJUST_CENTER:
2518 374 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QC);
2519 374 : break;
2520 : default:
2521 0 : break;
2522 : }
2523 788 : }
2524 :
2525 62 : void RtfAttributeOutput::ParaSplit(const SvxFmtSplitItem& rSplit)
2526 : {
2527 62 : if (!rSplit.GetValue())
2528 62 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEP);
2529 62 : }
2530 :
2531 252 : void RtfAttributeOutput::ParaWidows(const SvxWidowsItem& rWidows)
2532 : {
2533 252 : if (rWidows.GetValue())
2534 86 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_WIDCTLPAR);
2535 : else
2536 166 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOWIDCTLPAR);
2537 252 : }
2538 :
2539 372 : void RtfAttributeOutput::ParaTabStop(const SvxTabStopItem& rTabStop)
2540 : {
2541 372 : long nOffset = ((SvxLRSpaceItem&)m_rExport.GetItem(RES_LR_SPACE)).GetTxtLeft();
2542 706 : for (sal_uInt16 n = 0; n < rTabStop.Count(); n++)
2543 : {
2544 334 : const SvxTabStop& rTS = rTabStop[ n ];
2545 334 : if (SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment())
2546 : {
2547 194 : const char* pFill = 0;
2548 194 : switch (rTS.GetFill())
2549 : {
2550 : case cDfltFillChar:
2551 126 : break;
2552 :
2553 : case '.':
2554 68 : pFill = OOO_STRING_SVTOOLS_RTF_TLDOT;
2555 68 : break;
2556 : case '_':
2557 0 : pFill = OOO_STRING_SVTOOLS_RTF_TLUL;
2558 0 : break;
2559 : case '-':
2560 0 : pFill = OOO_STRING_SVTOOLS_RTF_TLTH;
2561 0 : break;
2562 : case '=':
2563 0 : pFill = OOO_STRING_SVTOOLS_RTF_TLEQ;
2564 0 : break;
2565 : default:
2566 0 : break;
2567 : }
2568 194 : if (pFill)
2569 68 : m_aStyles.append(pFill);
2570 :
2571 194 : const sal_Char* pAdjStr = 0;
2572 194 : switch (rTS.GetAdjustment())
2573 : {
2574 : case SVX_TAB_ADJUST_RIGHT:
2575 84 : pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
2576 84 : break;
2577 : case SVX_TAB_ADJUST_DECIMAL:
2578 0 : pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
2579 0 : break;
2580 : case SVX_TAB_ADJUST_CENTER:
2581 12 : pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
2582 12 : break;
2583 : default:
2584 98 : break;
2585 : }
2586 194 : if (pAdjStr)
2587 96 : m_aStyles.append(pAdjStr);
2588 194 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TX);
2589 194 : m_aStyles.append((sal_Int32)(rTS.GetTabPos() + nOffset));
2590 : }
2591 : else
2592 : {
2593 140 : m_aTabStop.append(OOO_STRING_SVTOOLS_RTF_DEFTAB);
2594 140 : m_aTabStop.append((sal_Int32)rTabStop[0].GetTabPos());
2595 : }
2596 : }
2597 372 : }
2598 :
2599 144 : void RtfAttributeOutput::ParaHyphenZone(const SvxHyphenZoneItem& rHyphenZone)
2600 : {
2601 144 : sal_Int32 nFlags = rHyphenZone.IsHyphen() ? 1 : 0;
2602 144 : if (rHyphenZone.IsPageEnd())
2603 144 : nFlags += 2;
2604 144 : m_aStyles.append('{');
2605 144 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
2606 144 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHEN);
2607 144 : m_aStyles.append((sal_Int32)nFlags);
2608 144 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHLEAD);
2609 144 : m_aStyles.append((sal_Int32)rHyphenZone.GetMinLead());
2610 144 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHTRAIL);
2611 144 : m_aStyles.append((sal_Int32)rHyphenZone.GetMinTrail());
2612 144 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHMAX);
2613 144 : m_aStyles.append((sal_Int32)rHyphenZone.GetMaxHyphens());
2614 144 : m_aStyles.append('}');
2615 144 : }
2616 :
2617 136 : void RtfAttributeOutput::ParaNumRule_Impl(const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId)
2618 : {
2619 136 : if (USHRT_MAX == nNumId || 0 == nNumId || 0 == pTxtNd)
2620 176 : return;
2621 :
2622 96 : const SwNumRule* pRule = pTxtNd->GetNumRule();
2623 :
2624 96 : if (pRule && pTxtNd->IsInList())
2625 : {
2626 : SAL_WARN_IF(pTxtNd->GetActualListLevel() < 0 || pTxtNd->GetActualListLevel() >= MAXLEVEL, "sw.rtf", "text node does not have valid list level");
2627 :
2628 96 : const SwNumFmt* pFmt = pRule->GetNumFmt(nLvl);
2629 96 : if (!pFmt)
2630 0 : pFmt = &pRule->Get(nLvl);
2631 :
2632 96 : const SfxItemSet& rNdSet = pTxtNd->GetSwAttrSet();
2633 :
2634 96 : m_aStyles.append('{');
2635 96 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LISTTEXT);
2636 96 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PARD);
2637 96 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
2638 96 : m_aStyles.append(' ');
2639 :
2640 96 : SvxLRSpaceItem aLR((SvxLRSpaceItem&)rNdSet.Get(RES_LR_SPACE));
2641 96 : aLR.SetTxtLeft(aLR.GetTxtLeft() + pFmt->GetIndentAt());
2642 96 : aLR.SetTxtFirstLineOfst(pFmt->GetFirstLineOffset());
2643 :
2644 96 : sal_uInt16 nStyle = m_rExport.GetId(pFmt->GetCharFmt());
2645 96 : OString* pString = m_rExport.GetStyle(nStyle);
2646 96 : if (pString)
2647 12 : m_aStyles.append(*pString);
2648 :
2649 : {
2650 96 : OUString sTxt;
2651 96 : if (SVX_NUM_CHAR_SPECIAL == pFmt->GetNumberingType() || SVX_NUM_BITMAP == pFmt->GetNumberingType())
2652 2 : sTxt = OUString(pFmt->GetBulletChar());
2653 : else
2654 94 : sTxt = pTxtNd->GetNumString();
2655 :
2656 96 : if (!sTxt.isEmpty())
2657 : {
2658 30 : m_aStyles.append(' ');
2659 30 : m_aStyles.append(msfilter::rtfutil::OutString(sTxt, m_rExport.eDefaultEncoding));
2660 : }
2661 :
2662 96 : if (OUTLINE_RULE != pRule->GetRuleType())
2663 : {
2664 30 : if (!sTxt.isEmpty())
2665 30 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
2666 30 : m_aStyles.append('}');
2667 30 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
2668 30 : if (nLvl > 8) // RTF knows only 9 levels
2669 : {
2670 0 : m_aStyles.append((sal_Int32)8);
2671 0 : m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SOUTLVL);
2672 0 : m_aStyles.append((sal_Int32)nLvl);
2673 0 : m_aStyles.append('}');
2674 : }
2675 : else
2676 30 : m_aStyles.append((sal_Int32)nLvl);
2677 : }
2678 : else
2679 66 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB "}");
2680 96 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LS);
2681 96 : m_aStyles.append((sal_Int32)m_rExport.GetId(*pRule)+1);
2682 96 : m_aStyles.append(' ');
2683 : }
2684 96 : FormatLRSpace(aLR);
2685 : }
2686 : }
2687 :
2688 36 : void RtfAttributeOutput::ParaScriptSpace(const SfxBoolItem& rScriptSpace)
2689 : {
2690 36 : if (!rScriptSpace.GetValue())
2691 36 : return;
2692 :
2693 36 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ASPALPHA);
2694 : }
2695 :
2696 36 : void RtfAttributeOutput::ParaHangingPunctuation(const SfxBoolItem&)
2697 : {
2698 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2699 36 : }
2700 :
2701 36 : void RtfAttributeOutput::ParaForbiddenRules(const SfxBoolItem&)
2702 : {
2703 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2704 36 : }
2705 :
2706 14 : void RtfAttributeOutput::ParaVerticalAlign(const SvxParaVertAlignItem& rAlign)
2707 : {
2708 : const char* pStr;
2709 14 : switch (rAlign.GetValue())
2710 : {
2711 : case SvxParaVertAlignItem::TOP:
2712 0 : pStr = OOO_STRING_SVTOOLS_RTF_FAHANG;
2713 0 : break;
2714 : case SvxParaVertAlignItem::BOTTOM:
2715 0 : pStr = OOO_STRING_SVTOOLS_RTF_FAVAR;
2716 0 : break;
2717 : case SvxParaVertAlignItem::CENTER:
2718 0 : pStr = OOO_STRING_SVTOOLS_RTF_FACENTER;
2719 0 : break;
2720 : case SvxParaVertAlignItem::BASELINE:
2721 0 : pStr = OOO_STRING_SVTOOLS_RTF_FAROMAN;
2722 0 : break;
2723 :
2724 : default:
2725 14 : pStr = OOO_STRING_SVTOOLS_RTF_FAAUTO;
2726 14 : break;
2727 : }
2728 14 : m_aStyles.append(pStr);
2729 14 : }
2730 :
2731 0 : void RtfAttributeOutput::ParaSnapToGrid(const SvxParaGridItem& /*rGrid*/)
2732 : {
2733 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2734 0 : }
2735 :
2736 386 : void RtfAttributeOutput::FormatFrameSize(const SwFmtFrmSize& rSize)
2737 : {
2738 386 : if (m_rExport.bOutPageDescs)
2739 : {
2740 330 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGWSXN);
2741 330 : m_aSectionBreaks.append((sal_Int32)rSize.GetWidth());
2742 330 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGHSXN);
2743 330 : m_aSectionBreaks.append((sal_Int32)rSize.GetHeight());
2744 330 : if (!m_bBufferSectionBreaks)
2745 320 : m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
2746 : }
2747 386 : }
2748 :
2749 0 : void RtfAttributeOutput::FormatPaperBin(const SvxPaperBinItem&)
2750 : {
2751 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2752 0 : }
2753 :
2754 716 : void RtfAttributeOutput::FormatLRSpace(const SvxLRSpaceItem& rLRSpace)
2755 : {
2756 716 : if (!m_rExport.bOutFlyFrmAttrs)
2757 : {
2758 666 : if (m_rExport.bOutPageDescs)
2759 : {
2760 330 : if (rLRSpace.GetLeft())
2761 : {
2762 328 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGLSXN);
2763 328 : m_aSectionBreaks.append((sal_Int32)rLRSpace.GetLeft());
2764 : }
2765 330 : if (rLRSpace.GetRight())
2766 : {
2767 328 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGRSXN);
2768 328 : m_aSectionBreaks.append((sal_Int32)rLRSpace.GetRight());
2769 : }
2770 330 : if (!m_bBufferSectionBreaks)
2771 320 : m_rExport.Strm(). WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
2772 : }
2773 : else
2774 : {
2775 336 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LI);
2776 336 : m_aStyles.append((sal_Int32) rLRSpace.GetTxtLeft());
2777 336 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RI);
2778 336 : m_aStyles.append((sal_Int32) rLRSpace.GetRight());
2779 336 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LIN);
2780 336 : m_aStyles.append((sal_Int32) rLRSpace.GetTxtLeft());
2781 336 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RIN);
2782 336 : m_aStyles.append((sal_Int32) rLRSpace.GetRight());
2783 336 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FI);
2784 336 : m_aStyles.append((sal_Int32) rLRSpace.GetTxtFirstLineOfst());
2785 : }
2786 : }
2787 50 : else if (m_rExport.bRTFFlySyntax)
2788 : {
2789 : // Wrap: top and bottom spacing, convert from twips to EMUs.
2790 44 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxWrapDistLeft", OString::number(rLRSpace.GetLeft() * 635)));
2791 44 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxWrapDistRight", OString::number(rLRSpace.GetRight() * 635)));
2792 : }
2793 716 : }
2794 :
2795 1198 : void RtfAttributeOutput::FormatULSpace(const SvxULSpaceItem& rULSpace)
2796 : {
2797 1198 : if (!m_rExport.bOutFlyFrmAttrs)
2798 : {
2799 1154 : if (m_rExport.bOutPageDescs)
2800 : {
2801 : OSL_ENSURE(m_rExport.GetCurItemSet(), "Impossible");
2802 330 : if (!m_rExport.GetCurItemSet())
2803 1198 : return;
2804 :
2805 330 : HdFtDistanceGlue aDistances(*m_rExport.GetCurItemSet());
2806 :
2807 330 : if (aDistances.dyaTop)
2808 : {
2809 328 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGTSXN);
2810 328 : m_aSectionBreaks.append((sal_Int32)aDistances.dyaTop);
2811 : }
2812 330 : if (aDistances.HasHeader())
2813 : {
2814 26 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_HEADERY);
2815 26 : m_aSectionBreaks.append((sal_Int32)aDistances.dyaHdrTop);
2816 : }
2817 :
2818 330 : if (aDistances.dyaBottom)
2819 : {
2820 328 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGBSXN);
2821 328 : m_aSectionBreaks.append((sal_Int32)aDistances.dyaBottom);
2822 : }
2823 330 : if (aDistances.HasFooter())
2824 : {
2825 30 : m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_FOOTERY);
2826 30 : m_aSectionBreaks.append((sal_Int32)aDistances.dyaHdrBottom);
2827 : }
2828 330 : if (!m_bBufferSectionBreaks)
2829 320 : m_rExport.Strm(). WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
2830 : }
2831 : else
2832 : {
2833 824 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
2834 824 : m_aStyles.append((sal_Int32) rULSpace.GetUpper());
2835 824 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
2836 824 : m_aStyles.append((sal_Int32) rULSpace.GetLower());
2837 824 : if (rULSpace.GetContext())
2838 2 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CONTEXTUALSPACE);
2839 : }
2840 : }
2841 44 : else if (m_rExport.bRTFFlySyntax)
2842 : {
2843 : // Wrap: top and bottom spacing, convert from twips to EMUs.
2844 40 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyWrapDistTop", OString::number(rULSpace.GetUpper() * 635)));
2845 40 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyWrapDistBottom", OString::number(rULSpace.GetLower() * 635)));
2846 : }
2847 : }
2848 :
2849 56 : void RtfAttributeOutput::FormatSurround(const SwFmtSurround& rSurround)
2850 : {
2851 56 : if (m_rExport.bOutFlyFrmAttrs && !m_rExport.bRTFFlySyntax)
2852 : {
2853 8 : SwSurround eSurround = rSurround.GetSurround();
2854 8 : bool bGold = SURROUND_IDEAL == eSurround;
2855 8 : if (bGold)
2856 2 : eSurround = SURROUND_PARALLEL;
2857 8 : RTFSurround aMC(bGold, static_cast< sal_uInt8 >(eSurround));
2858 8 : m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYMAINCNT);
2859 8 : m_aRunText->append((sal_Int32) aMC.GetValue());
2860 : }
2861 48 : else if (m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax)
2862 : {
2863 : // See DocxSdrExport::startDMLAnchorInline() for SwFmtSurround -> WR / WRK mappings.
2864 48 : sal_Int32 nWr = -1;
2865 48 : boost::optional<sal_Int32> oWrk;
2866 48 : switch (rSurround.GetValue())
2867 : {
2868 : case SURROUND_NONE:
2869 0 : nWr = 1; // top and bottom
2870 0 : break;
2871 : case SURROUND_THROUGHT:
2872 16 : nWr = 3; // none
2873 16 : break;
2874 : case SURROUND_PARALLEL:
2875 28 : nWr = 2; // around
2876 28 : oWrk = 0; // both sides
2877 28 : break;
2878 : case SURROUND_IDEAL:
2879 : default:
2880 4 : nWr = 2; // around
2881 4 : oWrk = 3; // largest
2882 4 : break;
2883 : }
2884 :
2885 48 : if (rSurround.IsContour())
2886 4 : nWr = 4; // tight
2887 :
2888 48 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWR);
2889 48 : m_rExport.OutLong(nWr);
2890 48 : if (oWrk)
2891 : {
2892 32 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWRK);
2893 32 : m_rExport.OutLong(*oWrk);
2894 48 : }
2895 : }
2896 56 : }
2897 :
2898 56 : void RtfAttributeOutput::FormatVertOrientation(const SwFmtVertOrient& rFlyVert)
2899 : {
2900 56 : if (m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax)
2901 : {
2902 48 : switch (rFlyVert.GetRelationOrient())
2903 : {
2904 : case text::RelOrientation::PAGE_FRAME:
2905 2 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelv", OString::number(1)));
2906 2 : break;
2907 : default:
2908 46 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelv", OString::number(2)));
2909 46 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYPARA).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE);
2910 46 : break;
2911 : }
2912 :
2913 48 : switch (rFlyVert.GetVertOrient())
2914 : {
2915 : case text::VertOrientation::TOP:
2916 : case text::VertOrientation::LINE_TOP:
2917 14 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(1)));
2918 14 : break;
2919 : case text::VertOrientation::BOTTOM:
2920 : case text::VertOrientation::LINE_BOTTOM:
2921 0 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(3)));
2922 0 : break;
2923 : case text::VertOrientation::CENTER:
2924 : case text::VertOrientation::LINE_CENTER:
2925 0 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(2)));
2926 0 : break;
2927 : default:
2928 34 : break;
2929 : }
2930 :
2931 48 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPTOP);
2932 48 : m_rExport.OutLong(rFlyVert.GetPos());
2933 48 : if (m_pFlyFrameSize)
2934 : {
2935 32 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM);
2936 32 : m_rExport.OutLong(rFlyVert.GetPos() + m_pFlyFrameSize->Height());
2937 : }
2938 : }
2939 56 : }
2940 :
2941 56 : void RtfAttributeOutput::FormatHorizOrientation(const SwFmtHoriOrient& rFlyHori)
2942 : {
2943 56 : if (m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax)
2944 : {
2945 48 : switch (rFlyHori.GetRelationOrient())
2946 : {
2947 : case text::RelOrientation::PAGE_FRAME:
2948 4 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelh", OString::number(1)));
2949 4 : break;
2950 : default:
2951 44 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelh", OString::number(2)));
2952 44 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE);
2953 44 : break;
2954 : }
2955 :
2956 48 : switch (rFlyHori.GetHoriOrient())
2957 : {
2958 : case text::HoriOrientation::LEFT:
2959 0 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(1)));
2960 0 : break;
2961 : case text::HoriOrientation::CENTER:
2962 22 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(2)));
2963 22 : break;
2964 : case text::HoriOrientation::RIGHT:
2965 0 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(3)));
2966 0 : break;
2967 : default:
2968 26 : break;
2969 : }
2970 :
2971 48 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPLEFT);
2972 48 : m_rExport.OutLong(rFlyHori.GetPos());
2973 48 : if (m_pFlyFrameSize)
2974 : {
2975 32 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPRIGHT);
2976 32 : m_rExport.OutLong(rFlyHori.GetPos() + m_pFlyFrameSize->Width());
2977 : }
2978 : }
2979 56 : }
2980 :
2981 56 : void RtfAttributeOutput::FormatAnchor(const SwFmtAnchor& rAnchor)
2982 : {
2983 56 : if (!m_rExport.bRTFFlySyntax)
2984 : {
2985 8 : sal_uInt16 nId = static_cast< sal_uInt16 >(rAnchor.GetAnchorId());
2986 8 : m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYANCHOR);
2987 8 : m_aRunText->append((sal_Int32)nId);
2988 8 : switch (nId)
2989 : {
2990 : case FLY_AT_PAGE:
2991 2 : m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYPAGE);
2992 2 : m_aRunText->append((sal_Int32)rAnchor.GetPageNum());
2993 2 : break;
2994 : case FLY_AT_PARA:
2995 : case FLY_AS_CHAR:
2996 2 : m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYCNTNT);
2997 2 : break;
2998 : }
2999 : }
3000 56 : }
3001 :
3002 4 : void RtfAttributeOutput::FormatBackground(const SvxBrushItem& rBrush)
3003 : {
3004 4 : if (m_rExport.bRTFFlySyntax)
3005 : {
3006 4 : const Color& rColor = rBrush.GetColor();
3007 : // We in fact need RGB to BGR, but the transformation is symmetric.
3008 4 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
3009 : }
3010 0 : else if (!rBrush.GetColor().GetTransparency())
3011 : {
3012 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CBPAT);
3013 0 : m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
3014 : }
3015 4 : }
3016 :
3017 1442 : void RtfAttributeOutput::FormatFillStyle(const XFillStyleItem& rFillStyle)
3018 : {
3019 1442 : m_oFillStyle.reset(rFillStyle.GetValue());
3020 1442 : }
3021 :
3022 4 : void RtfAttributeOutput::FormatFillGradient(const XFillGradientItem& rFillGradient)
3023 : {
3024 4 : if (*m_oFillStyle == drawing::FillStyle_GRADIENT)
3025 : {
3026 4 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillType", OString::number(7))); // Shade using the fillAngle
3027 :
3028 4 : const XGradient& rGradient = rFillGradient.GetGradientValue();
3029 4 : const Color& rStartColor = rGradient.GetStartColor();
3030 4 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillBackColor", OString::number(msfilter::util::BGRToRGB(rStartColor.GetColor()))));
3031 :
3032 4 : const Color& rEndColor = rGradient.GetEndColor();
3033 4 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillColor", OString::number(msfilter::util::BGRToRGB(rEndColor.GetColor()))));
3034 :
3035 4 : switch (rGradient.GetGradientStyle())
3036 : {
3037 : case XGRAD_LINEAR:
3038 0 : break;
3039 : case XGRAD_AXIAL:
3040 4 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillFocus", OString::number(50)));
3041 4 : break;
3042 : case XGRAD_RADIAL:
3043 0 : break;
3044 : case XGRAD_ELLIPTICAL:
3045 0 : break;
3046 : case XGRAD_SQUARE:
3047 0 : break;
3048 : case XGRAD_RECT:
3049 0 : break;
3050 : }
3051 : }
3052 4 : }
3053 :
3054 90 : void RtfAttributeOutput::FormatBox(const SvxBoxItem& rBox)
3055 : {
3056 : static const sal_uInt16 aBorders[] =
3057 : {
3058 : BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
3059 : };
3060 : static const sal_Char* aBorderNames[] =
3061 : {
3062 : OOO_STRING_SVTOOLS_RTF_BRDRT, OOO_STRING_SVTOOLS_RTF_BRDRL, OOO_STRING_SVTOOLS_RTF_BRDRB, OOO_STRING_SVTOOLS_RTF_BRDRR
3063 : };
3064 :
3065 90 : sal_uInt16 nDist = rBox.GetDistance();
3066 :
3067 90 : if (m_rExport.bRTFFlySyntax)
3068 : {
3069 : // Borders: spacing to contents, convert from twips to EMUs.
3070 50 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxTextLeft", OString::number(rBox.GetDistance(BOX_LINE_LEFT) * 635)));
3071 50 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyTextTop", OString::number(rBox.GetDistance(BOX_LINE_TOP) * 635)));
3072 50 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxTextRight", OString::number(rBox.GetDistance(BOX_LINE_RIGHT) * 635)));
3073 50 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyTextBottom", OString::number(rBox.GetDistance(BOX_LINE_BOTTOM) * 635)));
3074 :
3075 50 : const SvxBorderLine* pLeft = rBox.GetLine(BOX_LINE_LEFT);
3076 50 : const SvxBorderLine* pRight = rBox.GetLine(BOX_LINE_RIGHT);
3077 50 : const SvxBorderLine* pTop = rBox.GetLine(BOX_LINE_TOP);
3078 50 : const SvxBorderLine* pBottom = rBox.GetLine(BOX_LINE_BOTTOM);
3079 50 : if (pLeft && pRight && pTop && pBottom && *pLeft == *pRight && *pLeft == *pTop && *pLeft == *pBottom)
3080 : {
3081 34 : const Color& rColor = pTop->GetColor();
3082 : // We in fact need RGB to BGR, but the transformation is symmetric.
3083 34 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("lineColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
3084 :
3085 34 : if (pTop->GetBorderLineStyle() != table::BorderLineStyle::NONE)
3086 : {
3087 30 : double const fConverted(editeng::ConvertBorderWidthToWord(pTop->GetBorderLineStyle(), pTop->GetWidth()));
3088 30 : sal_Int32 nWidth = sal_Int32(fConverted * 635); // Twips -> EMUs
3089 30 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("lineWidth", OString::number(nWidth)));
3090 : }
3091 : else
3092 : // No border: no line.
3093 4 : m_aFlyProperties.push_back(std::make_pair<OString, OString>("fLine", "0"));
3094 : }
3095 :
3096 140 : return;
3097 : }
3098 :
3099 122 : if (rBox.GetTop() && rBox.GetBottom() &&
3100 60 : rBox.GetLeft() && rBox.GetRight() &&
3101 40 : *rBox.GetTop() == *rBox.GetBottom() &&
3102 40 : *rBox.GetTop() == *rBox.GetLeft() &&
3103 40 : *rBox.GetTop() == *rBox.GetRight() &&
3104 28 : nDist == rBox.GetDistance(BOX_LINE_TOP) &&
3105 10 : nDist == rBox.GetDistance(BOX_LINE_LEFT) &&
3106 44 : nDist == rBox.GetDistance(BOX_LINE_BOTTOM) &&
3107 2 : nDist == rBox.GetDistance(BOX_LINE_RIGHT))
3108 2 : m_aSectionBreaks.append(OutBorderLine(m_rExport, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist));
3109 : else
3110 : {
3111 38 : SvxShadowLocation eShadowLocation = SVX_SHADOW_NONE;
3112 38 : if (const SfxPoolItem* pItem = GetExport().HasItem(RES_SHADOW))
3113 22 : eShadowLocation = static_cast<const SvxShadowItem*>(pItem)->GetLocation();
3114 :
3115 38 : const sal_uInt16* pBrd = aBorders;
3116 38 : const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
3117 190 : for (int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
3118 : {
3119 152 : if (const SvxBorderLine* pLn = rBox.GetLine(*pBrd))
3120 : {
3121 : m_aSectionBreaks.append(OutBorderLine(m_rExport, pLn, *pBrdNms,
3122 76 : rBox.GetDistance(*pBrd), eShadowLocation));
3123 : }
3124 : }
3125 : }
3126 :
3127 40 : if (!m_bBufferSectionBreaks)
3128 32 : m_aStyles.append(m_aSectionBreaks.makeStringAndClear());
3129 : }
3130 :
3131 14 : void RtfAttributeOutput::FormatColumns_Impl(sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize)
3132 : {
3133 14 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLS);
3134 14 : m_rExport.OutLong(nCols);
3135 :
3136 14 : if (bEven)
3137 : {
3138 14 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSX);
3139 14 : m_rExport.OutLong(rCol.GetGutterWidth(true));
3140 : }
3141 : else
3142 : {
3143 0 : const SwColumns& rColumns = rCol.GetColumns();
3144 0 : for (sal_uInt16 n = 0; n < nCols;)
3145 : {
3146 0 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLNO);
3147 0 : m_rExport.OutLong(n+1);
3148 :
3149 0 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLW);
3150 0 : m_rExport.OutLong(rCol.CalcPrtColWidth(n, nPageSize));
3151 :
3152 0 : if (++n != nCols)
3153 : {
3154 0 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSR);
3155 0 : m_rExport.OutLong(rColumns[ n-1 ].GetRight() +
3156 0 : rColumns[ n ].GetLeft());
3157 : }
3158 : }
3159 : }
3160 14 : }
3161 :
3162 232 : void RtfAttributeOutput::FormatKeep(const SvxFmtKeepItem& rItem)
3163 : {
3164 232 : if (rItem.GetValue())
3165 224 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEPN);
3166 232 : }
3167 :
3168 328 : void RtfAttributeOutput::FormatTextGrid(const SwTextGridItem& /*rGrid*/)
3169 : {
3170 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3171 328 : }
3172 :
3173 364 : void RtfAttributeOutput::FormatLineNumbering(const SwFmtLineNumber& rNumbering)
3174 : {
3175 364 : if (!rNumbering.IsCount())
3176 358 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOLINE);
3177 364 : }
3178 :
3179 454 : void RtfAttributeOutput::FormatFrameDirection(const SvxFrameDirectionItem& rDirection)
3180 : {
3181 454 : if (!m_rExport.bOutPageDescs)
3182 : {
3183 124 : if (rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP)
3184 0 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RTLPAR);
3185 : else
3186 124 : m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LTRPAR);
3187 : }
3188 454 : }
3189 :
3190 0 : void RtfAttributeOutput::ParaGrabBag(const SfxGrabBagItem& /*rItem*/)
3191 : {
3192 0 : }
3193 :
3194 36 : void RtfAttributeOutput::CharGrabBag(const SfxGrabBagItem& /*rItem*/)
3195 : {
3196 36 : }
3197 :
3198 92 : void RtfAttributeOutput::ParaOutlineLevel(const SfxUInt16Item& /*rItem*/)
3199 : {
3200 92 : }
3201 :
3202 0 : void RtfAttributeOutput::WriteExpand(const SwField* pFld)
3203 : {
3204 0 : OUString sCmd; // for optional Parameters
3205 0 : switch (pFld->GetTyp()->Which())
3206 : {
3207 : //#i119803# Export user field and DB field for RTF filter
3208 : case RES_DBFLD:
3209 0 : sCmd = FieldString(ww::eMERGEFIELD);
3210 : // no break !!
3211 : case RES_USERFLD:
3212 0 : sCmd += pFld->GetTyp()->GetName();
3213 0 : m_rExport.OutputField(pFld, ww::eNONE, sCmd);
3214 0 : break;
3215 : default:
3216 0 : m_rExport.OutputField(pFld, ww::eUNKNOWN, sCmd);
3217 0 : break;
3218 0 : }
3219 0 : }
3220 :
3221 0 : void RtfAttributeOutput::RefField(const SwField& /*rFld*/, const OUString& /*rRef*/)
3222 : {
3223 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3224 0 : }
3225 :
3226 0 : void RtfAttributeOutput::HiddenField(const SwField& /*rFld*/)
3227 : {
3228 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3229 0 : }
3230 :
3231 0 : void RtfAttributeOutput::SetField(const SwField& /*rFld*/, ww::eField /*eType*/, const OUString& /*rCmd*/)
3232 : {
3233 : SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3234 0 : }
3235 :
3236 14 : void RtfAttributeOutput::PostitField(const SwField* pFld)
3237 : {
3238 14 : const SwPostItField& rPFld = *(SwPostItField*)pFld;
3239 :
3240 14 : OString aName = OUStringToOString(rPFld.GetName(), RTL_TEXTENCODING_UTF8);
3241 14 : std::map<OString, sal_uInt16>::iterator it = m_rOpenedAnnotationMarksIds.find(aName);
3242 14 : if (it != m_rOpenedAnnotationMarksIds.end())
3243 : {
3244 : // In case this field is inside annotation marks, we want to write the
3245 : // annotation itself after the annotation mark is closed, not here.
3246 6 : m_aPostitFields[it->second] = &rPFld;
3247 20 : return;
3248 : }
3249 :
3250 8 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " ");
3251 8 : m_aRunText->append(OUStringToOString(OUString(rPFld.GetInitials()), m_rExport.eCurrentEncoding));
3252 8 : m_aRunText->append("}");
3253 8 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNAUTHOR " ");
3254 8 : m_aRunText->append(OUStringToOString(OUString(rPFld.GetPar1()), m_rExport.eCurrentEncoding));
3255 8 : m_aRunText->append("}");
3256 8 : m_aRunText->append(OOO_STRING_SVTOOLS_RTF_CHATN);
3257 :
3258 8 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ANNOTATION);
3259 :
3260 8 : if (m_nCurrentAnnotationMarkId != -1)
3261 : {
3262 6 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNREF " ");
3263 6 : m_aRunText->append(m_nCurrentAnnotationMarkId);
3264 6 : m_aRunText->append('}');
3265 : }
3266 8 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNDATE " ");
3267 8 : m_aRunText->append((sal_Int32)sw::ms::DateTime2DTTM(rPFld.GetDateTime()));
3268 8 : m_aRunText->append('}');
3269 8 : m_aRunText->append(OUStringToOString(OUString(rPFld.GetTxt()), m_rExport.eCurrentEncoding));
3270 8 : m_aRunText->append('}');
3271 : }
3272 :
3273 0 : bool RtfAttributeOutput::DropdownField(const SwField* /*pFld*/)
3274 : {
3275 : // this is handled in OutputFlyFrame_Impl()
3276 0 : return true;
3277 : }
3278 :
3279 2 : bool RtfAttributeOutput::PlaceholderField(const SwField* pField)
3280 : {
3281 2 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " MACROBUTTON None ");
3282 2 : RunText(pField->GetPar1());
3283 2 : m_aRunText->append("}}");
3284 2 : return false; // do not expand
3285 : }
3286 :
3287 138 : RtfAttributeOutput::RtfAttributeOutput(RtfExport& rExport)
3288 : : m_rExport(rExport),
3289 : m_nStyleId(0),
3290 : m_nListId(0),
3291 : m_bStrikeDouble(false),
3292 : m_nNextAnnotationMarkId(0),
3293 : m_nCurrentAnnotationMarkId(-1),
3294 : m_pTableWrt(NULL),
3295 : m_bTableCellOpen(false),
3296 : m_nTableDepth(0),
3297 : m_bTblAfterCell(false),
3298 : m_nColBreakNeeded(false),
3299 : m_bBufferSectionBreaks(false),
3300 : m_bBufferSectionHeaders(false),
3301 : m_bLastTable(true),
3302 : m_bWroteCellInfo(false),
3303 : m_bTableRowEnded(false),
3304 : m_aCells(),
3305 : m_bSingleEmptyRun(false),
3306 : m_bInRun(false),
3307 : m_pFlyFrameSize(0),
3308 138 : m_pPrevPageDesc(0)
3309 : {
3310 138 : }
3311 :
3312 276 : RtfAttributeOutput::~RtfAttributeOutput()
3313 : {
3314 276 : }
3315 :
3316 4178 : MSWordExportBase& RtfAttributeOutput::GetExport()
3317 : {
3318 4178 : return m_rExport;
3319 : }
3320 :
3321 : // These are used by wwFont::WriteRtf()
3322 :
3323 : /// Start the font.
3324 1014 : void RtfAttributeOutput::StartFont(const OUString& rFamilyName) const
3325 : {
3326 : // write the font name hex-encoded, but without Unicode - Word at least
3327 : // cannot read *both* Unicode and fallback as written by OutString
3328 1014 : m_rExport.Strm().WriteCharPtr(
3329 2028 : msfilter::rtfutil::OutString(rFamilyName, m_rExport.eCurrentEncoding, false).getStr());
3330 1014 : }
3331 :
3332 : /// End the font.
3333 1014 : void RtfAttributeOutput::EndFont() const
3334 : {
3335 1014 : m_rExport.Strm().WriteCharPtr(";}");
3336 1014 : m_rExport.eCurrentEncoding = m_rExport.eDefaultEncoding;
3337 1014 : }
3338 :
3339 : /// Alternate name for the font.
3340 270 : void RtfAttributeOutput::FontAlternateName(const OUString& rName) const
3341 : {
3342 270 : m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_IGNORE).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FALT).WriteChar(' ');
3343 : // write the font name hex-encoded, but without Unicode - Word at least
3344 : // cannot read *both* Unicode and fallback as written by OutString
3345 270 : m_rExport.Strm().WriteCharPtr(
3346 540 : msfilter::rtfutil::OutString(rName, m_rExport.eCurrentEncoding, false).getStr()).WriteChar('}');
3347 270 : }
3348 :
3349 : /// Font charset.
3350 1014 : void RtfAttributeOutput::FontCharset(sal_uInt8 nCharSet) const
3351 : {
3352 1014 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FCHARSET);
3353 1014 : m_rExport.OutULong(nCharSet);
3354 1014 : m_rExport.Strm().WriteChar(' ');
3355 1014 : m_rExport.eCurrentEncoding =rtl_getTextEncodingFromWindowsCharset(nCharSet);
3356 1014 : }
3357 :
3358 : /// Font family.
3359 1014 : void RtfAttributeOutput::FontFamilyType(FontFamily eFamily, const wwFont& rFont) const
3360 : {
3361 1014 : m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_F);
3362 :
3363 1014 : const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL;
3364 1014 : switch (eFamily)
3365 : {
3366 : case FAMILY_ROMAN:
3367 474 : pStr = OOO_STRING_SVTOOLS_RTF_FROMAN;
3368 474 : break;
3369 : case FAMILY_SWISS:
3370 312 : pStr = OOO_STRING_SVTOOLS_RTF_FSWISS;
3371 312 : break;
3372 : case FAMILY_MODERN:
3373 6 : pStr = OOO_STRING_SVTOOLS_RTF_FMODERN;
3374 6 : break;
3375 : case FAMILY_SCRIPT:
3376 0 : pStr = OOO_STRING_SVTOOLS_RTF_FSCRIPT;
3377 0 : break;
3378 : case FAMILY_DECORATIVE:
3379 0 : pStr = OOO_STRING_SVTOOLS_RTF_FDECOR;
3380 0 : break;
3381 : default:
3382 222 : break;
3383 : }
3384 1014 : m_rExport.OutULong(m_rExport.maFontHelper.GetId(rFont)).WriteCharPtr(pStr);
3385 1014 : }
3386 :
3387 : /// Font pitch.
3388 1014 : void RtfAttributeOutput::FontPitchType(FontPitch ePitch) const
3389 : {
3390 1014 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FPRQ);
3391 :
3392 1014 : sal_uInt16 nVal = 0;
3393 1014 : switch (ePitch)
3394 : {
3395 : case PITCH_FIXED:
3396 4 : nVal = 1;
3397 4 : break;
3398 : case PITCH_VARIABLE:
3399 962 : nVal = 2;
3400 962 : break;
3401 : default:
3402 48 : break;
3403 : }
3404 1014 : m_rExport.OutULong(nVal);
3405 1014 : }
3406 :
3407 0 : static bool IsEMF(const sal_uInt8* pGraphicAry, unsigned long nSize)
3408 : {
3409 0 : if (pGraphicAry && (nSize > 0x2c))
3410 : {
3411 : // check the magic number
3412 0 : if ((pGraphicAry[0x28] == 0x20) && (pGraphicAry[0x29] == 0x45) && (pGraphicAry[0x2a] == 0x4d) && (pGraphicAry[0x2b] == 0x46))
3413 : {
3414 : //emf detected
3415 0 : return true;
3416 : }
3417 : }
3418 0 : return false;
3419 : }
3420 :
3421 70 : static bool StripMetafileHeader(const sal_uInt8*& rpGraphicAry, unsigned long& rSize)
3422 : {
3423 70 : if (rpGraphicAry && (rSize > 0x22))
3424 : {
3425 70 : if ((rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) && (rpGraphicAry[2] == 0xc6) && (rpGraphicAry[3] == 0x9a))
3426 : {
3427 : // we have to get rid of the metafileheader
3428 70 : rpGraphicAry += 22;
3429 70 : rSize -= 22;
3430 70 : return true;
3431 : }
3432 : }
3433 0 : return false;
3434 : }
3435 :
3436 150 : OString RtfAttributeOutput::WriteHex(const sal_uInt8* pData, sal_uInt32 nSize, SvStream* pStream, sal_uInt32 nLimit)
3437 : {
3438 150 : OStringBuffer aRet;
3439 :
3440 150 : sal_uInt32 nBreak = 0;
3441 10414254 : for (sal_uInt32 i = 0; i < nSize; i++)
3442 : {
3443 10414104 : OString sNo = OString::number(pData[i], 16);
3444 10414104 : if (sNo.getLength() < 2)
3445 : {
3446 2737279 : if (pStream)
3447 2277669 : pStream->WriteChar('0');
3448 : else
3449 459610 : aRet.append('0');
3450 : }
3451 10414104 : if (pStream)
3452 9789462 : pStream->WriteCharPtr(sNo.getStr());
3453 : else
3454 624642 : aRet.append(sNo);
3455 10414104 : if (++nBreak == nLimit)
3456 : {
3457 162648 : if (pStream)
3458 152950 : pStream->WriteCharPtr(SAL_NEWLINE_STRING);
3459 : else
3460 9698 : aRet.append(SAL_NEWLINE_STRING);
3461 162648 : nBreak = 0;
3462 : }
3463 10414104 : }
3464 :
3465 150 : return aRet.makeStringAndClear();
3466 : }
3467 :
3468 264 : static void lcl_AppendSP(OStringBuffer& rBuffer,
3469 : const char cName[],
3470 : const OUString& rValue,
3471 : const RtfExport& rExport)
3472 : {
3473 264 : rBuffer.append("{" OOO_STRING_SVTOOLS_RTF_SP "{"); // "{\sp{"
3474 264 : rBuffer.append(OOO_STRING_SVTOOLS_RTF_SN " "); //" \sn "
3475 264 : rBuffer.append(cName); //"PropName"
3476 264 : rBuffer.append("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
3477 : // "}{ \sv "
3478 264 : rBuffer.append(msfilter::rtfutil::OutString(rValue, rExport.eCurrentEncoding));
3479 264 : rBuffer.append("}}");
3480 264 : }
3481 :
3482 140 : static OString ExportPICT(const SwFlyFrmFmt* pFlyFrmFmt, const Size& rOrig, const Size& rRendered, const Size& rMapped,
3483 : const SwCropGrf& rCr, const char* pBLIPType, const sal_uInt8* pGraphicAry,
3484 : unsigned long nSize, const RtfExport& rExport, SvStream* pStream = 0, bool bWritePicProp = true)
3485 : {
3486 140 : OStringBuffer aRet;
3487 140 : if (pBLIPType && nSize && pGraphicAry)
3488 : {
3489 140 : bool bIsWMF = std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
3490 :
3491 140 : aRet.append("{" OOO_STRING_SVTOOLS_RTF_PICT);
3492 :
3493 140 : if (pFlyFrmFmt && bWritePicProp)
3494 : {
3495 132 : OUString sDescription = pFlyFrmFmt->GetObjDescription();
3496 : //write picture properties - wzDescription at first
3497 : //looks like: "{\*\picprop{\sp{\sn PropertyName}{\sv PropertyValue}}}"
3498 132 : aRet.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_PICPROP); //"{\*\picprop
3499 132 : lcl_AppendSP(aRet, "wzDescription", sDescription, rExport);
3500 264 : OUString sName = pFlyFrmFmt->GetObjTitle();
3501 132 : lcl_AppendSP(aRet, "wzName", sName, rExport);
3502 264 : aRet.append("}"); //"}"
3503 : }
3504 :
3505 140 : long nXCroppedSize = rOrig.Width()-(rCr.GetLeft() + rCr.GetRight());
3506 140 : long nYCroppedSize = rOrig.Height()-(rCr.GetTop() + rCr.GetBottom());
3507 : /* Graphic with a zero height or width, typically copied from webpages, caused crashes. */
3508 140 : if (!nXCroppedSize)
3509 2 : nXCroppedSize = 100;
3510 140 : if (!nYCroppedSize)
3511 2 : nYCroppedSize = 100;
3512 :
3513 : //Given the original size and taking cropping into account
3514 : //first, how much has the original been scaled to get the
3515 : //final rendered size
3516 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEX);
3517 140 : aRet.append((sal_Int32)((100 * rRendered.Width()) / nXCroppedSize));
3518 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEY);
3519 140 : aRet.append((sal_Int32)((100 * rRendered.Height()) / nYCroppedSize));
3520 :
3521 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPL);
3522 140 : aRet.append((sal_Int32)rCr.GetLeft());
3523 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPR);
3524 140 : aRet.append((sal_Int32)rCr.GetRight());
3525 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPT);
3526 140 : aRet.append((sal_Int32)rCr.GetTop());
3527 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPB);
3528 140 : aRet.append((sal_Int32)rCr.GetBottom());
3529 :
3530 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICW);
3531 140 : aRet.append((sal_Int32)rMapped.Width());
3532 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICH);
3533 140 : aRet.append((sal_Int32)rMapped.Height());
3534 :
3535 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
3536 140 : aRet.append((sal_Int32)rOrig.Width());
3537 140 : aRet.append(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
3538 140 : aRet.append((sal_Int32)rOrig.Height());
3539 :
3540 140 : aRet.append(pBLIPType);
3541 140 : if (bIsWMF)
3542 : {
3543 70 : aRet.append((sal_Int32)8);
3544 70 : StripMetafileHeader(pGraphicAry, nSize);
3545 : }
3546 140 : aRet.append(SAL_NEWLINE_STRING);
3547 140 : if (pStream)
3548 20 : pStream->WriteCharPtr(aRet.makeStringAndClear().getStr());
3549 140 : if (pStream)
3550 20 : RtfAttributeOutput::WriteHex(pGraphicAry, nSize, pStream);
3551 : else
3552 120 : aRet.append(RtfAttributeOutput::WriteHex(pGraphicAry, nSize));
3553 140 : aRet.append('}');
3554 140 : if (pStream)
3555 20 : pStream->WriteCharPtr(aRet.makeStringAndClear().getStr());
3556 : }
3557 140 : return aRet.makeStringAndClear();
3558 : }
3559 :
3560 60 : void RtfAttributeOutput::FlyFrameOLEReplacement(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
3561 : {
3562 60 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
3563 60 : Size aSize(sw::util::GetSwappedInSize(rOLENode));
3564 60 : Size aRendered(aSize);
3565 60 : aRendered.Width() = rSize.Width();
3566 60 : aRendered.Height() = rSize.Height();
3567 60 : const Graphic* pGraphic = rOLENode.GetGraphic();
3568 60 : Size aMapped(pGraphic->GetPrefSize());
3569 60 : const SwCropGrf& rCr = (const SwCropGrf&)rOLENode.GetAttr(RES_GRFATR_CROPGRF);
3570 60 : const sal_Char* pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3571 60 : const sal_uInt8* pGraphicAry = 0;
3572 60 : SvMemoryStream aStream;
3573 60 : if (GraphicConverter::Export(aStream, *pGraphic, CVT_PNG) != ERRCODE_NONE)
3574 : OSL_FAIL("failed to export the graphic");
3575 60 : aStream.Seek(STREAM_SEEK_TO_END);
3576 60 : sal_uInt32 nSize = aStream.Tell();
3577 60 : pGraphicAry = (sal_uInt8*)aStream.GetData();
3578 60 : m_aRunText->append(ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport));
3579 60 : m_aRunText->append("}"); // shppict
3580 60 : m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT);
3581 60 : pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3582 120 : SvMemoryStream aWmfStream;
3583 60 : if (GraphicConverter::Export(aWmfStream, *pGraphic, CVT_WMF) != ERRCODE_NONE)
3584 : OSL_FAIL("failed to export the graphic");
3585 60 : aWmfStream.Seek(STREAM_SEEK_TO_END);
3586 60 : nSize = aWmfStream.Tell();
3587 60 : pGraphicAry = (sal_uInt8*)aWmfStream.GetData();
3588 60 : m_aRunText->append(ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport));
3589 120 : m_aRunText->append("}"); // nonshppict
3590 60 : }
3591 :
3592 60 : bool RtfAttributeOutput::FlyFrameOLEMath(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
3593 : {
3594 60 : uno::Reference <embed::XEmbeddedObject> xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
3595 60 : sal_Int64 nAspect = rOLENode.GetAspect();
3596 120 : svt::EmbeddedObjectRef aObjRef(xObj, nAspect);
3597 120 : SvGlobalName aObjName(aObjRef->getClassID());
3598 :
3599 60 : if (!SotExchange::IsMath(aObjName))
3600 0 : return false;
3601 :
3602 60 : m_aRunText->append("{" LO_STRING_SVTOOLS_RTF_MMATH " ");
3603 120 : uno::Reference<util::XCloseable> xClosable(xObj->getComponent(), uno::UNO_QUERY);
3604 60 : if (!xClosable.is())
3605 0 : return false;
3606 : // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
3607 : // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
3608 : // to RTLD_GLOBAL, so most probably a gcc bug.
3609 60 : oox::FormulaExportBase* pBase = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xClosable.get()));
3610 : assert(pBase != NULL);
3611 120 : OStringBuffer aBuf;
3612 60 : if (pBase)
3613 60 : pBase->writeFormulaRtf(aBuf, m_rExport.eCurrentEncoding);
3614 60 : m_aRunText->append(aBuf.makeStringAndClear());
3615 : // Replacement graphic.
3616 60 : m_aRunText->append("{" LO_STRING_SVTOOLS_RTF_MMATHPICT " ");
3617 60 : FlyFrameOLEReplacement(pFlyFrmFmt, rOLENode, rSize);
3618 60 : m_aRunText->append("}"); // mmathPict
3619 60 : m_aRunText->append("}"); // mmath
3620 :
3621 120 : return true;
3622 : }
3623 :
3624 60 : void RtfAttributeOutput::FlyFrameOLE(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
3625 : {
3626 60 : if (FlyFrameOLEMath(pFlyFrmFmt, rOLENode, rSize))
3627 120 : return;
3628 :
3629 0 : FlyFrameOLEReplacement(pFlyFrmFmt, rOLENode, rSize);
3630 : }
3631 :
3632 14 : void RtfAttributeOutput::FlyFrameGraphic(const SwFlyFrmFmt* pFlyFrmFmt, const SwGrfNode* pGrfNode)
3633 : {
3634 14 : SvMemoryStream aStream;
3635 14 : const sal_uInt8* pGraphicAry = 0;
3636 14 : sal_uInt32 nSize = 0;
3637 :
3638 14 : const Graphic& rGraphic(pGrfNode->GetGrf());
3639 :
3640 : // If there is no graphic there is not much point in parsing it
3641 14 : if (rGraphic.GetType()==GRAPHIC_NONE)
3642 14 : return;
3643 :
3644 14 : bool bSwapped = rGraphic.IsSwapOut();
3645 14 : if (bSwapped)
3646 : {
3647 : // always swapin via the Node
3648 0 : const_cast<SwGrfNode*>(pGrfNode)->SwapIn();
3649 : }
3650 :
3651 28 : GfxLink aGraphicLink;
3652 14 : const sal_Char* pBLIPType = 0;
3653 14 : if (rGraphic.IsLink())
3654 : {
3655 12 : aGraphicLink = rGraphic.GetLink();
3656 12 : nSize = aGraphicLink.GetDataSize();
3657 12 : pGraphicAry = aGraphicLink.GetData();
3658 12 : switch (aGraphicLink.GetType())
3659 : {
3660 : // #i15508# trying to add BMP type for better exports, need to check if this works
3661 : // checked, does not work. Also need to reset pGraphicAry to NULL to force conversion
3662 : // to PNG, else the BMP array will be used.
3663 : // It may work using direct DIB data, but that needs to be checked eventually
3664 : //
3665 : // #i15508# before GFX_LINK_TYPE_NATIVE_BMP was added the graphic data
3666 : // (to be hold in pGraphicAry) was not available; thus for now to stay
3667 : // compatible, keep it that way by assigning NULL value to pGraphicAry
3668 : case GFX_LINK_TYPE_NATIVE_BMP:
3669 : // pBLIPType = OOO_STRING_SVTOOLS_RTF_WBITMAP;
3670 0 : pGraphicAry = 0;
3671 0 : break;
3672 :
3673 : case GFX_LINK_TYPE_NATIVE_JPG:
3674 0 : pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
3675 0 : break;
3676 : case GFX_LINK_TYPE_NATIVE_PNG:
3677 10 : pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3678 10 : break;
3679 : case GFX_LINK_TYPE_NATIVE_WMF:
3680 : pBLIPType =
3681 0 : IsEMF(pGraphicAry, nSize) ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3682 0 : break;
3683 : default:
3684 2 : break;
3685 : }
3686 : }
3687 :
3688 14 : GraphicType eGraphicType = rGraphic.GetType();
3689 14 : if (!pGraphicAry)
3690 : {
3691 2 : if (ERRCODE_NONE == GraphicConverter::Export(aStream, rGraphic,
3692 2 : (eGraphicType == GRAPHIC_BITMAP) ? CVT_PNG : CVT_WMF))
3693 : {
3694 : pBLIPType = (eGraphicType == GRAPHIC_BITMAP) ?
3695 2 : OOO_STRING_SVTOOLS_RTF_PNGBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3696 2 : aStream.Seek(STREAM_SEEK_TO_END);
3697 2 : nSize = aStream.Tell();
3698 2 : pGraphicAry = (sal_uInt8*)aStream.GetData();
3699 : }
3700 : }
3701 :
3702 14 : Size aMapped(eGraphicType == GRAPHIC_BITMAP ? rGraphic.GetSizePixel() : rGraphic.GetPrefSize());
3703 :
3704 14 : const SwCropGrf& rCr = (const SwCropGrf&)pGrfNode->GetAttr(RES_GRFATR_CROPGRF);
3705 :
3706 : //Get original size in twips
3707 14 : Size aSize(sw::util::GetSwappedInSize(*pGrfNode));
3708 14 : Size aRendered(aSize);
3709 :
3710 14 : const SwFmtFrmSize& rS = pFlyFrmFmt->GetFrmSize();
3711 14 : aRendered.Width() = rS.GetWidth();
3712 14 : aRendered.Height() = rS.GetHeight();
3713 :
3714 14 : sw::Frame* pFrame = 0;
3715 18 : for (sw::FrameIter it = m_rExport.maFrames.begin(); it != m_rExport.maFrames.end(); ++it)
3716 : {
3717 12 : if (pFlyFrmFmt == &it->GetFrmFmt())
3718 : {
3719 8 : pFrame = &(*it);
3720 8 : break;
3721 : }
3722 : }
3723 :
3724 : /*
3725 : If the graphic is not of type WMF then we will have to store two
3726 : graphics, one in the native format wrapped in shppict, and the other in
3727 : the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
3728 : a wmf already then we don't need any such wrapping
3729 : */
3730 14 : bool bIsWMF = pBLIPType && std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
3731 14 : if (!pFrame || pFrame->IsInline())
3732 : {
3733 6 : if (!bIsWMF)
3734 6 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
3735 : }
3736 : else
3737 : {
3738 8 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHP "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPINST);
3739 8 : m_pFlyFrameSize = &aRendered;
3740 8 : m_rExport.mpParentFrame = pFrame;
3741 8 : m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = true;
3742 8 : m_rExport.OutputFormat(pFrame->GetFrmFmt(), false, false, true);
3743 8 : m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = false;
3744 8 : m_rExport.mpParentFrame = NULL;
3745 8 : m_pFlyFrameSize = 0;
3746 :
3747 8 : std::vector< std::pair<OString, OString> > aFlyProperties;
3748 8 : aFlyProperties.push_back(std::make_pair<OString, OString>("shapeType", OString::number(ESCHER_ShpInst_PictureFrame)));
3749 8 : aFlyProperties.push_back(std::make_pair<OString, OString>("wzDescription", msfilter::rtfutil::OutString(pFlyFrmFmt->GetObjDescription(), m_rExport.eCurrentEncoding)));
3750 8 : aFlyProperties.push_back(std::make_pair<OString, OString>("wzName", msfilter::rtfutil::OutString(pFlyFrmFmt->GetObjTitle(), m_rExport.eCurrentEncoding)));
3751 :
3752 : // If we have a wrap polygon, then handle that here.
3753 8 : if (pFlyFrmFmt->GetSurround().IsContour())
3754 : {
3755 2 : if (const SwNoTxtNode* pNd = sw::util::GetNoTxtNodeFromSwFrmFmt(*pFlyFrmFmt))
3756 : {
3757 2 : const tools::PolyPolygon* pPolyPoly = pNd->HasContour();
3758 2 : if (pPolyPoly && pPolyPoly->Count())
3759 : {
3760 2 : Polygon aPoly = sw::util::CorrectWordWrapPolygonForExport(*pPolyPoly, pNd);
3761 4 : OStringBuffer aVerticies;
3762 24 : for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i)
3763 22 : aVerticies.append(";(").append(aPoly[i].X()).append(",").append(aPoly[i].Y()).append(")");
3764 4 : aFlyProperties.push_back(std::make_pair<OString, OString>("pWrapPolygonVertices", "8;" + OString::number(aPoly.GetSize()) + aVerticies.makeStringAndClear()));
3765 : }
3766 : }
3767 : }
3768 :
3769 : // Below text, behind document, opaque: they all refer to the same thing.
3770 8 : if (!pFlyFrmFmt->GetOpaque().GetValue())
3771 2 : aFlyProperties.push_back(std::make_pair<OString, OString>("fBehindDocument", "1"));
3772 :
3773 36 : for (size_t i = 0; i < aFlyProperties.size(); ++i)
3774 : {
3775 28 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{");
3776 28 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SN " ");
3777 28 : m_rExport.Strm().WriteCharPtr(aFlyProperties[i].first.getStr());
3778 28 : m_rExport.Strm().WriteCharPtr("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
3779 28 : m_rExport.Strm().WriteCharPtr(aFlyProperties[i].second.getStr());
3780 28 : m_rExport.Strm().WriteCharPtr("}}");
3781 : }
3782 8 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{" OOO_STRING_SVTOOLS_RTF_SN " pib" "}{" OOO_STRING_SVTOOLS_RTF_SV " ");
3783 : }
3784 :
3785 14 : bool bWritePicProp = !pFrame || pFrame->IsInline();
3786 14 : if (pBLIPType)
3787 12 : ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm(), bWritePicProp);
3788 : else
3789 : {
3790 2 : aStream.Seek(0);
3791 2 : GraphicConverter::Export(aStream, rGraphic, CVT_WMF);
3792 2 : pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3793 2 : aStream.Seek(STREAM_SEEK_TO_END);
3794 2 : nSize = aStream.Tell();
3795 2 : pGraphicAry = (sal_uInt8*)aStream.GetData();
3796 :
3797 2 : ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm(), bWritePicProp);
3798 : }
3799 :
3800 14 : if (!pFrame || pFrame->IsInline())
3801 : {
3802 6 : if (!bIsWMF)
3803 : {
3804 6 : m_rExport.Strm().WriteCharPtr("}" "{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT);
3805 :
3806 6 : aStream.Seek(0);
3807 6 : GraphicConverter::Export(aStream, rGraphic, CVT_WMF);
3808 6 : pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3809 6 : aStream.Seek(STREAM_SEEK_TO_END);
3810 6 : nSize = aStream.Tell();
3811 6 : pGraphicAry = (sal_uInt8*)aStream.GetData();
3812 :
3813 6 : ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm());
3814 :
3815 6 : m_rExport.Strm().WriteChar('}');
3816 : }
3817 : }
3818 : else
3819 8 : m_rExport.Strm().WriteCharPtr("}}}}"); // Close SV, SP, SHPINST and SHP.
3820 :
3821 14 : if (bSwapped)
3822 0 : const_cast<Graphic&>(rGraphic).SwapOut();
3823 :
3824 28 : m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
3825 : }
3826 :
3827 2 : void RtfAttributeOutput::BulletDefinition(int /*nId*/, const Graphic& rGraphic, Size aSize)
3828 : {
3829 2 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
3830 2 : m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT OOO_STRING_SVTOOLS_RTF_PNGBLIP);
3831 :
3832 2 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
3833 2 : m_rExport.OutULong(aSize.Width());
3834 2 : m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
3835 2 : m_rExport.OutULong(aSize.Height());
3836 :
3837 2 : m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
3838 2 : const sal_uInt8* pGraphicAry = 0;
3839 2 : SvMemoryStream aStream;
3840 2 : if (GraphicConverter::Export(aStream, rGraphic, CVT_PNG) != ERRCODE_NONE)
3841 : SAL_WARN("sw.rtf", "failed to export the numbering picture bullet");
3842 2 : aStream.Seek(STREAM_SEEK_TO_END);
3843 2 : sal_uInt32 nSize = aStream.Tell();
3844 2 : pGraphicAry = (sal_uInt8*)aStream.GetData();
3845 2 : RtfAttributeOutput::WriteHex(pGraphicAry, nSize, &m_rExport.Strm());
3846 2 : m_rExport.Strm().WriteCharPtr("}}"); // pict, shppict
3847 104 : }
3848 :
3849 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|