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