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