bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww8 / rtfattributeoutput.cxx
blob589f8a9944cb0e90c2914a0dc444c06a964231c0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include <cstring>
24 #include "rtfattributeoutput.hxx"
25 #include "rtfsdrexport.hxx"
26 #include "writerwordglue.hxx"
27 #include "ww8par.hxx"
28 #include "fmtcntnt.hxx"
29 #include "fchrfmt.hxx"
31 #include <rtl/ustring.hxx>
32 #include <rtl/tencinfo.h>
33 #include <svtools/rtfkeywd.hxx>
35 #include <editeng/fontitem.hxx>
36 #include <editeng/tstpitem.hxx>
37 #include <editeng/adjustitem.hxx>
38 #include <editeng/spltitem.hxx>
39 #include <editeng/widwitem.hxx>
40 #include <editeng/keepitem.hxx>
41 #include <editeng/brushitem.hxx>
42 #include <editeng/postitem.hxx>
43 #include <editeng/wghtitem.hxx>
44 #include <editeng/kernitem.hxx>
45 #include <editeng/crossedoutitem.hxx>
46 #include <editeng/cmapitem.hxx>
47 #include <editeng/wrlmitem.hxx>
48 #include <editeng/udlnitem.hxx>
49 #include <editeng/langitem.hxx>
50 #include <editeng/escapementitem.hxx>
51 #include <editeng/fhgtitem.hxx>
52 #include <editeng/colritem.hxx>
53 #include <editeng/hyphenzoneitem.hxx>
54 #include <editeng/ulspitem.hxx>
55 #include <editeng/boxitem.hxx>
56 #include <editeng/contouritem.hxx>
57 #include <editeng/shdditem.hxx>
58 #include <editeng/autokernitem.hxx>
59 #include <editeng/emphasismarkitem.hxx>
60 #include <editeng/twolinesitem.hxx>
61 #include <editeng/charscaleitem.hxx>
62 #include <editeng/charrotateitem.hxx>
63 #include <editeng/charreliefitem.hxx>
64 #include <editeng/paravertalignitem.hxx>
65 #include <editeng/frmdiritem.hxx>
66 #include <editeng/blinkitem.hxx>
67 #include <editeng/charhiddenitem.hxx>
68 #include <editeng/shaditem.hxx>
69 #include <svx/svdmodel.hxx>
70 #include <svx/fmglob.hxx>
71 #include <svx/svdouno.hxx>
72 #include <filter/msfilter/msoleexp.hxx>
73 #include <filter/msfilter/rtfutil.hxx>
74 #include <svtools/miscopt.hxx>
75 #include <sfx2/sfxbasemodel.hxx>
76 #include <svx/xflgrit.hxx>
78 #include <docufld.hxx>
79 #include <fmtclds.hxx>
80 #include <fmtinfmt.hxx>
81 #include <fmtftn.hxx>
82 #include <fmtrowsplt.hxx>
83 #include <fmtline.hxx>
84 #include <fmtanchr.hxx>
85 #include <frmatr.hxx>
86 #include <htmltbl.hxx>
87 #include <ndgrf.hxx>
88 #include <ndtxt.hxx>
89 #include <pagedesc.hxx>
90 #include <swmodule.hxx>
91 #include <swtable.hxx>
92 #include <txtftn.hxx>
93 #include <txtinet.hxx>
94 #include <grfatr.hxx>
95 #include <ndole.hxx>
96 #include <lineinfo.hxx>
97 #include <rtf.hxx>
99 #include <vcl/cvtgrf.hxx>
100 #include <oox/mathml/export.hxx>
102 #include <com/sun/star/i18n/ScriptType.hpp>
104 using ::editeng::SvxBorderLine;
105 using namespace nsSwDocInfoSubType;
106 using namespace nsFieldFlags;
107 using namespace sw::util;
108 using namespace ::com::sun::star;
110 static OString OutTBLBorderLine(RtfExport &rExport, const SvxBorderLine* pLine, const sal_Char* pStr)
112 OStringBuffer aRet;
113 if ( !pLine->isEmpty() )
115 aRet.append(pStr);
116 // single line
117 switch (pLine->GetBorderLineStyle())
119 case table::BorderLineStyle::SOLID:
121 if( DEF_LINE_WIDTH_0 == pLine->GetWidth() )
122 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRHAIR);
123 else
124 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRS);
126 break;
127 case table::BorderLineStyle::DOTTED:
128 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDOT);
129 break;
130 case table::BorderLineStyle::DASHED:
131 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDASH);
132 break;
133 case table::BorderLineStyle::DOUBLE:
134 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDB);
135 break;
136 case table::BorderLineStyle::THINTHICK_SMALLGAP:
137 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHSG);
138 break;
139 case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
140 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHMG);
141 break;
142 case table::BorderLineStyle::THINTHICK_LARGEGAP:
143 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHLG);
144 break;
145 case table::BorderLineStyle::THICKTHIN_SMALLGAP:
146 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNSG);
147 break;
148 case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
149 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNMG);
150 break;
151 case table::BorderLineStyle::THICKTHIN_LARGEGAP:
152 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNLG);
153 break;
154 case table::BorderLineStyle::EMBOSSED:
155 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDREMBOSS);
156 break;
157 case table::BorderLineStyle::ENGRAVED:
158 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRENGRAVE);
159 break;
160 case table::BorderLineStyle::OUTSET:
161 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDROUTSET);
162 break;
163 case table::BorderLineStyle::INSET:
164 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRINSET);
165 break;
166 case table::BorderLineStyle::NONE:
167 default:
168 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRNONE);
169 break;
172 double const fConverted( ::editeng::ConvertBorderWidthToWord(
173 pLine->GetBorderLineStyle(), pLine->GetWidth()) );
174 if ( 255 >= pLine->GetWidth() ) // That value comes from RTF specs
176 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW).append(
177 static_cast<sal_Int32>(fConverted));
179 else
180 { // use \brdrth to double the value range...
181 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTH OOO_STRING_SVTOOLS_RTF_BRDRW);
182 aRet.append(static_cast<sal_Int32>(fConverted) / 2);
185 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRCF);
186 aRet.append((sal_Int32)rExport.GetColor(pLine->GetColor()));
188 return aRet.makeStringAndClear();
191 static OString OutBorderLine(RtfExport &rExport, const SvxBorderLine* pLine,
192 const sal_Char* pStr, sal_uInt16 nDist)
194 OStringBuffer aRet;
195 aRet.append(OutTBLBorderLine(rExport, pLine, pStr));
196 aRet.append(OOO_STRING_SVTOOLS_RTF_BRSP);
197 aRet.append((sal_Int32)nDist);
198 return aRet.makeStringAndClear();
201 void RtfAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
203 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
205 You would have thought that
206 m_rExport.Strm() << (bIsRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficent here ,
207 but looks like word needs to see the other directional token to be
208 satisified that all is kosher, otherwise it seems in ver 2003 to go and
209 semi-randomlyly stick strike through about the place. Perhaps
210 strikethrough is some ms developers "something is wrong signal" debugging
211 code that we're triggering ?
213 if (bIsRTL) {
214 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
215 m_aStylesEnd.append(' ');
216 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
217 } else {
218 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
219 m_aStylesEnd.append(' ');
220 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
223 switch (nScript) {
224 case i18n::ScriptType::LATIN:
225 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
226 break;
227 case i18n::ScriptType::ASIAN:
228 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_DBCH);
229 break;
230 case i18n::ScriptType::COMPLEX:
231 /* noop */
232 break;
233 default:
234 /* should not happen? */
235 break;
239 void RtfAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
241 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
243 // Output table/table row/table cell starts if needed
244 if ( pTextNodeInfo.get() )
246 sal_uInt32 nRow = pTextNodeInfo->getRow();
247 sal_uInt32 nCell = pTextNodeInfo->getCell();
249 // New cell/row?
250 if ( m_nTableDepth > 0 && !m_bTableCellOpen )
252 ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
253 OSL_ENSURE( pDeepInner, "TableNodeInfoInner not found");
254 // Make sure we always start a row between ending one and starting a cell.
255 // In case of subtables, we may not get the first cell.
256 if (pDeepInner && (pDeepInner->getCell() == 0 || m_bTableRowEnded))
258 m_bTableRowEnded = false;
259 StartTableRow( pDeepInner );
262 StartTableCell( pDeepInner );
265 // Again, if depth was incremented, start a new table even if we skipped the first cell.
266 if ((nRow == 0 && nCell == 0) || (m_nTableDepth == 0 && pTextNodeInfo->getDepth()))
268 // Do we have to start the table?
269 // [If we are at the rigth depth already, it means that we
270 // continue the table cell]
271 sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
273 if ( nCurrentDepth > m_nTableDepth )
275 // Start all the tables that begin here
276 for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
278 ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
280 m_bLastTable = (nDepth == pTextNodeInfo->getDepth());
281 StartTable( pInner );
282 StartTableRow( pInner );
283 StartTableCell( pInner );
286 m_nTableDepth = nCurrentDepth;
291 OSL_ENSURE(m_aRun.getLength() == 0, "m_aRun is not empty");
294 void RtfAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
296 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
298 FinishTableRowCell( pTextNodeInfoInner );
300 RtfStringBuffer aParagraph;
302 aParagraph.appendAndClear(m_aRun);
303 aParagraph->append(m_aAfterRuns.makeStringAndClear());
304 if (m_bTblAfterCell)
305 m_bTblAfterCell = false;
306 else
308 aParagraph->append(m_rExport.sNewLine);
309 aParagraph->append(OOO_STRING_SVTOOLS_RTF_PAR);
310 aParagraph->append(' ');
312 if (m_nColBreakNeeded)
314 aParagraph->append(OOO_STRING_SVTOOLS_RTF_COLUMN);
315 m_nColBreakNeeded = false;
318 if (!m_bBufferSectionHeaders)
319 aParagraph.makeStringAndClear(this);
320 else
321 m_aSectionHeaders.append(aParagraph.makeStringAndClear());
324 void RtfAttributeOutput::EmptyParagraph()
326 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
328 m_rExport.Strm() << m_rExport.sNewLine << OOO_STRING_SVTOOLS_RTF_PAR << ' ';
331 void RtfAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode )
333 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
334 OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
336 // output page/section breaks
337 SwNodeIndex aNextIndex( rNode, 1 );
338 m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear().getStr();
339 m_bBufferSectionBreaks = true;
341 // output section headers / footers
342 if (!m_bBufferSectionHeaders)
343 m_rExport.Strm() << m_aSectionHeaders.makeStringAndClear().getStr();
345 if ( aNextIndex.GetNode().IsTxtNode() )
347 const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
348 m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode );
349 // Save the current page description for now, so later we will be able to access the previous one.
350 m_pPrevPageDesc = pTxtNode->FindPageDesc(sal_False);
352 else if ( aNextIndex.GetNode().IsTableNode() )
354 const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
355 const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
356 m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
358 m_bBufferSectionBreaks = false;
360 OStringBuffer aPar;
361 if (!m_rExport.bRTFFlySyntax)
363 aPar.append(OOO_STRING_SVTOOLS_RTF_PARD);
364 aPar.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
365 aPar.append(' ');
367 if (!m_bBufferSectionHeaders)
368 m_rExport.Strm() << aPar.makeStringAndClear().getStr();
369 else
370 m_aSectionHeaders.append(aPar.makeStringAndClear());
373 void RtfAttributeOutput::EndParagraphProperties()
375 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
376 m_aStyles.append(m_aStylesEnd.makeStringAndClear());
377 m_rExport.Strm() << m_aStyles.makeStringAndClear().getStr();
380 void RtfAttributeOutput::StartRun( const SwRedlineData* pRedlineData, bool bSingleEmptyRun )
382 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", bSingleEmptyRun: " << bSingleEmptyRun);
384 m_bInRun = true;
385 m_bSingleEmptyRun = bSingleEmptyRun;
386 if (!m_bSingleEmptyRun)
387 m_aRun->append('{');
389 // if there is some redlining in the document, output it
390 Redline( pRedlineData );
392 OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
395 void RtfAttributeOutput::EndRun()
397 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
398 m_aRun->append(m_rExport.sNewLine);
399 m_aRun.appendAndClear(m_aRunText);
400 if (!m_bSingleEmptyRun && m_bInRun)
401 m_aRun->append('}');
402 m_bInRun = false;
405 void RtfAttributeOutput::StartRunProperties()
407 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
408 OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
411 void RtfAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ )
413 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
414 m_aStyles.append(m_aStylesEnd.makeStringAndClear());
415 m_aRun->append(m_aStyles.makeStringAndClear());
418 void RtfAttributeOutput::RunText( const String& rText, rtl_TextEncoding /*eCharSet*/ )
420 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rText: " << rText);
421 RawText( rText, 0, m_rExport.eCurrentEncoding );
424 OStringBuffer& RtfAttributeOutput::RunText()
426 return m_aRunText.getLastBuffer();
429 OStringBuffer& RtfAttributeOutput::Styles()
431 return m_aStyles;
434 void RtfAttributeOutput::RawText( const String& rText, bool /*bForceUnicode*/, rtl_TextEncoding eCharSet )
436 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
437 m_aRunText->append(msfilter::rtfutil::OutString(rText, eCharSet));
440 void RtfAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, xub_StrLen /*nPos*/, const SwFmtRuby& /*rRuby*/ )
442 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
445 void RtfAttributeOutput::EndRuby()
447 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
450 bool RtfAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
452 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
454 m_aStyles.append('{');
455 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FIELD);
456 m_aStyles.append('{');
457 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
458 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FLDINST);
459 m_aStyles.append(" HYPERLINK ");
461 String sURL( rUrl );
462 if( sURL.Len() )
464 m_aStyles.append("\"");
465 m_aStyles.append(msfilter::rtfutil::OutString( sURL, m_rExport.eCurrentEncoding));
466 m_aStyles.append("\" ");
469 if( rTarget.Len() )
471 m_aStyles.append("\\\\t \"");
472 m_aStyles.append(msfilter::rtfutil::OutString( rTarget, m_rExport.eCurrentEncoding));
473 m_aStyles.append("\" ");
476 m_aStyles.append("}");
477 m_bHadFieldResult = false;
478 return true;
481 bool RtfAttributeOutput::EndURL()
483 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
485 // close the fldrslt group
486 if (m_bHadFieldResult)
487 m_aRunText->append('}');
488 // close the field group
489 m_aRunText->append('}');
490 return true;
493 void RtfAttributeOutput::FieldVanish( const String& /*rTxt*/, ww::eField /*eType*/ )
495 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
498 void RtfAttributeOutput::Redline( const SwRedlineData* pRedline )
500 if (!pRedline)
501 return;
503 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
505 if (pRedline->GetType() == nsRedlineType_t::REDLINE_INSERT)
507 m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED);
508 m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH);
509 m_aRun->append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
510 m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM);
512 else if(pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
514 m_aRun->append(OOO_STRING_SVTOOLS_RTF_DELETED);
515 m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL);
516 m_aRun->append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
517 m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL);
519 m_aRun->append((sal_Int32)sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()));
520 m_aRun->append(' ');
523 void RtfAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t /*pTextNodeInfoInner*/ )
525 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
528 void RtfAttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
530 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
532 OString *pStyle = m_rExport.GetStyle(nStyle);
533 OStringBuffer aStyle;
534 aStyle.append(OOO_STRING_SVTOOLS_RTF_S);
535 aStyle.append((sal_Int32)nStyle);
536 if (pStyle)
537 aStyle.append(pStyle->getStr());
538 if (!m_bBufferSectionHeaders)
539 m_rExport.Strm() << aStyle.makeStringAndClear().getStr();
540 else
541 m_aSectionHeaders.append(aStyle.makeStringAndClear());
544 void RtfAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
546 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
548 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_INTBL);
549 if ( m_nTableDepth > 1 )
551 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ITAP);
552 m_aStyles.append((sal_Int32)m_nTableDepth);
554 m_bWroteCellInfo = true;
557 void RtfAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
559 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
561 /* noop */
564 void RtfAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
566 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
568 if ( !m_pTableWrt )
569 InitTableHelper( pTableTextNodeInfoInner );
571 const SwTable *pTbl = pTableTextNodeInfoInner->getTable();
572 SwFrmFmt *pFmt = pTbl->GetFrmFmt( );
574 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TROWD);
575 TableOrientation( pTableTextNodeInfoInner );
576 TableBidi( pTableTextNodeInfoInner );
577 TableHeight( pTableTextNodeInfoInner );
578 TableCanSplit( pTableTextNodeInfoInner );
580 // Cell margins
581 const SvxBoxItem& rBox = pFmt->GetBox( );
582 static const sal_uInt16 aBorders[] =
584 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
587 static const char* aRowPadNames[] =
589 OOO_STRING_SVTOOLS_RTF_TRPADDT, OOO_STRING_SVTOOLS_RTF_TRPADDL, OOO_STRING_SVTOOLS_RTF_TRPADDB, OOO_STRING_SVTOOLS_RTF_TRPADDR
592 static const char* aRowPadUnits[] =
594 OOO_STRING_SVTOOLS_RTF_TRPADDFT, OOO_STRING_SVTOOLS_RTF_TRPADDFL, OOO_STRING_SVTOOLS_RTF_TRPADDFB, OOO_STRING_SVTOOLS_RTF_TRPADDFR
597 for (int i = 0; i < 4; ++i)
599 m_aRowDefs.append(aRowPadUnits[i]);
600 m_aRowDefs.append((sal_Int32)3);
601 m_aRowDefs.append(aRowPadNames[i]);
602 m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
605 // The cell-dependent properties
606 const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
607 SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
608 SwTwips nSz = 0;
609 Point aPt;
610 SwRect aRect( pFmt->FindLayoutRect( false, &aPt ));
611 SwTwips nPageSize = aRect.Width();
613 // Handle the page size when not rendered
614 if( 0 == nPageSize )
616 const SwNode* pNode = pTableTextNodeInfoInner->getNode();
617 const SwFrmFmt* pFrmFmt = GetExport().mpParentFrame ? &GetExport().mpParentFrame->GetFrmFmt() :
618 GetExport().pDoc->GetPageDesc(0).GetPageFmtOfNode(*pNode, false);
620 const SvxLRSpaceItem& rLR = pFrmFmt->GetLRSpace();
621 nPageSize = pFrmFmt->GetFrmSize().GetWidth() -
622 rLR.GetLeft() - rLR.GetRight();
624 SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
625 // Not using m_nTableDepth, which is not yet incremented here.
626 sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
627 m_aCells[nCurrentDepth] = pRow->GetCells().size();
628 for( sal_uInt16 i = 0; i < m_aCells[nCurrentDepth]; i++ )
630 const SwWriteTableCell *pCell = &pRow->GetCells( )[ i ];
631 const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
633 pTableTextNodeInfoInner->setCell( i );
634 TableCellProperties(pTableTextNodeInfoInner);
636 // Right boundary: this can't be in TableCellProperties as the old
637 // value of nSz is needed.
638 nSz += pCellFmt->GetFrmSize().GetWidth();
639 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CELLX);
640 SwTwips nCalc = nSz;
641 nCalc *= nPageSize;
642 nCalc /= nTblSz;
643 m_aRowDefs.append( (sal_Int32)(pFmt->GetLRSpace().GetLeft() + nCalc) );
647 void RtfAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
649 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
652 * The function name is a bit misleading: given that we write borders
653 * before each row, we just have borders, not default ones. Additionally,
654 * this function actually writes borders for a specific cell only and is
655 * called for each cell.
658 const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
659 SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
660 const SvxBoxItem& rDefault = pFmt->GetBox( );
661 const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
662 SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
663 const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
664 const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
665 const SfxPoolItem* pItem;
666 if (pCellFmt->GetAttrSet().HasItem(RES_BOX, &pItem))
668 const SvxBoxItem& rBox = (SvxBoxItem&)*pItem;
669 static const sal_uInt16 aBorders[] =
671 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
673 static const char* aBorderNames[] =
675 OOO_STRING_SVTOOLS_RTF_CLBRDRT, OOO_STRING_SVTOOLS_RTF_CLBRDRL, OOO_STRING_SVTOOLS_RTF_CLBRDRB, OOO_STRING_SVTOOLS_RTF_CLBRDRR
677 //Yes left and top are swapped with eachother for cell padding! Because
678 //that's what the thunderingly annoying rtf export/import word xp does.
679 static const char* aCellPadNames[] =
681 OOO_STRING_SVTOOLS_RTF_CLPADL, OOO_STRING_SVTOOLS_RTF_CLPADT, OOO_STRING_SVTOOLS_RTF_CLPADB, OOO_STRING_SVTOOLS_RTF_CLPADR
683 static const char* aCellPadUnits[] =
685 OOO_STRING_SVTOOLS_RTF_CLPADFL, OOO_STRING_SVTOOLS_RTF_CLPADFT, OOO_STRING_SVTOOLS_RTF_CLPADFB, OOO_STRING_SVTOOLS_RTF_CLPADFR
687 for (int i = 0; i < 4; ++i)
689 if (const SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
690 m_aRowDefs.append(OutTBLBorderLine(m_rExport, pLn, aBorderNames[i]));
691 if (rDefault.GetDistance(aBorders[i]) !=
692 rBox.GetDistance(aBorders[i]))
694 m_aRowDefs.append(aCellPadUnits[i]);
695 m_aRowDefs.append((sal_Int32)3);
696 m_aRowDefs.append(aCellPadNames[i]);
697 m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
703 void RtfAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
705 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
707 const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
708 SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
709 const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
710 const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
711 const SfxPoolItem* pItem;
712 if (pCellFmt->GetAttrSet().HasItem(RES_BACKGROUND, &pItem))
714 const SvxBrushItem& rBack = (SvxBrushItem&)*pItem;
715 if( !rBack.GetColor().GetTransparency() )
717 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLCBPAT);
718 m_aRowDefs.append((sal_Int32)m_rExport.GetColor(rBack.GetColor()));
723 void RtfAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
725 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
727 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
728 const SwTableLine * pTabLine = pTabBox->GetUpper();
729 const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
730 const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
732 if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
734 sal_Int32 nHeight = 0;
736 switch ( rLSz.GetHeightSizeType() )
738 case ATT_FIX_SIZE: nHeight = -rLSz.GetHeight(); break;
739 case ATT_MIN_SIZE: nHeight = rLSz.GetHeight(); break;
740 default: break;
743 if ( nHeight )
745 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRRH);
746 m_aRowDefs.append(nHeight);
751 void RtfAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
753 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
755 const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
756 const SwTableLine * pTabLine = pTabBox->GetUpper();
757 const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
758 const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
760 // The rtf default is to allow a row to break
761 if (rSplittable.GetValue() == 0)
762 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRKEEP);
765 void RtfAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
767 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
769 const SwTable * pTable = pTableTextNodeInfoInner->getTable();
770 const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
772 if ( m_rExport.TrueFrameDirection( *pFrmFmt ) != FRMDIR_HORI_RIGHT_TOP )
773 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_LTRROW);
774 else
775 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_RTLROW);
778 void RtfAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
780 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
782 const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
783 SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
784 const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
785 const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
786 const SfxPoolItem* pItem;
788 // vertical merges
789 if (pCell->GetRowSpan() > 1)
790 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMGF);
791 else if (pCell->GetRowSpan() == 0)
792 m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMRG);
794 // vertical alignment
795 if (pCellFmt->GetAttrSet().HasItem(RES_VERT_ORIENT, &pItem))
796 switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
798 case text::VertOrientation::CENTER: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALC); break;
799 case text::VertOrientation::BOTTOM: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALB); break;
800 default: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALT); break;
804 void RtfAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
806 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
808 /* noop */
811 void RtfAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
813 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
815 // This is called when the nested table ends in a cell, and there's no
816 // paragraph benhind that; so we must check for the ends of cell, rows,
817 // and tables
818 // ['true' to write an empty paragraph, MS Word insists on that]
819 FinishTableRowCell( pNodeInfoInner, true );
822 void RtfAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
824 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
826 const SwTable *pTable = pTableTextNodeInfoInner->getTable();
827 SwFrmFmt *pFmt = pTable->GetFrmFmt( );
829 OStringBuffer aTblAdjust( OOO_STRING_SVTOOLS_RTF_TRQL );
830 switch (pFmt->GetHoriOrient().GetHoriOrient())
832 case text::HoriOrientation::CENTER:
833 aTblAdjust.setLength(0);
834 aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQC);
835 break;
836 case text::HoriOrientation::RIGHT:
837 aTblAdjust.setLength(0);
838 aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQR);
839 break;
840 case text::HoriOrientation::NONE:
841 case text::HoriOrientation::LEFT_AND_WIDTH:
842 aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRLEFT);
843 aTblAdjust.append((sal_Int32)pFmt->GetLRSpace().GetLeft());
844 break;
845 default:
846 break;
849 m_aRowDefs.append(aTblAdjust.makeStringAndClear());
852 void RtfAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
854 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
857 void RtfAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
859 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
861 /* noop, see EndTableRow() */
865 * Our private table methods.
868 void RtfAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
870 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
872 sal_uInt32 nPageSize = 0;
873 bool bRelBoxSize = false;
875 // Create the SwWriteTable instance to use col spans
876 GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
878 const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
879 const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
880 SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
882 const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
883 if( pLayout && pLayout->IsExportable() )
884 m_pTableWrt = new SwWriteTable( pLayout );
885 else
886 m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (sal_uInt16)nPageSize,
887 (sal_uInt16)nTblSz, false);
890 void RtfAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
892 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
894 // To trigger calling InitTableHelper()
895 delete m_pTableWrt, m_pTableWrt = NULL;
898 void RtfAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
900 sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
901 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << nCurrentDepth << ")");
903 TableDefinition(pTableTextNodeInfoInner);
905 SvtMiscOptions aMiscOptions;
906 if (aMiscOptions.IsExperimentalMode())
908 m_aTables.push_back(m_aRowDefs.toString());
909 // Emit row properties at the start of the row as well for non-nested
910 // tables, to support old readers.
911 if ( nCurrentDepth <= 1 )
912 m_rExport.Strm() << m_aRowDefs.makeStringAndClear().getStr();
913 m_aRowDefs.setLength(0);
914 return;
916 else
918 if (!m_bLastTable)
919 m_aTables.push_back(m_aRowDefs.makeStringAndClear());
921 // We'll write the table definition for nested tables later
922 if ( nCurrentDepth > 1 )
923 return;
924 // Empty the previous row closing buffer before starting the new one,
925 // necessary for subtables.
926 m_rExport.Strm() << m_aAfterRuns.makeStringAndClear().getStr();
927 m_rExport.Strm() << m_aRowDefs.makeStringAndClear().getStr();
931 void RtfAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
933 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
935 m_bTableCellOpen = true;
938 void RtfAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
940 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
942 TableDefaultBorders(pTableTextNodeInfoInner);
943 TableBackgrounds(pTableTextNodeInfoInner);
944 TableVerticalCell(pTableTextNodeInfoInner);
947 void RtfAttributeOutput::EndTableCell( )
949 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
951 if (!m_bWroteCellInfo)
953 m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_INTBL);
954 m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ITAP);
955 m_aAfterRuns.append((sal_Int32)m_nTableDepth);
957 if ( m_nTableDepth > 1 )
958 m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTCELL);
959 else
960 m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
962 m_bTableCellOpen = false;
963 m_bTblAfterCell = true;
964 m_bWroteCellInfo = false;
965 if (m_aCells[m_nTableDepth] > 0)
966 m_aCells[m_nTableDepth]--;
969 void RtfAttributeOutput::EndTableRow( )
971 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
973 // Trying to end the row without writing the required number of cells? Fill with empty ones.
974 for( sal_uInt16 i = 0; i < m_aCells[m_nTableDepth]; i++ )
975 m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
977 if ( m_nTableDepth > 1 )
979 m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS);
980 if (m_aRowDefs.getLength() > 0)
981 m_aAfterRuns.append(m_aRowDefs.makeStringAndClear());
982 else if (!m_aTables.empty())
984 m_aAfterRuns.append(m_aTables.back());
985 m_aTables.pop_back();
987 m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTROW "}" "{" OOO_STRING_SVTOOLS_RTF_NONESTTABLES OOO_STRING_SVTOOLS_RTF_PAR "}");
989 else
991 if (!m_aTables.empty())
993 m_aAfterRuns.append(m_aTables.back());
994 m_aTables.pop_back();
996 m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD);
998 m_bTableRowEnded = true;
1001 void RtfAttributeOutput::EndTable()
1003 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1005 if ( m_nTableDepth > 0 ) {
1006 m_nTableDepth--;
1007 delete m_pTableWrt, m_pTableWrt = NULL;
1010 // We closed the table; if it is a nested table, the cell that contains it
1011 // still continues
1012 m_bTableCellOpen = true;
1014 // Cleans the table helper
1015 delete m_pTableWrt, m_pTableWrt = NULL;
1018 void RtfAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool /*bForceEmptyParagraph*/ )
1020 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1022 if ( pInner.get() )
1024 // Where are we in the table
1025 sal_uInt32 nRow = pInner->getRow( );
1027 const SwTable *pTable = pInner->getTable( );
1028 const SwTableLines& rLines = pTable->GetTabLines( );
1029 sal_uInt16 nLinesCount = rLines.size( );
1031 if ( pInner->isEndOfCell() )
1032 EndTableCell();
1034 // This is a line end
1035 if ( pInner->isEndOfLine() )
1036 EndTableRow();
1038 // This is the end of the table
1039 if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
1040 EndTable();
1044 void RtfAttributeOutput::StartStyles()
1046 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1047 m_rExport.Strm() << m_rExport.sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_COLORTBL;
1048 m_rExport.OutColorTable();
1049 OSL_ENSURE(m_aStylesheet.getLength() == 0, "m_aStylesheet is not empty");
1050 m_aStylesheet.append(m_rExport.sNewLine);
1051 m_aStylesheet.append('{');
1052 m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_STYLESHEET);
1055 void RtfAttributeOutput::EndStyles( sal_uInt16 /*nNumberOfStyles*/ )
1057 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1058 m_rExport.Strm() << '}';
1059 m_rExport.Strm() << m_aStylesheet.makeStringAndClear().getStr();
1060 m_rExport.Strm() << '}';
1063 void RtfAttributeOutput::DefaultStyle( sal_uInt16 /*nStyle*/ )
1065 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1067 /* noop, the default style is always 0 in RTF */
1070 void RtfAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
1071 sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId,
1072 bool /* bAutoUpdate */ )
1074 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rName = '" << OUString(rName) << "'");
1076 m_aStylesheet.append('{');
1077 if (bPapFmt)
1078 m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
1079 else
1080 m_aStylesheet.append( OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_CS);
1081 m_aStylesheet.append( (sal_Int32)nId );
1083 if ( nBase != 0x0FFF )
1085 m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SBASEDON);
1086 m_aStylesheet.append((sal_Int32)nBase);
1089 m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SNEXT);
1090 m_aStylesheet.append((sal_Int32)nNext);
1092 m_rStyleName = rName;
1093 m_nStyleId = nId;
1096 void RtfAttributeOutput::EndStyle()
1098 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1099 m_aStyles.append(m_aStylesEnd.makeStringAndClear());
1100 OString aStyles = m_aStyles.makeStringAndClear();
1101 m_rExport.InsStyle(m_nStyleId, aStyles);
1102 m_aStylesheet.append(aStyles);
1103 m_aStylesheet.append(' ');
1104 m_aStylesheet.append(msfilter::rtfutil::OutString(m_rStyleName, m_rExport.eCurrentEncoding));
1105 m_aStylesheet.append(";}");
1106 m_aStylesheet.append(m_rExport.sNewLine);
1109 void RtfAttributeOutput::StartStyleProperties( bool /*bParProp*/, sal_uInt16 /*nStyle*/ )
1111 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1112 /* noop */
1115 void RtfAttributeOutput::EndStyleProperties( bool /*bParProp*/ )
1117 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1118 /* noop */
1121 void RtfAttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
1123 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1125 if ( nLvl >= WW8ListManager::nMaxLevel )
1126 nLvl = WW8ListManager::nMaxLevel - 1;
1128 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
1129 m_aStyles.append((sal_Int32)nLvl);
1130 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL);
1131 m_aStyles.append((sal_Int32)nLvl);
1134 void RtfAttributeOutput::PageBreakBefore( bool bBreak )
1136 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1138 if (bBreak)
1140 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_PAGEBB;
1144 void RtfAttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* pSectionInfo )
1146 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1148 switch (nC)
1150 case msword::ColumnBreak:
1151 m_nColBreakNeeded = true;
1152 break;
1153 case msword::PageBreak:
1154 if ( pSectionInfo )
1155 m_rExport.SectionProperties( *pSectionInfo );
1156 break;
1160 void RtfAttributeOutput::StartSection()
1162 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1164 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECT OOO_STRING_SVTOOLS_RTF_SECTD);
1165 if (!m_bBufferSectionBreaks)
1166 m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear().getStr();
1169 void RtfAttributeOutput::EndSection()
1171 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1174 * noop, \sect must go to StartSection or Word won't notice multiple
1175 * columns...
1179 void RtfAttributeOutput::SectionFormProtection( bool bProtected )
1181 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1183 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED);
1184 m_aSectionBreaks.append((sal_Int32)!bProtected);
1187 void RtfAttributeOutput::SectionLineNumbering( sal_uLong /*nRestartNo*/, const SwLineNumberInfo& rLnNumInfo )
1189 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1191 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINEMOD;
1192 m_rExport.OutLong(rLnNumInfo.GetCountBy());
1193 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINEX;
1194 m_rExport.OutLong(rLnNumInfo.GetPosFromLeft());
1195 if (!rLnNumInfo.IsRestartEachPage())
1196 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINECONT;
1199 void RtfAttributeOutput::SectionTitlePage()
1201 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1204 * noop, handled in RtfExport::WriteHeaderFooter()
1208 void RtfAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
1210 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1212 const SvxBoxItem& rBox = pFmt->GetBox();
1213 const SvxBorderLine *pLine = rBox.GetTop();
1214 if(pLine)
1215 m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
1216 OOO_STRING_SVTOOLS_RTF_PGBRDRT,
1217 rBox.GetDistance(BOX_LINE_TOP) ));
1218 pLine = rBox.GetBottom();
1219 if(pLine)
1220 m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
1221 OOO_STRING_SVTOOLS_RTF_PGBRDRB,
1222 rBox.GetDistance(BOX_LINE_BOTTOM) ));
1223 pLine = rBox.GetLeft();
1224 if(pLine)
1225 m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
1226 OOO_STRING_SVTOOLS_RTF_PGBRDRL,
1227 rBox.GetDistance(BOX_LINE_LEFT) ));
1228 pLine = rBox.GetRight();
1229 if(pLine)
1230 m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
1231 OOO_STRING_SVTOOLS_RTF_PGBRDRR,
1232 rBox.GetDistance(BOX_LINE_RIGHT) ));
1235 void RtfAttributeOutput::SectionBiDi( bool bBiDi )
1237 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1239 m_rExport.Strm() << (bBiDi ? OOO_STRING_SVTOOLS_RTF_RTLSECT : OOO_STRING_SVTOOLS_RTF_LTRSECT);
1242 void RtfAttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, sal_uInt16 nPageRestartNumber )
1244 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1246 if (nPageRestartNumber > 0)
1248 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNSTARTS);
1249 m_aSectionBreaks.append((sal_Int32)nPageRestartNumber);
1250 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNRESTART);
1253 const char* pStr = 0;
1254 switch ( nNumType )
1256 case SVX_NUM_CHARS_UPPER_LETTER:
1257 case SVX_NUM_CHARS_UPPER_LETTER_N: pStr = OOO_STRING_SVTOOLS_RTF_PGNUCLTR; break;
1258 case SVX_NUM_CHARS_LOWER_LETTER:
1259 case SVX_NUM_CHARS_LOWER_LETTER_N: pStr = OOO_STRING_SVTOOLS_RTF_PGNLCLTR; break;
1260 case SVX_NUM_ROMAN_UPPER: pStr = OOO_STRING_SVTOOLS_RTF_PGNUCRM; break;
1261 case SVX_NUM_ROMAN_LOWER: pStr = OOO_STRING_SVTOOLS_RTF_PGNLCRM; break;
1263 case SVX_NUM_ARABIC: pStr = OOO_STRING_SVTOOLS_RTF_PGNDEC; break;
1265 if (pStr)
1266 m_aSectionBreaks.append(pStr);
1269 void RtfAttributeOutput::SectionType( sal_uInt8 nBreakCode )
1271 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", nBreakCode = " << int(nBreakCode));
1274 * break code: 0 No break, 1 New column
1275 * 2 New page, 3 Even page, 4 Odd page
1277 const char* sType = NULL;
1278 switch ( nBreakCode )
1280 case 1: sType = OOO_STRING_SVTOOLS_RTF_SBKCOL; break;
1281 case 2: sType = OOO_STRING_SVTOOLS_RTF_SBKPAGE; break;
1282 case 3: sType = OOO_STRING_SVTOOLS_RTF_SBKEVEN; break;
1283 case 4: sType = OOO_STRING_SVTOOLS_RTF_SBKODD; break;
1284 default: sType = OOO_STRING_SVTOOLS_RTF_SBKNONE; break;
1286 m_aSectionBreaks.append(sType);
1287 if (!m_bBufferSectionBreaks)
1288 m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear().getStr();
1291 void RtfAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &/*rRule*/ )
1293 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1295 m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE;
1296 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTID;
1297 m_rExport.OutULong(nId);
1298 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT << '0';
1299 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LS;
1300 m_rExport.OutULong(nId) << '}';
1303 void RtfAttributeOutput::StartAbstractNumbering( sal_uInt16 nId )
1305 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1307 m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LIST << OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID;
1308 m_rExport.OutULong( nId );
1309 m_nListId = nId;
1312 void RtfAttributeOutput::EndAbstractNumbering()
1314 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1316 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTID;
1317 m_rExport.OutULong( m_nListId ) << '}' << m_rExport.sNewLine;
1320 void RtfAttributeOutput::NumberingLevel( sal_uInt8 nLevel,
1321 sal_uInt16 nStart,
1322 sal_uInt16 nNumberingType,
1323 SvxAdjust eAdjust,
1324 const sal_uInt8 * pNumLvlPos,
1325 sal_uInt8 nFollow,
1326 const wwFont * pFont,
1327 const SfxItemSet * pOutSet,
1328 sal_Int16 nIndentAt,
1329 sal_Int16 nFirstLineIndex,
1330 sal_Int16 /*nListTabPos*/,
1331 const String &rNumberingString,
1332 const SvxBrushItem* pBrush)
1334 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1336 m_rExport.Strm() << m_rExport.sNewLine;
1337 if( nLevel > 8 ) // RTF knows only 9 levels
1338 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_SOUTLVL;
1340 m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTLEVEL;
1342 sal_uInt16 nVal = 0;
1343 switch( nNumberingType )
1345 case SVX_NUM_ROMAN_UPPER: nVal = 1; break;
1346 case SVX_NUM_ROMAN_LOWER: nVal = 2; break;
1347 case SVX_NUM_CHARS_UPPER_LETTER:
1348 case SVX_NUM_CHARS_UPPER_LETTER_N: nVal = 3; break;
1349 case SVX_NUM_CHARS_LOWER_LETTER:
1350 case SVX_NUM_CHARS_LOWER_LETTER_N: nVal = 4; break;
1352 case SVX_NUM_BITMAP:
1353 case SVX_NUM_CHAR_SPECIAL: nVal = 23; break;
1354 case SVX_NUM_NUMBER_NONE: nVal = 255; break;
1356 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELNFC;
1357 m_rExport.OutULong( nVal );
1359 switch( eAdjust )
1361 case SVX_ADJUST_CENTER: nVal = 1; break;
1362 case SVX_ADJUST_RIGHT: nVal = 2; break;
1363 default: nVal = 0; break;
1365 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELJC;
1366 m_rExport.OutULong( nVal );
1368 // bullet
1369 if (nNumberingType == SVX_NUM_BITMAP && pBrush)
1371 int nIndex = m_rExport.GetGrfIndex(*pBrush);
1372 if (nIndex != -1)
1374 m_rExport.Strm() << LO_STRING_SVTOOLS_RTF_LEVELPICTURE;
1375 m_rExport.OutULong(nIndex);
1379 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT;
1380 m_rExport.OutULong( nStart );
1382 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW;
1383 m_rExport.OutULong( nFollow );
1385 // leveltext group
1386 m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LEVELTEXT << ' ';
1388 if( SVX_NUM_CHAR_SPECIAL == nNumberingType ||
1389 SVX_NUM_BITMAP == nNumberingType )
1391 m_rExport.Strm() << "\\'01";
1392 sal_Unicode cChar = rNumberingString.GetChar(0);
1393 m_rExport.Strm() << "\\u";
1394 m_rExport.OutULong(cChar);
1395 m_rExport.Strm() << " ?";
1397 else
1399 m_rExport.Strm() << "\\'" << msfilter::rtfutil::OutHex( rNumberingString.Len(), 2 ).getStr();
1400 m_rExport.Strm() << msfilter::rtfutil::OutString( rNumberingString, m_rExport.eDefaultEncoding, /*bUnicode =*/ false ).getStr();
1403 m_rExport.Strm() << ";}";
1405 // write the levelnumbers
1406 m_rExport.Strm() << "{" << OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS;
1407 for( sal_uInt8 i = 0; i <= nLevel && pNumLvlPos[ i ]; ++i )
1409 m_rExport.Strm() << "\\'" << msfilter::rtfutil::OutHex(pNumLvlPos[ i ], 2).getStr();
1411 m_rExport.Strm() << ";}";
1413 if( pOutSet )
1415 if (pFont)
1417 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_F;
1418 m_rExport.OutULong(m_rExport.maFontHelper.GetId(*pFont));
1420 m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF );
1421 m_rExport.Strm() << m_aStyles.makeStringAndClear().getStr();
1424 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_FI;
1425 m_rExport.OutLong( nFirstLineIndex ) << OOO_STRING_SVTOOLS_RTF_LI;
1426 m_rExport.OutLong( nIndentAt );
1428 m_rExport.Strm() << '}';
1429 if( nLevel > 8 )
1430 m_rExport.Strm() << '}';
1433 void RtfAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField /*eType*/, const String& rFldCmd, sal_uInt8 /*nMode*/ )
1435 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1437 // If there are no field instructions, don't export it as a field.
1438 bool bHasInstructions = rFldCmd.Len() > 0;
1439 if (bHasInstructions)
1441 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1442 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " ");
1443 m_aRunText->append(msfilter::rtfutil::OutString(rFldCmd, m_rExport.eCurrentEncoding));
1444 m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1446 if (pFld)
1447 m_aRunText->append(msfilter::rtfutil::OutString(pFld->ExpandField(true), m_rExport.eDefaultEncoding));
1448 if (bHasInstructions)
1449 m_aRunText->append("}}");
1452 void RtfAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts, std::vector< OUString >& rEnds )
1454 for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it )
1456 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKSTART " ");
1457 m_aRun->append(msfilter::rtfutil::OutString(*it, m_rExport.eCurrentEncoding));
1458 m_aRun->append('}');
1460 rStarts.clear();
1462 for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it )
1464 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKEND " ");
1465 m_aRun->append(msfilter::rtfutil::OutString(*it, m_rExport.eCurrentEncoding));
1466 m_aRun->append('}');
1468 rEnds.clear();
1471 void RtfAttributeOutput::WriteHeaderFooter_Impl( const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr, bool bTitlepg )
1473 OStringBuffer aSectionBreaks = m_aSectionBreaks;
1474 m_aSectionBreaks.setLength(0);
1475 RtfStringBuffer aRun = m_aRun;
1476 m_aRun.clear();
1478 m_aSectionHeaders.append(bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY : OOO_STRING_SVTOOLS_RTF_FOOTERY);
1479 m_aSectionHeaders.append((sal_Int32)m_rExport.pAktPageDesc->GetMaster().GetULSpace().GetUpper());
1480 if (bTitlepg)
1481 m_aSectionHeaders.append(OOO_STRING_SVTOOLS_RTF_TITLEPG);
1482 m_aSectionHeaders.append('{');
1483 m_aSectionHeaders.append(pStr);
1484 m_bBufferSectionHeaders = true;
1485 m_rExport.WriteHeaderFooterText(rFmt, bHeader);
1486 m_bBufferSectionHeaders = false;
1487 m_aSectionHeaders.append('}');
1489 m_aSectionBreaks = aSectionBreaks;
1490 m_aRun = aRun;
1493 void lcl_TextFrameShadow(std::vector< std::pair<OString, OString> >& rFlyProperties, const SwFrmFmt& rFrmFmt)
1495 SvxShadowItem aShadowItem = rFrmFmt.GetShadow();
1496 if (aShadowItem.GetLocation() == SVX_SHADOW_NONE)
1497 return;
1499 rFlyProperties.push_back(std::make_pair<OString, OString>("fShadow", OString::number(1)));
1501 const Color& rColor = aShadowItem.GetColor();
1502 // We in fact need RGB to BGR, but the transformation is symmetric.
1503 rFlyProperties.push_back(std::make_pair<OString, OString>("shadowColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
1505 // Twips -> points -> EMUs -- hacky, the intermediate step hides rounding errors on roundtrip.
1506 OString aShadowWidth = OString::number(sal_Int32(aShadowItem.GetWidth() / 20) * 12700);
1507 OString aOffsetX;
1508 OString aOffsetY;
1509 switch (aShadowItem.GetLocation())
1511 case SVX_SHADOW_TOPLEFT: aOffsetX = "-" + aShadowWidth; aOffsetY = "-" + aShadowWidth; break;
1512 case SVX_SHADOW_TOPRIGHT: aOffsetX = aShadowWidth; aOffsetY = "-" + aShadowWidth; break;
1513 case SVX_SHADOW_BOTTOMLEFT: aOffsetX = "-" + aShadowWidth; aOffsetY = aShadowWidth; break;
1514 case SVX_SHADOW_BOTTOMRIGHT: aOffsetX = aShadowWidth; aOffsetY = aShadowWidth; break;
1515 case SVX_SHADOW_NONE:
1516 case SVX_SHADOW_END:
1517 break;
1519 if (!aOffsetX.isEmpty())
1520 rFlyProperties.push_back(std::make_pair<OString, OString>("shadowOffsetX", OString(aOffsetX)));
1521 if (!aOffsetY.isEmpty())
1522 rFlyProperties.push_back(std::make_pair<OString, OString>("shadowOffsetY", OString(aOffsetY)));
1525 void RtfAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& /*rNdTopLeft*/ )
1527 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1529 const SwNode *pNode = rFrame.GetContent();
1530 const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
1532 switch ( rFrame.GetWriterType() )
1534 case sw::Frame::eTxtBox:
1536 OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
1537 m_rExport.mpParentFrame = &rFrame;
1539 m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_SHP;
1540 m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPINST;
1542 // Shape properties.
1543 m_aFlyProperties.push_back(std::make_pair<OString, OString>("shapeType", OString::number(ESCHER_ShpInst_TextBox)));
1545 // When a frame has some low height, but automatically expanded due
1546 // to lots of contents, this size contains the real size.
1547 const Size aSize = rFrame.GetSize();
1548 m_pFlyFrameSize = &aSize;
1550 m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = true;
1551 m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
1552 m_rExport.Strm() << m_aRunText.makeStringAndClear().getStr();
1553 m_rExport.Strm() << m_aStyles.makeStringAndClear().getStr();
1554 m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = false;
1555 m_pFlyFrameSize = 0;
1557 const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
1558 lcl_TextFrameShadow(m_aFlyProperties, rFrmFmt);
1560 for (size_t i = 0; i < m_aFlyProperties.size(); ++i)
1562 m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_SP "{";
1563 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SN " ";
1564 m_rExport.Strm() << m_aFlyProperties[i].first.getStr();
1565 m_rExport.Strm() << "}{" OOO_STRING_SVTOOLS_RTF_SV " ";
1566 m_rExport.Strm() << m_aFlyProperties[i].second.getStr();
1567 m_rExport.Strm() << "}}";
1569 m_aFlyProperties.clear();
1571 m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_SHPTXT;
1575 * Save m_aRun as we should not loose the opening brace.
1576 * OTOH, just drop the contents of m_aRunText in case something
1577 * would be there, causing a problem later.
1579 OString aSave = m_aRun.makeStringAndClear();
1580 // Also back m_bInRun and m_bSingleEmptyRun up.
1581 bool bInRunOrig = m_bInRun;
1582 m_bInRun = false;
1583 bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
1584 m_bSingleEmptyRun = false;
1585 m_rExport.bRTFFlySyntax = true;
1587 const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
1588 sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
1589 sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1590 m_rExport.SaveData( nStt, nEnd );
1591 m_rExport.mpParentFrame = &rFrame;
1592 m_rExport.WriteText( );
1593 m_rExport.RestoreData();
1595 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_PARD;
1596 m_rExport.bRTFFlySyntax = false;
1597 m_aRun->append(aSave);
1598 m_aRunText.clear();
1599 m_bInRun = bInRunOrig;
1600 m_bSingleEmptyRun = bSingleEmptyRunOrig;
1603 m_rExport.mpParentFrame = NULL;
1605 m_rExport.Strm() << '}'; // shptxt
1606 m_rExport.Strm() << '}'; // shpinst
1607 m_rExport.Strm() << '}'; // shp
1609 m_rExport.Strm() << RtfExport::sNewLine;
1611 break;
1612 case sw::Frame::eGraphic:
1613 if (!rFrame.IsInline())
1615 m_rExport.mpParentFrame = &rFrame;
1616 m_rExport.bRTFFlySyntax = true;
1617 m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
1618 m_rExport.bRTFFlySyntax = false;
1619 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
1620 m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
1621 m_aRunText->append('}');
1622 m_rExport.mpParentFrame = NULL;
1625 if ( pGrfNode )
1626 m_aRunText.append(dynamic_cast<const SwFlyFrmFmt*>( &rFrame.GetFrmFmt() ), pGrfNode);
1627 break;
1628 case sw::Frame::eDrawing:
1630 const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
1631 if ( pSdrObj )
1633 bool bSwapInPage = false;
1634 if ( !pSdrObj->GetPage() )
1636 if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() )
1638 if ( SdrPage *pPage = pModel->GetPage( 0 ) )
1640 bSwapInPage = true;
1641 const_cast< SdrObject* >( pSdrObj )->SetPage( pPage );
1646 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{");
1647 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_IGNORE);
1648 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLDINST);
1649 m_aRunText->append(" SHAPE ");
1650 m_aRunText->append("}" "{" OOO_STRING_SVTOOLS_RTF_FLDRSLT);
1652 m_rExport.SdrExporter().AddSdrObject( *pSdrObj );
1654 m_aRunText->append('}');
1655 m_aRunText->append('}');
1657 if ( bSwapInPage )
1658 const_cast< SdrObject* >( pSdrObj )->SetPage( 0 );
1661 break;
1662 case sw::Frame::eFormControl:
1664 const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
1665 const SdrObject *pObject = rFrmFmt.FindRealSdrObject();
1667 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1668 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST);
1670 if (pObject && pObject->GetObjInventor() == FmFormInventor)
1672 if (SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObject))
1674 uno::Reference< awt::XControlModel > xControlModel =
1675 pFormObj->GetUnoControlModel();
1676 uno::Reference< lang::XServiceInfo > xInfo(xControlModel, uno::UNO_QUERY);
1677 uno::Reference<beans::XPropertySet> xPropSet(xControlModel, uno::UNO_QUERY);
1678 uno::Reference<beans::XPropertySetInfo> xPropSetInfo = xPropSet->getPropertySetInfo();
1679 OUString sName;
1680 if (xInfo->supportsService("com.sun.star.form.component.CheckBox"))
1683 m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMCHECKBOX)), m_rExport.eCurrentEncoding));
1684 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
1685 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "1"); // 1 = checkbox
1686 // checkbox size in half points, this seems to be always 20, see WW8Export::DoCheckBox()
1687 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHPS "20");
1689 OUString aStr;
1690 sName = "Name";
1691 if (xPropSetInfo->hasPropertyByName(sName))
1693 xPropSet->getPropertyValue(sName) >>= aStr;
1694 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
1695 m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1696 m_aRun->append('}');
1699 sName = "HelpText";
1700 if (xPropSetInfo->hasPropertyByName(sName))
1702 xPropSet->getPropertyValue(sName) >>= aStr;
1703 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
1704 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
1705 m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1706 m_aRun->append('}');
1709 sName = "HelpF1Text";
1710 if (xPropSetInfo->hasPropertyByName(sName))
1712 xPropSet->getPropertyValue(sName) >>= aStr;
1713 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
1714 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
1715 m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1716 m_aRun->append('}');
1719 sal_Int16 nTemp = 0;
1720 xPropSet->getPropertyValue("DefaultState") >>= nTemp;
1721 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
1722 m_aRun->append((sal_Int32)nTemp);
1723 xPropSet->getPropertyValue("State") >>= nTemp;
1724 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
1725 m_aRun->append((sal_Int32)nTemp);
1727 m_aRun->append("}}");
1729 // field result is empty, ffres already contains the form result
1730 m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1732 else if (xInfo->supportsService("com.sun.star.form.component.TextField"))
1734 OStringBuffer aBuf;
1735 OString aStr;
1736 OUString aTmp;
1737 const sal_Char* pStr;
1739 m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMTEXT)), m_rExport.eCurrentEncoding));
1740 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_DATAFIELD " ");
1741 for (int i = 0; i < 8; i++) aBuf.append((sal_Char)0x00);
1742 xPropSet->getPropertyValue("Name") >>= aTmp;
1743 aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
1744 aBuf.append((sal_Char)aStr.getLength());
1745 aBuf.append(aStr);
1746 aBuf.append((sal_Char)0x00);
1747 xPropSet->getPropertyValue("DefaultText") >>= aTmp;
1748 aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
1749 aBuf.append((sal_Char)aStr.getLength());
1750 aBuf.append(aStr);
1751 for (int i = 0; i < 11; i++) aBuf.append((sal_Char)0x00);
1752 aStr = aBuf.makeStringAndClear();
1753 pStr = aStr.getStr();
1754 for (int i = 0; i < aStr.getLength(); i++, pStr++)
1755 m_aRun->append(msfilter::rtfutil::OutHex(*pStr, 2));
1756 m_aRun->append('}');
1757 m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1758 xPropSet->getPropertyValue("Text") >>= aTmp;
1759 m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
1760 m_aRun->append('}');
1761 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
1762 sName = "HelpText";
1763 if (xPropSetInfo->hasPropertyByName(sName))
1765 xPropSet->getPropertyValue(sName) >>= aTmp;
1766 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
1767 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
1768 m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
1769 m_aRun->append('}');
1772 sName = "HelpF1Text";
1773 if (xPropSetInfo->hasPropertyByName(sName))
1775 xPropSet->getPropertyValue(sName) >>= aTmp;
1776 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
1777 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
1778 m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
1779 m_aRun->append('}');
1781 m_aRun->append("}");
1783 else if (xInfo->supportsService("com.sun.star.form.component.ListBox"))
1785 OUString aStr;
1786 uno::Sequence<sal_Int16> aIntSeq;
1787 uno::Sequence<OUString> aStrSeq;
1789 m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMDROPDOWN)), m_rExport.eCurrentEncoding));
1790 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
1791 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "2"); // 2 = list
1792 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX);
1794 xPropSet->getPropertyValue("DefaultSelection") >>= aIntSeq;
1795 if( aIntSeq.getLength() )
1797 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
1798 // a dropdown list can have only one 'selected item by default'
1799 m_aRun->append((sal_Int32)aIntSeq[0]);
1802 xPropSet->getPropertyValue("SelectedItems") >>= aIntSeq;
1803 if( aIntSeq.getLength() )
1805 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
1806 // a dropdown list can have only one 'currently selected item'
1807 m_aRun->append((sal_Int32)aIntSeq[0]);
1810 sName = "Name";
1811 if (xPropSetInfo->hasPropertyByName(sName))
1813 xPropSet->getPropertyValue(sName) >>= aStr;
1814 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
1815 m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1816 m_aRun->append('}');
1819 sName = "HelpText";
1820 if (xPropSetInfo->hasPropertyByName(sName))
1822 xPropSet->getPropertyValue(sName) >>= aStr;
1823 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
1824 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
1825 m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1826 m_aRun->append('}');
1829 sName = "HelpF1Text";
1830 if (xPropSetInfo->hasPropertyByName(sName))
1832 xPropSet->getPropertyValue(sName) >>= aStr;
1833 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
1834 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
1835 m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
1836 m_aRun->append('}');
1840 xPropSet->getPropertyValue("StringItemList") >>= aStrSeq;
1841 sal_uInt32 nListItems = aStrSeq.getLength();
1842 for (sal_uInt32 i = 0; i < nListItems; i++)
1843 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFL " ")
1844 .append(OUStringToOString(aStrSeq[i], m_rExport.eCurrentEncoding)).append('}');
1846 m_aRun->append("}}");
1848 // field result is empty, ffres already contains the form result
1849 m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1851 else
1852 SAL_INFO("sw.rtf", OSL_THIS_FUNC << " unhandled form control: '" << xInfo->getImplementationName()<< "'");
1853 m_aRun->append('}');
1857 m_aRun->append('}');
1859 break;
1860 case sw::Frame::eOle:
1862 const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
1863 const SdrObject *pSdrObj = rFrmFmt.FindRealSdrObject();
1864 if ( pSdrObj )
1866 SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
1867 SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
1868 FlyFrameOLE(dynamic_cast<const SwFlyFrmFmt*>( &rFrmFmt ), rOLENd, rFrame.GetLayoutSize());
1871 break;
1872 default:
1873 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ": unknown type (" << (int)rFrame.GetWriterType() << ")");
1874 break;
1878 void RtfAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
1880 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1882 switch ( rCaseMap.GetValue() )
1884 case SVX_CASEMAP_KAPITAELCHEN:
1885 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
1886 break;
1887 case SVX_CASEMAP_VERSALIEN:
1888 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
1889 break;
1890 default: // Something that rtf does not support
1891 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
1892 m_aStyles.append((sal_Int32)0);
1893 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
1894 m_aStyles.append((sal_Int32)0);
1895 break;
1899 void RtfAttributeOutput::CharColor( const SvxColorItem& rColor )
1901 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1903 const Color aColor( rColor.GetValue() );
1905 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CF);
1906 m_aStyles.append( (sal_Int32)m_rExport.GetColor( aColor ));
1909 void RtfAttributeOutput::CharContour( const SvxContourItem& rContour )
1911 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1913 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTL);
1914 if ( !rContour.GetValue() )
1915 m_aStyles.append((sal_Int32)0);
1918 void RtfAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
1920 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1922 switch ( rCrossedOut.GetStrikeout() )
1924 case STRIKEOUT_NONE:
1925 if (!m_bStrikeDouble)
1926 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
1927 else
1928 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
1929 m_aStyles.append((sal_Int32)0);
1930 break;
1931 case STRIKEOUT_DOUBLE:
1932 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
1933 m_aStyles.append((sal_Int32)1);
1934 break;
1935 default:
1936 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
1937 break;
1941 void RtfAttributeOutput::CharEscapement( const SvxEscapementItem& rEsc )
1943 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
1945 short nEsc = rEsc.GetEsc();
1946 if (rEsc.GetProp() == DFLT_ESC_PROP)
1948 if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
1949 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUB);
1950 else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
1951 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUPER);
1952 return;
1955 const char * pUpDn;
1957 SwTwips nH = ((SvxFontHeightItem&)m_rExport.GetItem( RES_CHRATR_FONTSIZE )).GetHeight();
1959 if( 0 < rEsc.GetEsc() )
1960 pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
1961 else if( 0 > rEsc.GetEsc() )
1963 pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
1964 nH = -nH;
1966 else
1967 return;
1969 short nProp = rEsc.GetProp() * 100;
1970 if( DFLT_ESC_AUTO_SUPER == nEsc )
1972 nEsc = 100 - rEsc.GetProp();
1973 ++nProp;
1975 else if( DFLT_ESC_AUTO_SUB == nEsc )
1977 nEsc = - 100 + rEsc.GetProp();
1978 ++nProp;
1981 m_aStyles.append('{');
1982 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
1983 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_UPDNPROP);
1984 m_aStyles.append( (sal_Int32)nProp );
1985 m_aStyles.append('}');
1986 m_aStyles.append(pUpDn);
1989 * Calculate the act. FontSize and the percentage of the displacement;
1990 * RTF file expects half points, while internally it's in twips.
1991 * Formally : (FontSize * 1/20 ) pts x * 2
1992 * ----------------------- = ------------
1993 * 100% Escapement
1996 m_aStyles.append( (sal_Int32) ( (long( nEsc ) * nH) + 500L ) / 1000L );
1997 // 500L to round !!
2000 void RtfAttributeOutput::CharFont( const SvxFontItem& rFont)
2002 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2004 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
2005 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_F);
2006 m_aStylesEnd.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
2007 m_rExport.eCurrentEncoding = rtl_getTextEncodingFromWindowsCharset(rtl_getBestWindowsCharsetFromTextEncoding(rFont.GetCharSet()));
2010 void RtfAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
2012 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2014 switch ( rFontSize.Which() )
2016 case RES_CHRATR_FONTSIZE:
2017 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_FS);
2018 m_aStylesEnd.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
2019 break;
2020 case RES_CHRATR_CJK_FONTSIZE:
2021 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FS);
2022 m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
2023 break;
2024 case RES_CHRATR_CTL_FONTSIZE:
2025 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AFS);
2026 m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
2027 break;
2031 void RtfAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
2033 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2035 // in quarter points then in twips
2036 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPND);
2037 m_aStyles.append((sal_Int32)(rKerning.GetValue() / 5));
2038 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPNDTW);
2039 m_aStyles.append((sal_Int32)(rKerning.GetValue()));
2042 void RtfAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
2044 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2046 switch (rLanguage.Which())
2048 case RES_CHRATR_LANGUAGE:
2049 m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LANG);
2050 m_aStylesEnd.append((sal_Int32)rLanguage.GetLanguage());
2051 break;
2052 case RES_CHRATR_CJK_LANGUAGE:
2053 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANGFE);
2054 m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
2055 break;
2056 case RES_CHRATR_CTL_LANGUAGE:
2057 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ALANG);
2058 m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
2059 break;
2063 void RtfAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
2065 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2067 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
2068 if ( rPosture.GetPosture() == ITALIC_NONE )
2069 m_aStyles.append((sal_Int32)0);
2072 void RtfAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
2074 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2076 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SHAD);
2077 if ( !rShadow.GetValue() )
2078 m_aStyles.append((sal_Int32)0);
2081 void RtfAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
2083 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2085 const char* pStr = 0;
2086 const SfxPoolItem* pItem = m_rExport.HasItem( RES_CHRATR_WORDLINEMODE );
2087 bool bWord = false;
2088 if (pItem)
2089 bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;
2090 switch(rUnderline.GetLineStyle() )
2092 case UNDERLINE_SINGLE:
2093 pStr = bWord ? OOO_STRING_SVTOOLS_RTF_ULW : OOO_STRING_SVTOOLS_RTF_UL;
2094 break;
2095 case UNDERLINE_DOUBLE:
2096 pStr = OOO_STRING_SVTOOLS_RTF_ULDB;
2097 break;
2098 case UNDERLINE_NONE:
2099 pStr = OOO_STRING_SVTOOLS_RTF_ULNONE;
2100 break;
2101 case UNDERLINE_DOTTED:
2102 pStr = OOO_STRING_SVTOOLS_RTF_ULD;
2103 break;
2104 case UNDERLINE_DASH:
2105 pStr = OOO_STRING_SVTOOLS_RTF_ULDASH;
2106 break;
2107 case UNDERLINE_DASHDOT:
2108 pStr = OOO_STRING_SVTOOLS_RTF_ULDASHD;
2109 break;
2110 case UNDERLINE_DASHDOTDOT:
2111 pStr = OOO_STRING_SVTOOLS_RTF_ULDASHDD;
2112 break;
2113 case UNDERLINE_BOLD:
2114 pStr = OOO_STRING_SVTOOLS_RTF_ULTH;
2115 break;
2116 case UNDERLINE_WAVE:
2117 pStr = OOO_STRING_SVTOOLS_RTF_ULWAVE;
2118 break;
2119 case UNDERLINE_BOLDDOTTED:
2120 pStr = OOO_STRING_SVTOOLS_RTF_ULTHD;
2121 break;
2122 case UNDERLINE_BOLDDASH:
2123 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASH;
2124 break;
2125 case UNDERLINE_LONGDASH:
2126 pStr = OOO_STRING_SVTOOLS_RTF_ULLDASH;
2127 break;
2128 case UNDERLINE_BOLDLONGDASH:
2129 pStr = OOO_STRING_SVTOOLS_RTF_ULTHLDASH;
2130 break;
2131 case UNDERLINE_BOLDDASHDOT:
2132 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHD;
2133 break;
2134 case UNDERLINE_BOLDDASHDOTDOT:
2135 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHDD;
2136 break;
2137 case UNDERLINE_BOLDWAVE:
2138 pStr = OOO_STRING_SVTOOLS_RTF_ULHWAVE;
2139 break;
2140 case UNDERLINE_DOUBLEWAVE:
2141 pStr = OOO_STRING_SVTOOLS_RTF_ULULDBWAVE;
2142 break;
2143 default:
2144 break;
2147 if( pStr )
2149 m_aStyles.append(pStr);
2150 // NEEDSWORK looks like here rUnderline.GetColor() is always black,
2151 // even if the color in the odt is for example green...
2152 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ULC);
2153 m_aStyles.append( (sal_Int32)m_rExport.GetColor(rUnderline.GetColor()) );
2157 void RtfAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
2159 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2161 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
2162 if ( rWeight.GetWeight() != WEIGHT_BOLD )
2163 m_aStyles.append((sal_Int32)0);
2166 void RtfAttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern)
2168 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2170 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KERNING);
2171 m_aStyles.append((sal_Int32) (rAutoKern.GetValue() ? 1 : 0));
2174 void RtfAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
2176 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2178 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ANIMTEXT);
2179 m_aStyles.append((sal_Int32) (rBlink.GetValue() ? 2 : 0));
2182 void RtfAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
2184 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2186 if( !rBrush.GetColor().GetTransparency() )
2188 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHCBPAT);
2189 m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
2193 void RtfAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
2195 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2197 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2198 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
2199 m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
2202 void RtfAttributeOutput::CharFontSizeCJK( const SvxFontHeightItem& rFontSize )
2204 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2206 CharFontSize( rFontSize );
2209 void RtfAttributeOutput::CharLanguageCJK( const SvxLanguageItem& rLanguageItem )
2211 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2213 CharLanguage( rLanguageItem );
2216 void RtfAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
2218 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2220 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
2221 if ( rPosture.GetPosture() == ITALIC_NONE )
2222 m_aStyles.append((sal_Int32)0);
2225 void RtfAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
2227 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2229 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
2230 if ( rWeight.GetWeight() != WEIGHT_BOLD )
2231 m_aStyles.append((sal_Int32)0);
2234 void RtfAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
2236 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2238 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2239 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
2240 m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
2243 void RtfAttributeOutput::CharFontSizeCTL( const SvxFontHeightItem& rFontSize )
2245 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2247 CharFontSize( rFontSize );
2250 void RtfAttributeOutput::CharLanguageCTL( const SvxLanguageItem& rLanguageItem )
2252 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2254 CharLanguage( rLanguageItem );
2257 void RtfAttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture)
2259 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2261 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AI);
2262 if ( rPosture.GetPosture() == ITALIC_NONE )
2263 m_aStyles.append((sal_Int32)0);
2266 void RtfAttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
2268 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2270 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AB);
2271 if ( rWeight.GetWeight() != WEIGHT_BOLD )
2272 m_aStyles.append((sal_Int32)0);
2275 void RtfAttributeOutput::CharRotate( const SvxCharRotateItem& rRotate)
2277 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2279 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HORZVERT);
2280 m_aStyles.append((sal_Int32)(rRotate.IsFitToLine() ? 1 : 0));
2283 void RtfAttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
2285 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2287 const sal_Char* pStr;
2288 switch( rEmphasisMark.GetEmphasisMark())
2290 case EMPHASISMARK_NONE: pStr = OOO_STRING_SVTOOLS_RTF_ACCNONE; break;
2291 case EMPHASISMARK_SIDE_DOTS: pStr = OOO_STRING_SVTOOLS_RTF_ACCCOMMA; break;
2292 default: pStr = OOO_STRING_SVTOOLS_RTF_ACCDOT; break;
2294 m_aStyles.append(pStr);
2297 void RtfAttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
2299 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2301 if( rTwoLines.GetValue() )
2303 sal_Unicode cStart = rTwoLines.GetStartBracket();
2304 sal_Unicode cEnd = rTwoLines.GetEndBracket();
2306 sal_uInt16 nType;
2307 if( !cStart && !cEnd )
2308 nType = 0;
2309 else if( '{' == cStart || '}' == cEnd )
2310 nType = 4;
2311 else if( '<' == cStart || '>' == cEnd )
2312 nType = 3;
2313 else if( '[' == cStart || ']' == cEnd )
2314 nType = 2;
2315 else // all other kind of brackets
2316 nType = 1;
2318 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TWOINONE);
2319 m_aStyles.append((sal_Int32)nType);
2323 void RtfAttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
2325 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2327 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHARSCALEX);
2328 m_aStyles.append((sal_Int32)rScaleWidth.GetValue());
2331 void RtfAttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
2333 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2335 const sal_Char* pStr;
2336 switch (rRelief.GetValue())
2338 case RELIEF_EMBOSSED:
2339 pStr = OOO_STRING_SVTOOLS_RTF_EMBO;
2340 break;
2341 case RELIEF_ENGRAVED:
2342 pStr = OOO_STRING_SVTOOLS_RTF_IMPR;
2343 break;
2344 default:
2345 pStr = 0;
2346 break;
2349 if (pStr)
2350 m_aStyles.append(pStr);
2353 void RtfAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
2355 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2357 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_V);
2358 if ( !rHidden.GetValue() )
2359 m_aStyles.append((sal_Int32)0);
2362 void RtfAttributeOutput::TextINetFormat( const SwFmtINetFmt& rURL )
2364 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2366 if( rURL.GetValue().Len() )
2368 const SwCharFmt* pFmt;
2369 const SwTxtINetFmt* pTxtAtr = rURL.GetTxtINetFmt();
2371 m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
2372 m_bHadFieldResult = true;
2373 if( pTxtAtr && 0 != ( pFmt = pTxtAtr->GetCharFmt() ))
2375 sal_uInt16 nStyle = m_rExport.GetId( *pFmt );
2376 OString* pString = m_rExport.GetStyle(nStyle);
2377 if (pString)
2378 m_aStyles.append(*pString);
2383 void RtfAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
2385 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2387 sal_uInt16 nStyle = m_rExport.GetId( *rCharFmt.GetCharFmt() );
2388 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CS);
2389 m_aStyles.append((sal_Int32)nStyle);
2390 OString* pString = m_rExport.GetStyle(nStyle);
2391 if (pString)
2392 m_aStyles.append(*pString);
2395 void RtfAttributeOutput::WriteTextFootnoteNumStr(const SwFmtFtn& rFootnote)
2397 if (!rFootnote.GetNumStr().Len())
2398 m_aRun->append(OOO_STRING_SVTOOLS_RTF_CHFTN);
2399 else
2400 m_aRun->append(msfilter::rtfutil::OutString(rFootnote.GetNumStr(), m_rExport.eCurrentEncoding));
2403 void RtfAttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFootnote )
2405 SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
2407 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_SUPER " ");
2408 WriteTextFootnoteNumStr(rFootnote);
2409 m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FOOTNOTE);
2410 if( rFootnote.IsEndNote() )
2411 m_aRun->append(OOO_STRING_SVTOOLS_RTF_FTNALT);
2412 m_aRun->append(' ');
2413 WriteTextFootnoteNumStr(rFootnote);
2416 * The footnote contains a whole paragraph, so we have to:
2417 * 1) Reset, then later restore the contents of our run buffer and run state.
2418 * 2) Buffer the output of the whole paragraph, as we do so for section headers already.
2420 const SwNodeIndex* pIndex = rFootnote.GetTxtFtn()->GetStartNode();
2421 RtfStringBuffer aRun = m_aRun;
2422 m_aRun.clear();
2423 bool bInRunOrig = m_bInRun;
2424 m_bInRun = false;
2425 bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
2426 m_bSingleEmptyRun = false;
2427 m_bBufferSectionHeaders = true;
2428 m_rExport.WriteSpecialText( pIndex->GetIndex() + 1,
2429 pIndex->GetNode().EndOfSectionIndex(),
2430 !rFootnote.IsEndNote() ? TXT_FTN : TXT_EDN);
2431 m_bBufferSectionHeaders = false;
2432 m_bInRun = bInRunOrig;
2433 m_bSingleEmptyRun = bSingleEmptyRunOrig;
2434 m_aRun = aRun;
2435 m_aRun->append(m_aSectionHeaders.makeStringAndClear());
2437 m_aRun->append("}");
2438 m_aRun->append("}");
2440 SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
2443 void RtfAttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
2445 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2447 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SL);
2448 m_aStyles.append((sal_Int32)nSpace);
2449 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SLMULT);
2450 m_aStyles.append((sal_Int32)nMulti);
2454 void RtfAttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
2456 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2458 switch ( rAdjust.GetAdjust() )
2460 case SVX_ADJUST_LEFT:
2461 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QL);
2462 break;
2463 case SVX_ADJUST_RIGHT:
2464 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QR);
2465 break;
2466 case SVX_ADJUST_BLOCKLINE:
2467 case SVX_ADJUST_BLOCK:
2468 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QJ);
2469 break;
2470 case SVX_ADJUST_CENTER:
2471 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QC);
2472 break;
2473 default:
2474 break;
2478 void RtfAttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
2480 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2482 if( !rSplit.GetValue() )
2483 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEP);
2486 void RtfAttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
2488 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2490 if (rWidows.GetValue())
2491 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_WIDCTLPAR);
2492 else
2493 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOWIDCTLPAR);
2496 void RtfAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
2498 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2500 long nOffset = ((SvxLRSpaceItem&)m_rExport.GetItem( RES_LR_SPACE )).GetTxtLeft();
2501 for( sal_uInt16 n = 0; n < rTabStop.Count(); n++ )
2503 const SvxTabStop & rTS = rTabStop[ n ];
2504 if( SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment() )
2506 const char* pFill = 0;
2507 switch( rTS.GetFill() )
2509 case cDfltFillChar:
2510 break;
2512 case '.': pFill = OOO_STRING_SVTOOLS_RTF_TLDOT; break;
2513 case '_': pFill = OOO_STRING_SVTOOLS_RTF_TLUL; break;
2514 case '-': pFill = OOO_STRING_SVTOOLS_RTF_TLTH; break;
2515 case '=': pFill = OOO_STRING_SVTOOLS_RTF_TLEQ; break;
2516 default:
2517 break;
2519 if( pFill )
2520 m_aStyles.append(pFill);
2522 const sal_Char* pAdjStr = 0;
2523 switch (rTS.GetAdjustment())
2525 case SVX_TAB_ADJUST_RIGHT:
2526 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
2527 break;
2528 case SVX_TAB_ADJUST_DECIMAL:
2529 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
2530 break;
2531 case SVX_TAB_ADJUST_CENTER:
2532 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
2533 break;
2534 default:
2535 break;
2537 if (pAdjStr)
2538 m_aStyles.append(pAdjStr);
2539 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TX);
2540 m_aStyles.append((sal_Int32)(rTS.GetTabPos() + nOffset));
2542 else
2544 m_aTabStop.append( OOO_STRING_SVTOOLS_RTF_DEFTAB );
2545 m_aTabStop.append( (sal_Int32)rTabStop[0].GetTabPos() );
2550 void RtfAttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
2552 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2554 sal_Int32 nFlags = rHyphenZone.IsHyphen() ? 1 : 0;
2555 if( rHyphenZone.IsPageEnd() )
2556 nFlags += 2;
2557 m_aStyles.append('{');
2558 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
2559 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHEN);
2560 m_aStyles.append((sal_Int32)nFlags);
2561 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHLEAD);
2562 m_aStyles.append((sal_Int32)rHyphenZone.GetMinLead());
2563 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHTRAIL);
2564 m_aStyles.append((sal_Int32)rHyphenZone.GetMinTrail());
2565 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHMAX);
2566 m_aStyles.append((sal_Int32)rHyphenZone.GetMaxHyphens());
2567 m_aStyles.append('}');
2570 void RtfAttributeOutput::ParaNumRule_Impl( const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId )
2572 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2574 if ( USHRT_MAX == nNumId || 0 == nNumId || 0 == pTxtNd)
2575 return;
2577 const SwNumRule* pRule = pTxtNd->GetNumRule();
2579 if( pRule && pTxtNd->IsInList() )
2581 OSL_ENSURE( pTxtNd->GetActualListLevel() >= 0 && pTxtNd->GetActualListLevel() < MAXLEVEL,
2582 "<SwRTFWriter::OutListNum(..)> - text node does not have valid list level. Serious defect -> please inform OD" );
2584 const bool bExportNumRule = USHRT_MAX != nNumId;
2585 const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl );
2586 if( !pFmt )
2587 pFmt = &pRule->Get( nLvl );
2589 const SfxItemSet& rNdSet = pTxtNd->GetSwAttrSet();
2591 if ( bExportNumRule ) {
2592 m_aStyles.append('{');
2593 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LISTTEXT);
2594 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PARD);
2595 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
2596 m_aStyles.append(' ');
2599 SvxLRSpaceItem aLR( (SvxLRSpaceItem&)rNdSet.Get( RES_LR_SPACE ) );
2600 aLR.SetTxtLeft( aLR.GetTxtLeft() + pFmt->GetIndentAt() );
2601 aLR.SetTxtFirstLineOfst( pFmt->GetFirstLineOffset() );
2603 sal_uInt16 nStyle = m_rExport.GetId( *pFmt->GetCharFmt() );
2604 OString* pString = m_rExport.GetStyle(nStyle);
2605 if (pString)
2606 m_aStyles.append(*pString);
2609 String sTxt;
2610 if( SVX_NUM_CHAR_SPECIAL == pFmt->GetNumberingType() || SVX_NUM_BITMAP == pFmt->GetNumberingType() )
2611 sTxt = pFmt->GetBulletChar();
2612 else
2613 sTxt = pTxtNd->GetNumString();
2615 if (sTxt.Len())
2617 m_aStyles.append(' ');
2618 m_aStyles.append(msfilter::rtfutil::OutString(sTxt, m_rExport.eDefaultEncoding));
2621 if( bExportNumRule )
2623 if( OUTLINE_RULE != pRule->GetRuleType() )
2625 if (sTxt.Len())
2626 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
2627 m_aStyles.append('}');
2628 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
2629 if( nLvl > 8 ) // RTF knows only 9 levels
2631 m_aStyles.append((sal_Int32)8);
2632 m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SOUTLVL);
2633 m_aStyles.append((sal_Int32)nLvl);
2634 m_aStyles.append('}');
2636 else
2637 m_aStyles.append((sal_Int32)nLvl);
2639 else
2640 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB "}");
2641 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LS);
2642 m_aStyles.append((sal_Int32)m_rExport.GetId(*pRule)+1);
2643 m_aStyles.append(' ');
2645 else if( sTxt.Len() )
2646 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
2648 FormatLRSpace(aLR);
2652 void RtfAttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
2654 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2656 if (!rScriptSpace.GetValue( ))
2657 return;
2658 switch ( rScriptSpace.Which( ) )
2660 case RES_PARATR_SCRIPTSPACE:
2661 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ASPALPHA);
2662 break;
2664 default:
2665 break;
2669 void RtfAttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
2671 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2673 const char* pStr;
2674 switch ( rAlign.GetValue() )
2676 case SvxParaVertAlignItem::TOP: pStr = OOO_STRING_SVTOOLS_RTF_FAHANG; break;
2677 case SvxParaVertAlignItem::BOTTOM: pStr = OOO_STRING_SVTOOLS_RTF_FAVAR; break;
2678 case SvxParaVertAlignItem::CENTER: pStr = OOO_STRING_SVTOOLS_RTF_FACENTER; break;
2679 case SvxParaVertAlignItem::BASELINE: pStr = OOO_STRING_SVTOOLS_RTF_FAROMAN; break;
2681 default: pStr = OOO_STRING_SVTOOLS_RTF_FAAUTO; break;
2683 m_aStyles.append(pStr);
2686 void RtfAttributeOutput::ParaSnapToGrid( const SvxParaGridItem& /*rGrid*/ )
2688 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2691 void RtfAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
2693 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2695 if (m_rExport.bOutPageDescs)
2697 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGWSXN);
2698 m_aSectionBreaks.append((sal_Int32)rSize.GetWidth());
2699 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGHSXN);
2700 m_aSectionBreaks.append((sal_Int32)rSize.GetHeight());
2701 if (!m_bBufferSectionBreaks)
2702 m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear().getStr();
2706 void RtfAttributeOutput::FormatPaperBin( const SvxPaperBinItem& )
2708 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2711 void RtfAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
2713 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2715 if ( !m_rExport.bOutFlyFrmAttrs )
2717 if( m_rExport.bOutPageDescs )
2719 if( rLRSpace.GetLeft() )
2721 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGLSXN);
2722 m_aSectionBreaks.append((sal_Int32)rLRSpace.GetLeft());
2724 if( rLRSpace.GetRight() )
2726 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGRSXN);
2727 m_aSectionBreaks.append((sal_Int32)rLRSpace.GetRight());
2729 if (!m_bBufferSectionBreaks)
2730 m_rExport.Strm() <<
2731 m_aSectionBreaks.makeStringAndClear().getStr();
2733 else
2735 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LI);
2736 m_aStyles.append( (sal_Int32) rLRSpace.GetTxtLeft() );
2737 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RI);
2738 m_aStyles.append( (sal_Int32) rLRSpace.GetRight() );
2739 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LIN);
2740 m_aStyles.append( (sal_Int32) rLRSpace.GetTxtLeft() );
2741 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RIN);
2742 m_aStyles.append( (sal_Int32) rLRSpace.GetRight() );
2743 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FI);
2744 m_aStyles.append( (sal_Int32) rLRSpace.GetTxtFirstLineOfst() );
2747 else if (m_rExport.bRTFFlySyntax)
2749 // Wrap: top and bottom spacing, convert from twips to EMUs.
2750 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxWrapDistLeft", OString::number(rLRSpace.GetLeft() * 635)));
2751 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxWrapDistRight", OString::number(rLRSpace.GetRight() * 635)));
2755 void RtfAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
2757 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2759 if ( !m_rExport.bOutFlyFrmAttrs )
2761 if( m_rExport.bOutPageDescs )
2763 OSL_ENSURE( m_rExport.GetCurItemSet(), "Impossible" );
2764 if ( !m_rExport.GetCurItemSet() )
2765 return;
2767 HdFtDistanceGlue aDistances( *m_rExport.GetCurItemSet() );
2769 if( aDistances.dyaTop )
2771 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGTSXN);
2772 m_aSectionBreaks.append((sal_Int32)aDistances.dyaTop);
2774 if ( aDistances.HasHeader() )
2776 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_HEADERY);
2777 m_aSectionBreaks.append((sal_Int32)aDistances.dyaHdrTop);
2780 if( aDistances.dyaBottom )
2782 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGBSXN);
2783 m_aSectionBreaks.append((sal_Int32)aDistances.dyaBottom);
2785 if( aDistances.HasFooter() )
2787 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_FOOTERY);
2788 m_aSectionBreaks.append((sal_Int32)aDistances.dyaHdrBottom);
2790 if (!m_bBufferSectionBreaks)
2791 m_rExport.Strm() <<
2792 m_aSectionBreaks.makeStringAndClear().getStr();
2794 else
2796 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
2797 m_aStyles.append( (sal_Int32) rULSpace.GetUpper() );
2798 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
2799 m_aStyles.append( (sal_Int32) rULSpace.GetLower() );
2800 if (rULSpace.GetContext())
2801 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CONTEXTUALSPACE);
2804 else if (m_rExport.bRTFFlySyntax)
2806 // Wrap: top and bottom spacing, convert from twips to EMUs.
2807 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyWrapDistTop", OString::number(rULSpace.GetUpper() * 635)));
2808 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyWrapDistBottom", OString::number(rULSpace.GetLower() * 635)));
2812 void RtfAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
2814 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2816 if ( m_rExport.bOutFlyFrmAttrs && !m_rExport.bRTFFlySyntax )
2818 SwSurround eSurround = rSurround.GetSurround();
2819 sal_Bool bGold = SURROUND_IDEAL == eSurround;
2820 if( bGold )
2821 eSurround = SURROUND_PARALLEL;
2822 RTFSurround aMC( bGold, static_cast< sal_uInt8 >(eSurround) );
2823 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYMAINCNT);
2824 m_aRunText->append( (sal_Int32) aMC.GetValue() );
2828 void RtfAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
2830 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2832 if ( m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax )
2834 switch (rFlyVert.GetRelationOrient())
2836 case text::RelOrientation::PAGE_FRAME:
2837 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelv", OString::number(1)));
2838 break;
2839 default:
2840 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelv", OString::number(2)));
2841 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPBYPARA << OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE;
2842 break;
2845 switch(rFlyVert.GetVertOrient())
2847 case text::VertOrientation::TOP:
2848 case text::VertOrientation::LINE_TOP:
2849 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(1)));
2850 break;
2851 case text::VertOrientation::BOTTOM:
2852 case text::VertOrientation::LINE_BOTTOM:
2853 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(3)));
2854 break;
2855 case text::VertOrientation::CENTER:
2856 case text::VertOrientation::LINE_CENTER:
2857 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(2)));
2858 break;
2859 default:
2860 break;
2863 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPTOP;
2864 m_rExport.OutLong(rFlyVert.GetPos());
2865 if (m_pFlyFrameSize)
2867 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPBOTTOM;
2868 m_rExport.OutLong(rFlyVert.GetPos() + m_pFlyFrameSize->Height());
2873 void RtfAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
2875 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2877 if ( m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax )
2879 switch (rFlyHori.GetRelationOrient())
2881 case text::RelOrientation::PAGE_FRAME:
2882 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelh", OString::number(1)));
2883 break;
2884 default:
2885 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelh", OString::number(2)));
2886 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN << OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE;
2887 break;
2890 switch(rFlyHori.GetHoriOrient())
2892 case text::HoriOrientation::LEFT:
2893 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(1)));
2894 break;
2895 case text::HoriOrientation::CENTER:
2896 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(2)));
2897 break;
2898 case text::HoriOrientation::RIGHT:
2899 m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(3)));
2900 break;
2901 default:
2902 break;
2905 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPLEFT;
2906 m_rExport.OutLong(rFlyHori.GetPos());
2907 if (m_pFlyFrameSize)
2909 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_SHPRIGHT;
2910 m_rExport.OutLong(rFlyHori.GetPos() + m_pFlyFrameSize->Width());
2915 void RtfAttributeOutput::FormatAnchor( const SwFmtAnchor& rAnchor )
2917 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2919 if ( !m_rExport.bRTFFlySyntax )
2921 sal_uInt16 nId = static_cast< sal_uInt16 >(rAnchor.GetAnchorId());
2922 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYANCHOR);
2923 m_aRunText->append((sal_Int32)nId);
2924 switch( nId )
2926 case FLY_AT_PAGE:
2927 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYPAGE);
2928 m_aRunText->append((sal_Int32)rAnchor.GetPageNum());
2929 break;
2930 case FLY_AT_PARA:
2931 case FLY_AS_CHAR:
2932 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYCNTNT);
2933 break;
2938 void RtfAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
2940 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2942 if (m_rExport.bRTFFlySyntax)
2944 const Color& rColor = rBrush.GetColor();
2945 // We in fact need RGB to BGR, but the transformation is symmetric.
2946 m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
2948 else if( !rBrush.GetColor().GetTransparency() )
2950 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CBPAT);
2951 m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
2955 void RtfAttributeOutput::FormatFillStyle( const XFillStyleItem& rFillStyle )
2957 m_oFillStyle.reset(rFillStyle.GetValue());
2960 void RtfAttributeOutput::FormatFillGradient( const XFillGradientItem& rFillGradient )
2962 if (*m_oFillStyle == XFILL_GRADIENT)
2964 m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillType", OString::number(7))); // Shade using the fillAngle
2966 const XGradient& rGradient = rFillGradient.GetGradientValue();
2967 const Color& rStartColor = rGradient.GetStartColor();
2968 m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillBackColor", OString::number(msfilter::util::BGRToRGB(rStartColor.GetColor()))));
2970 const Color& rEndColor = rGradient.GetEndColor();
2971 m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillColor", OString::number(msfilter::util::BGRToRGB(rEndColor.GetColor()))));
2973 switch (rGradient.GetGradientStyle())
2975 case XGRAD_LINEAR: break;
2976 case XGRAD_AXIAL:
2977 m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillFocus", OString::number(50)));
2978 break;
2979 case XGRAD_RADIAL: break;
2980 case XGRAD_ELLIPTICAL: break;
2981 case XGRAD_SQUARE: break;
2982 case XGRAD_RECT: break;
2987 void RtfAttributeOutput::FormatBox( const SvxBoxItem& rBox )
2989 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
2991 static sal_uInt16 aBorders[] = {
2992 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT };
2993 static const sal_Char* aBorderNames[] = {
2994 OOO_STRING_SVTOOLS_RTF_BRDRT, OOO_STRING_SVTOOLS_RTF_BRDRL, OOO_STRING_SVTOOLS_RTF_BRDRB, OOO_STRING_SVTOOLS_RTF_BRDRR };
2996 sal_uInt16 nDist = rBox.GetDistance();
2998 if ( m_rExport.bRTFFlySyntax )
3000 // Borders: spacing to contents, convert from twips to EMUs.
3001 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxTextLeft", OString::number(rBox.GetDistance(BOX_LINE_LEFT) * 635)));
3002 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyTextTop", OString::number(rBox.GetDistance(BOX_LINE_TOP) * 635)));
3003 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxTextRight", OString::number(rBox.GetDistance(BOX_LINE_RIGHT) * 635)));
3004 m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyTextBottom", OString::number(rBox.GetDistance(BOX_LINE_BOTTOM) * 635)));
3006 const SvxBorderLine* pLeft = rBox.GetLine(BOX_LINE_LEFT);
3007 const SvxBorderLine* pRight = rBox.GetLine(BOX_LINE_RIGHT);
3008 const SvxBorderLine* pTop = rBox.GetLine(BOX_LINE_TOP);
3009 const SvxBorderLine* pBottom = rBox.GetLine(BOX_LINE_BOTTOM);
3010 if (pLeft && pRight && pTop && pBottom && *pLeft == *pRight && *pLeft == *pTop && *pLeft == *pBottom)
3012 const Color& rColor = pTop->GetColor();
3013 // We in fact need RGB to BGR, but the transformation is symmetric.
3014 m_aFlyProperties.push_back(std::make_pair<OString, OString>("lineColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
3016 double const fConverted(editeng::ConvertBorderWidthToWord(pTop->GetBorderLineStyle(), pTop->GetWidth()));
3017 sal_Int32 nWidth = sal_Int32(fConverted * 635); // Twips -> EMUs
3018 m_aFlyProperties.push_back(std::make_pair<OString, OString>("lineWidth", OString::number(nWidth)));
3021 return;
3024 if( rBox.GetTop() && rBox.GetBottom() &&
3025 rBox.GetLeft() && rBox.GetRight() &&
3026 *rBox.GetTop() == *rBox.GetBottom() &&
3027 *rBox.GetTop() == *rBox.GetLeft() &&
3028 *rBox.GetTop() == *rBox.GetRight() &&
3029 nDist == rBox.GetDistance( BOX_LINE_TOP ) &&
3030 nDist == rBox.GetDistance( BOX_LINE_LEFT ) &&
3031 nDist == rBox.GetDistance( BOX_LINE_BOTTOM ) &&
3032 nDist == rBox.GetDistance( BOX_LINE_RIGHT ))
3033 m_aSectionBreaks.append(OutBorderLine( m_rExport, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist ));
3034 else
3036 const sal_uInt16* pBrd = aBorders;
3037 const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
3038 for(int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
3040 if (const SvxBorderLine* pLn = rBox.GetLine(*pBrd))
3042 m_aSectionBreaks.append(OutBorderLine(m_rExport, pLn, *pBrdNms,
3043 rBox.GetDistance(*pBrd)));
3048 if (!m_bBufferSectionBreaks)
3049 m_aStyles.append(m_aSectionBreaks.makeStringAndClear());
3052 void RtfAttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize )
3054 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3056 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLS;
3057 m_rExport.OutLong( nCols );
3059 if( bEven )
3061 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLSX;
3062 m_rExport.OutLong( rCol.GetGutterWidth( sal_True ) );
3064 else
3066 const SwColumns & rColumns = rCol.GetColumns( );
3067 for( sal_uInt16 n = 0; n < nCols; )
3069 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLNO;
3070 m_rExport.OutLong( n+1 );
3072 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLW;
3073 m_rExport.OutLong( rCol.CalcPrtColWidth( n, nPageSize ) );
3075 if( ++n != nCols )
3077 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_COLSR;
3078 m_rExport.OutLong( rColumns[ n-1 ].GetRight() +
3079 rColumns[ n ].GetLeft() );
3085 void RtfAttributeOutput::FormatKeep( const SvxFmtKeepItem& rItem )
3087 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3089 if( rItem.GetValue() )
3090 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEPN);
3093 void RtfAttributeOutput::FormatTextGrid( const SwTextGridItem& /*rGrid*/ )
3095 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3098 void RtfAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
3100 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3102 if ( !rNumbering.IsCount( ) )
3103 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOLINE);
3106 void RtfAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
3108 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3110 if (!m_rExport.bOutPageDescs)
3112 if (rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP)
3113 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RTLPAR);
3114 else
3115 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LTRPAR);
3119 void RtfAttributeOutput::WriteExpand( const SwField* pFld )
3121 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3122 String sCmd; // for optional Parameters
3123 switch (pFld->GetTyp()->Which())
3125 //#i119803# Export user field and DB field for RTF filter
3126 case RES_DBFLD:
3127 sCmd = FieldString(ww::eMERGEFIELD);
3128 // no break !!
3129 case RES_USERFLD:
3130 sCmd += pFld->GetTyp()->GetName();
3131 m_rExport.OutputField(pFld, ww::eNONE, sCmd);
3132 break;
3133 default:
3134 m_rExport.OutputField(pFld, ww::eUNKNOWN, sCmd);
3135 break;
3139 void RtfAttributeOutput::RefField( const SwField& /*rFld*/, const String& /*rRef*/ )
3141 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3144 void RtfAttributeOutput::HiddenField( const SwField& /*rFld*/ )
3146 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3149 void RtfAttributeOutput::SetField( const SwField& /*rFld*/, ww::eField /*eType*/, const String& /*rCmd*/ )
3151 SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3154 void RtfAttributeOutput::PostitField( const SwField* pFld )
3156 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3158 const SwPostItField& rPFld = *(SwPostItField*)pFld;
3160 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " ");
3161 m_aRunText->append(OUStringToOString(OUString(rPFld.GetInitials()), m_rExport.eCurrentEncoding));
3162 m_aRunText->append("}");
3163 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNAUTHOR " ");
3164 m_aRunText->append(OUStringToOString(OUString(rPFld.GetPar1()), m_rExport.eCurrentEncoding));
3165 m_aRunText->append("}");
3166 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_CHATN);
3168 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ANNOTATION);
3169 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNREF " ");
3170 m_aRunText->append(sal_Int32(m_nPostitFieldsMaxId++));
3171 m_aRunText->append('}');
3172 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNDATE " ");
3173 m_aRunText->append((sal_Int32)sw::ms::DateTime2DTTM(rPFld.GetDateTime()));
3174 m_aRunText->append('}');
3175 m_aRunText->append(OUStringToOString(OUString(rPFld.GetTxt()), m_rExport.eCurrentEncoding));
3176 m_aRunText->append('}');
3179 void RtfAttributeOutput::WritePostitFieldStart()
3181 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFSTART " ");
3182 m_aRunText->append(sal_Int32(m_nPostitFieldsMaxId));
3183 m_aRunText->append("}");
3186 void RtfAttributeOutput::WritePostitFieldEnd()
3188 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFEND " ");
3189 m_aRunText->append(sal_Int32(m_nPostitFieldsMaxId));
3190 m_aRunText->append("}");
3193 bool RtfAttributeOutput::DropdownField( const SwField* /*pFld*/ )
3195 // this is handled in OutputFlyFrame_Impl()
3196 return true;
3199 bool RtfAttributeOutput::PlaceholderField( const SwField* pField)
3201 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " MACROBUTTON None ");
3202 RunText(pField->GetPar1());
3203 m_aRunText->append("}}");
3204 return false; // do not expand
3207 RtfAttributeOutput::RtfAttributeOutput( RtfExport &rExport )
3208 : m_rExport( rExport ),
3209 m_bStrikeDouble( false ),
3210 m_pTableWrt( NULL ),
3211 m_bTableCellOpen( false ),
3212 m_nTableDepth( 0 ),
3213 m_bTblAfterCell( false ),
3214 m_nColBreakNeeded( false ),
3215 m_bBufferSectionBreaks( false ),
3216 m_bBufferSectionHeaders( false ),
3217 m_bLastTable( true ),
3218 m_bWroteCellInfo( false ),
3219 m_bHadFieldResult( false ),
3220 m_bTableRowEnded( false ),
3221 m_aCells(),
3222 m_bSingleEmptyRun(false),
3223 m_bInRun(false),
3224 m_nPostitFieldsMaxId(0),
3225 m_pFlyFrameSize(0),
3226 m_pPrevPageDesc(0)
3228 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3231 RtfAttributeOutput::~RtfAttributeOutput()
3233 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3236 MSWordExportBase& RtfAttributeOutput::GetExport()
3238 return m_rExport;
3241 // These are used by wwFont::WriteRtf()
3243 /// Start the font.
3244 void RtfAttributeOutput::StartFont( const String& rFamilyName ) const
3246 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3248 m_rExport.Strm() << OUStringToOString( OUString( rFamilyName ), m_rExport.eCurrentEncoding ).getStr();
3251 /// End the font.
3252 void RtfAttributeOutput::EndFont() const
3254 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3256 m_rExport.Strm() << ";}";
3259 /// Alternate name for the font.
3260 void RtfAttributeOutput::FontAlternateName( const String& rName ) const
3262 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3264 m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_FALT << ' ';
3265 m_rExport.Strm() << OUStringToOString( OUString( rName ), m_rExport.eCurrentEncoding ).getStr() << '}';
3268 /// Font charset.
3269 void RtfAttributeOutput::FontCharset( sal_uInt8 nCharSet ) const
3271 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3273 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_FCHARSET;
3274 m_rExport.OutULong( nCharSet );
3275 m_rExport.Strm() << ' ';
3278 /// Font family.
3279 void RtfAttributeOutput::FontFamilyType( FontFamily eFamily, const wwFont &rFont ) const
3281 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3283 m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_F;
3285 const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL;
3286 switch (eFamily)
3288 case FAMILY_ROMAN:
3289 pStr = OOO_STRING_SVTOOLS_RTF_FROMAN;
3290 break;
3291 case FAMILY_SWISS:
3292 pStr = OOO_STRING_SVTOOLS_RTF_FSWISS;
3293 break;
3294 case FAMILY_MODERN:
3295 pStr = OOO_STRING_SVTOOLS_RTF_FMODERN;
3296 break;
3297 case FAMILY_SCRIPT:
3298 pStr = OOO_STRING_SVTOOLS_RTF_FSCRIPT;
3299 break;
3300 case FAMILY_DECORATIVE:
3301 pStr = OOO_STRING_SVTOOLS_RTF_FDECOR;
3302 break;
3303 default:
3304 break;
3306 m_rExport.OutULong(m_rExport.maFontHelper.GetId(rFont)) << pStr;
3309 /// Font pitch.
3310 void RtfAttributeOutput::FontPitchType( FontPitch ePitch ) const
3312 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3314 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_FPRQ;
3316 sal_uInt16 nVal = 0;
3317 switch (ePitch)
3319 case PITCH_FIXED:
3320 nVal = 1;
3321 break;
3322 case PITCH_VARIABLE:
3323 nVal = 2;
3324 break;
3325 default:
3326 break;
3328 m_rExport.OutULong(nVal);
3331 static bool IsEMF(const sal_uInt8 *pGraphicAry, unsigned long nSize)
3333 if (pGraphicAry && (nSize > 0x2c ))
3335 // check the magic number
3336 if (
3337 (pGraphicAry[0x28] == 0x20 ) && (pGraphicAry[0x29] == 0x45) &&
3338 (pGraphicAry[0x2a] == 0x4d ) && (pGraphicAry[0x2b] == 0x46)
3341 //emf detected
3342 return true;
3345 return false;
3348 static bool StripMetafileHeader(const sal_uInt8 *&rpGraphicAry, unsigned long &rSize)
3350 if (rpGraphicAry && (rSize > 0x22))
3352 if (
3353 (rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) &&
3354 (rpGraphicAry[2] == 0xc6) && (rpGraphicAry[3] == 0x9a)
3356 { // we have to get rid of the metafileheader
3357 rpGraphicAry += 22;
3358 rSize -= 22;
3359 return true;
3362 return false;
3365 OString RtfAttributeOutput::WriteHex(const sal_uInt8* pData, sal_uInt32 nSize, SvStream* pStream, sal_uInt32 nLimit)
3367 OStringBuffer aRet;
3369 sal_uInt32 nBreak = 0;
3370 for (sal_uInt32 i = 0; i < nSize; i++)
3372 OString sNo = OString::valueOf(sal_Int32(pData[i]), 16);
3373 if (sNo.getLength() < 2)
3375 if (pStream)
3376 (*pStream) << '0';
3377 else
3378 aRet.append('0');
3380 if (pStream)
3381 (*pStream) << sNo.getStr();
3382 else
3383 aRet.append(sNo);
3384 if (++nBreak == nLimit)
3386 if (pStream)
3387 (*pStream) << RtfExport::sNewLine;
3388 else
3389 aRet.append(RtfExport::sNewLine);
3390 nBreak = 0;
3394 return aRet.makeStringAndClear();
3397 static void lcl_AppendSP( OStringBuffer& rBuffer,
3398 const char cName[],
3399 const OUString& rValue,
3400 const RtfExport& rExport )
3402 rBuffer.append( "{" OOO_STRING_SVTOOLS_RTF_SP "{" ); // "{\sp{"
3403 rBuffer.append( OOO_STRING_SVTOOLS_RTF_SN " " );//" \sn "
3404 rBuffer.append( cName ); //"PropName"
3405 rBuffer.append( "}{" OOO_STRING_SVTOOLS_RTF_SV " " );
3406 // "}{ \sv "
3407 rBuffer.append( msfilter::rtfutil::OutString( rValue, rExport.eCurrentEncoding ) );
3408 rBuffer.append( "}}" );
3411 static OString ExportPICT( const SwFlyFrmFmt* pFlyFrmFmt, const Size &rOrig, const Size &rRendered, const Size &rMapped,
3412 const SwCropGrf &rCr, const char *pBLIPType, const sal_uInt8 *pGraphicAry,
3413 unsigned long nSize, const RtfExport& rExport, SvStream *pStream = 0 )
3415 OStringBuffer aRet;
3416 bool bIsWMF = std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
3417 if (pBLIPType && nSize && pGraphicAry)
3419 aRet.append("{" OOO_STRING_SVTOOLS_RTF_PICT);
3421 if( pFlyFrmFmt )
3423 String sDescription = pFlyFrmFmt->GetObjDescription();
3424 //write picture properties - wzDescription at first
3425 //looks like: "{\*\picprop{\sp{\sn PropertyName}{\sv PropertyValue}}}"
3426 aRet.append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_PICPROP );//"{\*\picprop
3427 lcl_AppendSP( aRet, "wzDescription", sDescription, rExport );
3428 String sName = pFlyFrmFmt->GetObjTitle();
3429 lcl_AppendSP( aRet, "wzName", sName, rExport );
3430 aRet.append( "}" ); //"}"
3433 long nXCroppedSize = rOrig.Width()-(rCr.GetLeft() + rCr.GetRight());
3434 long nYCroppedSize = rOrig.Height()-(rCr.GetTop() + rCr.GetBottom());
3435 /* Graphic with a zero height or width, typically copied from webpages, caused crashes. */
3436 if( !nXCroppedSize )
3437 nXCroppedSize = 100;
3438 if( !nYCroppedSize )
3439 nYCroppedSize = 100;
3441 //Given the original size and taking cropping into account
3442 //first, how much has the original been scaled to get the
3443 //final rendered size
3444 aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEX);
3445 aRet.append((sal_Int32)((100 * rRendered.Width()) / nXCroppedSize));
3446 aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEY);
3447 aRet.append((sal_Int32)((100 * rRendered.Height()) / nYCroppedSize));
3449 aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPL);
3450 aRet.append((sal_Int32)rCr.GetLeft());
3451 aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPR);
3452 aRet.append((sal_Int32)rCr.GetRight());
3453 aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPT);
3454 aRet.append((sal_Int32)rCr.GetTop());
3455 aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPB);
3456 aRet.append((sal_Int32)rCr.GetBottom());
3458 aRet.append(OOO_STRING_SVTOOLS_RTF_PICW);
3459 aRet.append((sal_Int32)rMapped.Width());
3460 aRet.append(OOO_STRING_SVTOOLS_RTF_PICH);
3461 aRet.append((sal_Int32)rMapped.Height());
3463 aRet.append(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
3464 aRet.append((sal_Int32)rOrig.Width());
3465 aRet.append(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
3466 aRet.append((sal_Int32)rOrig.Height());
3468 aRet.append(pBLIPType);
3469 if (bIsWMF)
3471 aRet.append((sal_Int32)8);
3472 StripMetafileHeader(pGraphicAry, nSize);
3474 aRet.append(RtfExport::sNewLine);
3475 if (pStream)
3476 (*pStream) << aRet.makeStringAndClear().getStr();
3477 if (pStream)
3478 RtfAttributeOutput::WriteHex(pGraphicAry, nSize, pStream);
3479 else
3480 aRet.append(RtfAttributeOutput::WriteHex(pGraphicAry, nSize));
3481 aRet.append('}');
3482 if (pStream)
3483 (*pStream) << aRet.makeStringAndClear().getStr();
3485 return aRet.makeStringAndClear();
3488 void RtfAttributeOutput::FlyFrameOLEReplacement(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
3490 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
3491 Size aSize(sw::util::GetSwappedInSize(rOLENode));
3492 Size aRendered(aSize);
3493 aRendered.Width() = rSize.Width();
3494 aRendered.Height() = rSize.Height();
3495 const Graphic* pGraphic = rOLENode.GetGraphic();
3496 Size aMapped(pGraphic->GetPrefSize());
3497 const SwCropGrf &rCr = (const SwCropGrf &)rOLENode.GetAttr(RES_GRFATR_CROPGRF);
3498 const sal_Char* pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3499 const sal_uInt8* pGraphicAry = 0;
3500 SvMemoryStream aStream;
3501 if (GraphicConverter::Export(aStream, *pGraphic, CVT_PNG) != ERRCODE_NONE)
3502 OSL_FAIL("failed to export the graphic");
3503 aStream.Seek(STREAM_SEEK_TO_END);
3504 sal_uInt32 nSize = aStream.Tell();
3505 pGraphicAry = (sal_uInt8*)aStream.GetData();
3506 m_aRunText->append(ExportPICT( pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport ));
3507 m_aRunText->append("}"); // shppict
3508 m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT);
3509 pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3510 SvMemoryStream aWmfStream;
3511 if (GraphicConverter::Export(aWmfStream, *pGraphic, CVT_WMF) != ERRCODE_NONE)
3512 OSL_FAIL("failed to export the graphic");
3513 aWmfStream.Seek(STREAM_SEEK_TO_END);
3514 nSize = aWmfStream.Tell();
3515 pGraphicAry = (sal_uInt8*)aWmfStream.GetData();
3516 m_aRunText->append(ExportPICT( pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport ));
3517 m_aRunText->append("}"); // nonshppict
3520 bool RtfAttributeOutput::FlyFrameOLEMath(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
3522 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3524 uno::Reference <embed::XEmbeddedObject> xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
3525 sal_Int64 nAspect = rOLENode.GetAspect();
3526 svt::EmbeddedObjectRef aObjRef(xObj, nAspect);
3527 SvGlobalName aObjName(aObjRef->getClassID());
3529 if (!SotExchange::IsMath(aObjName))
3530 return false;
3532 m_aRunText->append("{" LO_STRING_SVTOOLS_RTF_MMATH " ");
3533 uno::Reference<util::XCloseable> xClosable(xObj->getComponent(), uno::UNO_QUERY);
3534 // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
3535 // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
3536 // to RTLD_GLOBAL, so most probably a gcc bug.
3537 oox::FormulaExportBase* pBase = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xClosable.get()));
3538 assert( pBase != NULL );
3539 OStringBuffer aBuf;
3540 pBase->writeFormulaRtf(aBuf, m_rExport.eCurrentEncoding);
3541 m_aRunText->append(aBuf.makeStringAndClear());
3542 // Replacement graphic.
3543 m_aRunText->append("{" LO_STRING_SVTOOLS_RTF_MMATHPICT " ");
3544 FlyFrameOLEReplacement(pFlyFrmFmt, rOLENode, rSize);
3545 m_aRunText->append("}"); // mmathPict
3546 m_aRunText->append("}"); // mmath
3548 return true;
3551 void RtfAttributeOutput::FlyFrameOLE( const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize )
3553 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3555 if (FlyFrameOLEMath(pFlyFrmFmt, rOLENode, rSize))
3556 return;
3558 FlyFrameOLEReplacement(pFlyFrmFmt, rOLENode, rSize);
3561 void RtfAttributeOutput::FlyFrameGraphic( const SwFlyFrmFmt* pFlyFrmFmt, const SwGrfNode* pGrfNode)
3563 SAL_INFO("sw.rtf", OSL_THIS_FUNC);
3565 SvMemoryStream aStream;
3566 const sal_uInt8* pGraphicAry = 0;
3567 sal_uInt32 nSize = 0;
3569 Graphic aGraphic(pGrfNode->GetGrf());
3571 // If there is no graphic there is not much point in parsing it
3572 if(aGraphic.GetType()==GRAPHIC_NONE)
3573 return;
3575 GfxLink aGraphicLink;
3576 const sal_Char* pBLIPType = 0;
3577 if (aGraphic.IsLink())
3579 aGraphicLink = aGraphic.GetLink();
3580 nSize = aGraphicLink.GetDataSize();
3581 pGraphicAry = aGraphicLink.GetData();
3582 switch (aGraphicLink.GetType())
3584 case GFX_LINK_TYPE_NATIVE_JPG:
3585 pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
3586 break;
3587 case GFX_LINK_TYPE_NATIVE_PNG:
3588 pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3589 break;
3590 case GFX_LINK_TYPE_NATIVE_WMF:
3591 pBLIPType =
3592 IsEMF(pGraphicAry, nSize) ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3593 break;
3594 default:
3595 break;
3599 GraphicType eGraphicType = aGraphic.GetType();
3600 if (!pGraphicAry)
3602 if (ERRCODE_NONE == GraphicConverter::Export(aStream, aGraphic,
3603 (eGraphicType == GRAPHIC_BITMAP) ? CVT_PNG : CVT_WMF))
3605 pBLIPType = (eGraphicType == GRAPHIC_BITMAP) ?
3606 OOO_STRING_SVTOOLS_RTF_PNGBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3607 aStream.Seek(STREAM_SEEK_TO_END);
3608 nSize = aStream.Tell();
3609 pGraphicAry = (sal_uInt8*)aStream.GetData();
3613 Size aMapped(eGraphicType == GRAPHIC_BITMAP ? aGraphic.GetSizePixel() : aGraphic.GetPrefSize());
3615 const SwCropGrf &rCr = (const SwCropGrf &)pGrfNode->GetAttr(RES_GRFATR_CROPGRF);
3617 //Get original size in twips
3618 Size aSize(sw::util::GetSwappedInSize(*pGrfNode));
3619 Size aRendered(aSize);
3620 if (pFlyFrmFmt)
3622 const SwFmtFrmSize& rS = pFlyFrmFmt->GetFrmSize();
3623 aRendered.Width() = rS.GetWidth();
3624 aRendered.Height() = rS.GetHeight();
3628 If the graphic is not of type WMF then we will have to store two
3629 graphics, one in the native format wrapped in shppict, and the other in
3630 the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
3631 a wmf already then we don't need any such wrapping
3633 bool bIsWMF = pBLIPType && std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
3634 if (!bIsWMF)
3635 m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT;
3637 if (pBLIPType)
3638 ExportPICT( pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm() );
3639 else
3641 aStream.Seek(0);
3642 GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
3643 pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3644 aStream.Seek(STREAM_SEEK_TO_END);
3645 nSize = aStream.Tell();
3646 pGraphicAry = (sal_uInt8*)aStream.GetData();
3648 ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm() );
3651 if (!bIsWMF)
3653 m_rExport.Strm() << "}" "{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT;
3655 aStream.Seek(0);
3656 GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
3657 pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3658 aStream.Seek(STREAM_SEEK_TO_END);
3659 nSize = aStream.Tell();
3660 pGraphicAry = (sal_uInt8*)aStream.GetData();
3662 ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm() );
3664 m_rExport.Strm() << '}';
3667 m_rExport.Strm() << m_rExport.sNewLine;
3670 void RtfAttributeOutput::BulletDefinition(int /*nId*/, const Graphic& rGraphic, Size aSize)
3672 m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT;
3673 m_rExport.Strm() << "{" OOO_STRING_SVTOOLS_RTF_PICT OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3675 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_PICWGOAL;
3676 m_rExport.OutULong(aSize.Width());
3677 m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_PICHGOAL;
3678 m_rExport.OutULong(aSize.Height());
3680 m_rExport.Strm() << RtfExport::sNewLine;
3681 const sal_uInt8* pGraphicAry = 0;
3682 SvMemoryStream aStream;
3683 if (GraphicConverter::Export(aStream, rGraphic, CVT_PNG) != ERRCODE_NONE)
3684 SAL_WARN("sw.rtf", "failed to export the numbering picture bullet");
3685 aStream.Seek(STREAM_SEEK_TO_END);
3686 sal_uInt32 nSize = aStream.Tell();
3687 pGraphicAry = (sal_uInt8*)aStream.GetData();
3688 RtfAttributeOutput::WriteHex(pGraphicAry, nSize, &m_rExport.Strm());
3689 m_rExport.Strm() << "}}"; // pict, shppict
3692 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */