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