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