LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - rtfexport.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 477 592 80.6 %
Date: 2014-04-11 Functions: 46 60 76.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_version.h>
      21             : #include "rtfexportfilter.hxx"
      22             : #include "rtfsdrexport.hxx"
      23             : #include "rtfattributeoutput.hxx"
      24             : 
      25             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      26             : #include <com/sun/star/i18n/ScriptType.hpp>
      27             : 
      28             : #include <docsh.hxx>
      29             : #include <viewsh.hxx>
      30             : #include <viewopt.hxx>
      31             : #include <ndtxt.hxx>
      32             : #include <fmtpdsc.hxx>
      33             : #include <section.hxx>
      34             : #include <pagedesc.hxx>
      35             : #include <swtable.hxx>
      36             : #include <frmatr.hxx>
      37             : #include <ftninfo.hxx>
      38             : #include <fmthdft.hxx>
      39             : #include <editeng/colritem.hxx>
      40             : #include <editeng/udlnitem.hxx>
      41             : #include <editeng/boxitem.hxx>
      42             : #include <editeng/brushitem.hxx>
      43             : #include <editeng/shaditem.hxx>
      44             : #include <editeng/ulspitem.hxx>
      45             : #include <editeng/paperinf.hxx>
      46             : #include <editeng/protitem.hxx>
      47             : 
      48             : #include <docary.hxx>
      49             : #include <numrule.hxx>
      50             : #include <lineinfo.hxx>
      51             : #include <swmodule.hxx>
      52             : 
      53             : #include "ww8par.hxx"
      54             : 
      55             : #include <comphelper/string.hxx>
      56             : #include <rtl/ustring.hxx>
      57             : #include <svtools/rtfkeywd.hxx>
      58             : #include <filter/msfilter/rtfutil.hxx>
      59             : #include <unotools/configmgr.hxx>
      60             : #include <vcl/svapp.hxx>
      61             : 
      62             : #if OSL_DEBUG_LEVEL > 1
      63             : #include <iostream>
      64             : #endif
      65             : 
      66             : using ::editeng::SvxBorderLine;
      67             : using namespace ::comphelper;
      68             : using namespace ::com::sun::star;
      69             : 
      70             : using sw::mark::IMark;
      71             : 
      72             : // the default text encoding for the export, if it doesn't fit unicode will
      73             : // be used
      74             : #define DEF_ENCODING            RTL_TEXTENCODING_ASCII_US
      75             : 
      76       20572 : AttributeOutputBase& RtfExport::AttrOutput() const
      77             : {
      78       20572 :     return *m_pAttrOutput;
      79             : }
      80             : 
      81          16 : MSWordSections& RtfExport::Sections() const
      82             : {
      83          16 :     return *m_pSections;
      84             : }
      85             : 
      86           5 : RtfSdrExport& RtfExport::SdrExporter() const
      87             : {
      88           5 :     return *m_pSdrExport;
      89             : }
      90             : 
      91        4076 : bool RtfExport::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
      92             : {
      93             :     // FIXME is this actually true for rtf? - this is copied from DOCX
      94        4076 :     if ( nScript == i18n::ScriptType::ASIAN )
      95             :     {
      96             :         // for asian in ww8, there is only one fontsize
      97             :         // and one fontstyle (posture/weight)
      98           0 :         switch ( nWhich )
      99             :         {
     100             :             case RES_CHRATR_FONTSIZE:
     101             :             case RES_CHRATR_POSTURE:
     102             :             case RES_CHRATR_WEIGHT:
     103           0 :                 return false;
     104             :             default:
     105           0 :                 break;
     106             :         }
     107             :     }
     108        4076 :     else if ( nScript != i18n::ScriptType::COMPLEX )
     109             :     {
     110             :         // for western in ww8, there is only one fontsize
     111             :         // and one fontstyle (posture/weight)
     112        4076 :         switch ( nWhich )
     113             :         {
     114             :             case RES_CHRATR_CJK_FONTSIZE:
     115             :             case RES_CHRATR_CJK_POSTURE:
     116             :             case RES_CHRATR_CJK_WEIGHT:
     117         891 :                 return false;
     118             :             default:
     119        3185 :                 break;
     120             :         }
     121             :     }
     122        3185 :     return true;
     123             : }
     124             : 
     125        1118 : void RtfExport::AppendBookmarks( const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen )
     126             : {
     127             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     128             : 
     129        1118 :     std::vector< OUString > aStarts;
     130        2236 :     std::vector< OUString > aEnds;
     131             : 
     132        2236 :     IMarkVector aMarks;
     133        1118 :     if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
     134             :     {
     135           4 :         for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
     136             :                 it != end; ++it )
     137             :         {
     138           2 :             IMark* pMark = (*it);
     139           2 :             const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
     140           2 :             const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
     141             : 
     142           2 :             if ( nStart == nAktPos )
     143           1 :                 aStarts.push_back( pMark->GetName() );
     144             : 
     145           2 :             if ( nEnd == nAktPos )
     146           1 :                 aEnds.push_back( pMark->GetName() );
     147             :         }
     148             :     }
     149             : 
     150        2236 :     m_pAttrOutput->WriteBookmarks_Impl( aStarts, aEnds );
     151        1118 : }
     152             : 
     153           0 : void RtfExport::AppendBookmark( const OUString& rName, bool /*bSkip*/ )
     154             : {
     155             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     156             : 
     157           0 :     std::vector<OUString> aStarts;
     158           0 :     std::vector<OUString> aEnds;
     159             : 
     160           0 :     aStarts.push_back(rName);
     161           0 :     aEnds.push_back(rName);
     162             : 
     163           0 :     m_pAttrOutput->WriteBookmarks_Impl(aStarts, aEnds);
     164           0 : }
     165             : 
     166        1118 : void RtfExport::AppendAnnotationMarks( const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen )
     167             : {
     168             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     169             : 
     170        1118 :     std::vector< OUString > aStarts;
     171        2236 :     std::vector< OUString > aEnds;
     172             : 
     173        2236 :     IMarkVector aMarks;
     174        1118 :     if ( GetAnnotationMarks( rNode, nAktPos, nAktPos + nLen, aMarks ) )
     175             :     {
     176          23 :         for ( IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end();
     177             :                 it != end; ++it )
     178             :         {
     179          12 :             IMark* pMark = (*it);
     180          12 :             const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
     181          12 :             const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
     182             : 
     183          12 :             if ( nStart == nAktPos )
     184           3 :                 aStarts.push_back( pMark->GetName() );
     185             : 
     186          12 :             if ( nEnd == nAktPos )
     187           3 :                 aEnds.push_back( pMark->GetName() );
     188             :         }
     189             :     }
     190             : 
     191        2236 :     m_pAttrOutput->WriteAnnotationMarks_Impl( aStarts, aEnds );
     192        1118 : }
     193             : 
     194             : //For i120928,to export graphic of bullet for RTF filter
     195          56 : void RtfExport::ExportGrfBullet(const SwTxtNode&)
     196             : {
     197             :     // Noop, would be too late, see WriteNumbering() instead.
     198          56 : }
     199             : 
     200           0 : void RtfExport::WriteChar( sal_Unicode )
     201             : {
     202             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     203             : 
     204             :     /* WriteChar() has nothing to do for rtf. */
     205           0 : }
     206             : 
     207          63 : static bool IsExportNumRule( const SwNumRule& rRule, sal_uInt8* pEnd = 0 )
     208             : {
     209          63 :     sal_uInt8 nEnd = MAXLEVEL;
     210          63 :     while( nEnd-- && !rRule.GetNumFmt( nEnd ))
     211             :         ;
     212          63 :     ++nEnd;
     213             : 
     214             :     const SwNumFmt* pNFmt;
     215             :     sal_uInt8 nLvl;
     216             : 
     217         203 :     for( nLvl = 0; nLvl < nEnd; ++nLvl )
     218         580 :         if( SVX_NUM_NUMBER_NONE != ( pNFmt = &rRule.Get( nLvl ))
     219         435 :                 ->GetNumberingType() || !pNFmt->GetPrefix().isEmpty() ||
     220         285 :                 (!pNFmt->GetSuffix().isEmpty() && !pNFmt->GetSuffix().equals(".")) )
     221           5 :             break;
     222             : 
     223          63 :     if( pEnd )
     224           0 :         *pEnd = nEnd;
     225          63 :     return nLvl != nEnd;
     226             : }
     227             : 
     228          56 : void RtfExport::BuildNumbering()
     229             : {
     230          56 :     const SwNumRuleTbl& rListTbl = pDoc->GetNumRuleTbl();
     231             : 
     232         239 :     for( sal_uInt16 n = rListTbl.size()+1; n; )
     233             :     {
     234             :         SwNumRule* pRule;
     235         127 :         --n;
     236         127 :         if( n == rListTbl.size() )
     237          56 :             pRule = (SwNumRule*)pDoc->GetOutlineNumRule();
     238             :         else
     239             :         {
     240          71 :             pRule = rListTbl[ n ];
     241          71 :             if( !pDoc->IsUsed( *pRule ))
     242          64 :                 continue;
     243             :         }
     244             : 
     245          63 :         if( IsExportNumRule( *pRule ))
     246           5 :             GetId( *pRule );
     247             :     }
     248          56 : }
     249             : 
     250          56 : void RtfExport::WriteNumbering()
     251             : {
     252             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
     253             : 
     254          56 :     if ( !pUsedNumTbl )
     255         108 :         return; // no numbering is used
     256             : 
     257           4 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LISTTABLE );
     258             : 
     259           4 :     CollectGrfsOfBullets();
     260           4 :     if (!m_vecBulletPic.empty())
     261           1 :         Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( LO_STRING_SVTOOLS_RTF_LISTPICTURE );
     262           4 :     BulletDefinitions();
     263           4 :     if (!m_vecBulletPic.empty())
     264           1 :         Strm().WriteChar( '}' );
     265             : 
     266           4 :     AbstractNumberingDefinitions();
     267           4 :     Strm().WriteChar( '}' );
     268             : 
     269           4 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LISTOVERRIDETABLE );
     270           4 :     NumberingDefinitions();
     271           4 :     Strm().WriteChar( '}' );
     272             : 
     273             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
     274             : }
     275             : 
     276          56 : void RtfExport::WriteRevTab()
     277             : {
     278             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     279             : 
     280          56 :     int nRevAuthors = pDoc->GetRedlineTbl().size();
     281             : 
     282          56 :     if (nRevAuthors < 1)
     283         112 :         return;
     284             : 
     285             :     // RTF always seems to use Unknown as the default first entry
     286           0 :     GetRedline(OUString("Unknown"));
     287             : 
     288           0 :     for( sal_uInt16 i = 0; i < pDoc->GetRedlineTbl().size(); ++i )
     289             :     {
     290           0 :         const SwRangeRedline* pRedl = pDoc->GetRedlineTbl()[ i ];
     291             : 
     292           0 :         GetRedline(SW_MOD()->GetRedlineAuthor(pRedl->GetAuthor()));
     293             :     }
     294             : 
     295             :     // Now write the table
     296           0 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_REVTBL ).WriteChar( ' ' );
     297           0 :     for(sal_uInt16 i = 0; i < m_aRedlineTbl.size(); ++i)
     298             :     {
     299           0 :         const OUString* pAuthor = GetRedline(i);
     300           0 :         Strm().WriteChar( '{' );
     301           0 :         if (pAuthor)
     302           0 :             Strm().WriteCharPtr( msfilter::rtfutil::OutString(*pAuthor, eDefaultEncoding).getStr() );
     303           0 :         Strm().WriteCharPtr( ";}" );
     304             :     }
     305           0 :     Strm().WriteChar( '}' ).WriteCharPtr( SAL_NEWLINE_STRING );
     306             : }
     307             : 
     308           5 : void RtfExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
     309             :         const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, sal_uInt8 /*nBreakCode*/ )
     310             : {
     311             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     312             : 
     313             :     // headers
     314           5 :     if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_EVEN )
     315           0 :         WriteHeaderFooter( rLeftFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERL );
     316             : 
     317           5 :     if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_ODD )
     318           3 :         WriteHeaderFooter( rFmt, true, OOO_STRING_SVTOOLS_RTF_HEADER );
     319             : 
     320           5 :     if ( nHeadFootFlags & nsHdFtFlags::WW8_HEADER_FIRST )
     321           0 :         WriteHeaderFooter( rFirstPageFmt, true, OOO_STRING_SVTOOLS_RTF_HEADERF, true );
     322             : 
     323             :     // footers
     324           5 :     if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_EVEN )
     325           0 :         WriteHeaderFooter( rLeftFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERL );
     326             : 
     327           5 :     if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_ODD )
     328           3 :         WriteHeaderFooter( rFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTER );
     329             : 
     330           5 :     if ( nHeadFootFlags & nsHdFtFlags::WW8_FOOTER_FIRST )
     331           0 :         WriteHeaderFooter( rFirstPageFmt, false, OOO_STRING_SVTOOLS_RTF_FOOTERF, true );
     332           5 : }
     333             : 
     334          20 : void RtfExport::OutputField( const SwField* pFld, ww::eField eFldType, const OUString& rFldCmd, sal_uInt8 nMode )
     335             : {
     336             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     337             : 
     338          20 :     m_pAttrOutput->WriteField_Impl( pFld, eFldType, rFldCmd, nMode );
     339          20 : }
     340             : 
     341           0 : void RtfExport::WriteFormData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
     342             : {
     343             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
     344           0 : }
     345             : 
     346           0 : void RtfExport::WriteHyperlinkData( const ::sw::mark::IFieldmark& /*rFieldmark*/ )
     347             : {
     348             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
     349           0 : }
     350             : 
     351           0 : void RtfExport::DoComboBox(const OUString& /*rName*/,
     352             :                              const OUString& /*rHelp*/,
     353             :                              const OUString& /*rToolTip*/,
     354             :                              const OUString& /*rSelected*/,
     355             :                              uno::Sequence<OUString>& /*rListItems*/)
     356             : {
     357             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     358             : 
     359             :     // this is handled in RtfAttributeOutput::OutputFlyFrame_Impl
     360           0 : }
     361             : 
     362           0 : void RtfExport::DoFormText(const SwInputField* pFld )
     363             : {
     364             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     365             : 
     366           0 :     OUString sResult = pFld->ExpandField(true);
     367           0 :     OUString sHelp( pFld->GetHelp() );
     368           0 :     OUString sName = pFld->GetPar2();
     369           0 :     OUString sStatus = pFld->GetToolTip();
     370           0 :     m_pAttrOutput->RunText().append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST "{ FORMTEXT }");
     371           0 :     m_pAttrOutput->RunText().append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD " {" OOO_STRING_SVTOOLS_RTF_FFTYPE "0" );
     372           0 :     if( !sHelp.isEmpty() )
     373           0 :         m_pAttrOutput->RunText().append( OOO_STRING_SVTOOLS_RTF_FFOWNHELP );
     374           0 :     if( !sStatus.isEmpty() )
     375           0 :         m_pAttrOutput->RunText().append( OOO_STRING_SVTOOLS_RTF_FFOWNSTAT );
     376           0 :     m_pAttrOutput->RunText().append( OOO_STRING_SVTOOLS_RTF_FFTYPETXT  "0" );
     377             : 
     378           0 :     if( !sName.isEmpty() )
     379           0 :         m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ").append( msfilter::rtfutil::OutString( sName, eDefaultEncoding )).append( "}" );
     380           0 :     if( !sHelp.isEmpty() )
     381           0 :         m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ").append( msfilter::rtfutil::OutString( sHelp, eDefaultEncoding )).append( "}" );
     382           0 :     m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFDEFTEXT " ").append( msfilter::rtfutil::OutString( sResult, eDefaultEncoding )).append( "}" );
     383           0 :     if( !sStatus.isEmpty() )
     384           0 :         m_pAttrOutput->RunText().append( "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ").append( msfilter::rtfutil::OutString( sStatus, eDefaultEncoding )).append( "}");
     385           0 :     m_pAttrOutput->RunText().append( "}}}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " " );
     386           0 :     m_pAttrOutput->RunText().append( msfilter::rtfutil::OutString( sResult, eDefaultEncoding )).append( "}}" );
     387           0 : }
     388             : 
     389           0 : sal_uLong RtfExport::ReplaceCr( sal_uInt8 )
     390             : {
     391             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     392             : 
     393             :     // Completely unused for Rtf export... only here for code sharing
     394             :     // purpose with binary export
     395             : 
     396           0 :     return 0;
     397             : }
     398             : 
     399          56 : void RtfExport::WriteFonts()
     400             : {
     401          56 :     Strm().WriteCharPtr( SAL_NEWLINE_STRING ).WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FONTTBL );
     402          56 :     maFontHelper.WriteFontTable( *m_pAttrOutput );
     403          56 :     Strm().WriteChar( '}' );
     404          56 : }
     405             : 
     406          56 : void RtfExport::WriteStyles()
     407             : {
     408             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
     409          56 :     pStyles->OutputStylesTable();
     410             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
     411          56 : }
     412             : 
     413          56 : void RtfExport::WriteFootnoteSettings()
     414             : {
     415          56 :     const SwPageFtnInfo& rFtnInfo = pDoc->GetPageDesc(0).GetFtnInfo();
     416             :     // Request a separator only in case the width is larger than zero.
     417          56 :     bool bSeparator = double(rFtnInfo.GetWidth()) > 0;
     418             : 
     419          56 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FTNSEP );
     420          56 :     if (bSeparator)
     421          14 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CHFTNSEP );
     422          56 :     Strm().WriteChar( '}' );
     423          56 : }
     424             : 
     425          56 : void RtfExport::WriteMainText()
     426             : {
     427             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
     428             : 
     429          56 :     SwTableNode* pTableNode = pCurPam->GetNode()->FindTableNode();
     430          56 :     if ( m_pWriter && m_pWriter->bWriteOnlyFirstTable
     431           0 :          && pTableNode != 0 )
     432             :     {
     433           0 :         pCurPam->GetPoint()->nNode = *pTableNode;
     434           0 :         pCurPam->GetMark()->nNode = *(pTableNode->EndOfSectionNode());
     435             :     }
     436             :     else
     437             :     {
     438          56 :         pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
     439             :     }
     440             : 
     441          56 :     WriteText();
     442             : 
     443             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
     444          56 : }
     445             : 
     446          56 : void RtfExport::WriteInfo()
     447             : {
     448             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     449          56 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_INFO );
     450             : 
     451          56 :     SwDocShell *pDocShell(pDoc->GetDocShell());
     452          56 :     uno::Reference<document::XDocumentProperties> xDocProps;
     453          56 :     if (pDocShell) {
     454             :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
     455          55 :                 pDocShell->GetModel(), uno::UNO_QUERY);
     456          55 :         xDocProps.set(xDPS->getDocumentProperties());
     457             :     }
     458             : 
     459          56 :     if (xDocProps.is()) {
     460          55 :         OutUnicode(OOO_STRING_SVTOOLS_RTF_TITLE, xDocProps->getTitle(), true);
     461          55 :         OutUnicode(OOO_STRING_SVTOOLS_RTF_SUBJECT, xDocProps->getSubject());
     462             : 
     463             :         OutUnicode(OOO_STRING_SVTOOLS_RTF_KEYWORDS,
     464          55 :                 ::comphelper::string::convertCommaSeparated(xDocProps->getKeywords()));
     465          55 :         OutUnicode(OOO_STRING_SVTOOLS_RTF_DOCCOMM, xDocProps->getDescription());
     466             : 
     467          55 :         OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR, xDocProps->getAuthor());
     468          55 :         OutDateTime(OOO_STRING_SVTOOLS_RTF_CREATIM, xDocProps->getCreationDate());
     469             : 
     470          55 :         OutUnicode(OOO_STRING_SVTOOLS_RTF_AUTHOR,xDocProps->getModifiedBy());
     471          55 :         OutDateTime(OOO_STRING_SVTOOLS_RTF_REVTIM, xDocProps->getModificationDate());
     472             : 
     473          55 :         OutDateTime(OOO_STRING_SVTOOLS_RTF_PRINTIM, xDocProps->getPrintDate());
     474             :     }
     475             : 
     476          56 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_COMMENT ).WriteCharPtr( " " );
     477          56 :     Strm().WriteCharPtr( OUStringToOString( utl::ConfigManager::getProductName(), eCurrentEncoding).getStr() ).WriteCharPtr( "}{" ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_VERN );
     478             : 
     479             : // The convention that we follow is that the version number
     480             : // should be a non-negative 32-bit int
     481             : #if LIBO_VERSION_MAJOR > 127
     482             : #error Major version number must be less than 128
     483             : #elif LIBO_VERSION_MINOR > 255 || LIBO_VERSION_MICRO > 255 || LIBO_VERSION_PATCH > 255
     484             : #error Minor, micro and patchlevel version numbers must be less than 256
     485             : #endif
     486             : 
     487          56 :     Strm().WriteNumber((sal_Int32) LIBO_VERSION_ENCODED_IN_32BITS).WriteChar( '}' );
     488          56 :     Strm().WriteChar( '}' );
     489          56 : }
     490             : 
     491          56 : void RtfExport::WritePageDescTable()
     492             : {
     493             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     494             : 
     495             :     // Write page descriptions (page styles)
     496          56 :     sal_uInt16 nSize = pDoc->GetPageDescCnt();
     497          56 :     if( !nSize )
     498          56 :         return;
     499             : 
     500          56 :     Strm().WriteCharPtr( SAL_NEWLINE_STRING );
     501          56 :     bOutPageDescs = true;
     502          56 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCTBL );
     503         128 :     for( sal_uInt16 n = 0; n < nSize; ++n )
     504             :     {
     505          72 :         const SwPageDesc& rPageDesc = pDoc->GetPageDesc( n );
     506             : 
     507          72 :         Strm().WriteCharPtr( SAL_NEWLINE_STRING ).WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSC );
     508          72 :         OutULong( n ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCUSE );
     509          72 :         OutULong( rPageDesc.ReadUseOn() );
     510             : 
     511          72 :         OutPageDescription( rPageDesc, false, false );
     512             : 
     513             :         // search for the next page description
     514          72 :         sal_uInt16 i = nSize;
     515         197 :         while( i  )
     516         125 :             if( rPageDesc.GetFollow() == &pDoc->GetPageDesc( --i ) )
     517          72 :                 break;
     518          72 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCNXT );
     519          72 :         OutULong( i ).WriteChar( ' ' );
     520          72 :         Strm().WriteCharPtr( msfilter::rtfutil::OutString( rPageDesc.GetName(), eDefaultEncoding).getStr() ).WriteCharPtr( ";}" );
     521             :     }
     522          56 :     Strm().WriteChar( '}' ).WriteCharPtr( SAL_NEWLINE_STRING );
     523          56 :     bOutPageDescs = false;
     524             : 
     525             :     // reset table infos, otherwise the depth of the cells will be incorrect,
     526             :     // in case the page style (header or footer) had tables
     527          56 :     mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
     528             : }
     529             : 
     530          56 : void RtfExport::ExportDocument_Impl()
     531             : {
     532             :     // Make the header
     533          56 :     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RTF ).WriteChar( '1' )
     534          56 :        .WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ANSI );
     535          56 :     Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_DEFF );
     536          56 :     OutULong( maFontHelper.GetId( (SvxFontItem&)pDoc->GetAttrPool().GetDefaultItem(
     537          56 :                     RES_CHRATR_FONT ) ));
     538             :     // If this not exist, MS don't understand our ansi characters (0x80-0xff).
     539          56 :     Strm().WriteCharPtr( "\\adeflang1025" );
     540             : 
     541             :     // Font table
     542          56 :     WriteFonts();
     543             : 
     544          56 :     pStyles = new MSWordStyles( *this );
     545             :     // Color and stylesheet table
     546          56 :     WriteStyles();
     547             : 
     548             :     // List table
     549          56 :     BuildNumbering();
     550          56 :     WriteNumbering();
     551             : 
     552          56 :     WriteRevTab();
     553             : 
     554          56 :     WriteInfo();
     555             :     // Default TabSize
     556          56 :     Strm().WriteCharPtr( m_pAttrOutput->m_aTabStop.makeStringAndClear().getStr() ).WriteCharPtr( SAL_NEWLINE_STRING );
     557             :     // Zoom
     558          56 :     SwViewShell *pViewShell(pDoc->GetCurrentViewShell());
     559          56 :     if (pViewShell && pViewShell->GetViewOptions()->GetZoomType() == SVX_ZOOM_PERCENT)
     560             :     {
     561          50 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_VIEWSCALE );
     562          50 :         OutULong(pViewShell->GetViewOptions()->GetZoom());
     563             :     }
     564             :     // Record changes?
     565          56 :     if (nsRedlineMode_t::REDLINE_ON & mnRedlineMode)
     566           1 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_REVISIONS );
     567             :     // Init sections
     568          56 :     m_pSections = new MSWordSections( *this );
     569             : 
     570             :     // Page description
     571          56 :     WritePageDescTable();
     572             : 
     573             :     // Enable form protection by default if needed, as there is no switch to
     574             :     // enable it on a per-section basis. OTOH don't always enable it as it
     575             :     // breaks moving of drawings - so write it only in case there is really a
     576             :     // protected section in the document.
     577             :     {
     578          56 :         const SfxItemPool& rPool = pDoc->GetAttrPool();
     579          56 :         sal_uInt32 const nMaxItem = rPool.GetItemCount2(RES_PROTECT);
     580          56 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
     581             :         {
     582           1 :             const SvxProtectItem* pProtect = (const SvxProtectItem*)rPool.GetItem2(RES_PROTECT, n);
     583           1 :             if (pProtect && pProtect->IsCntntProtected())
     584             :             {
     585           1 :                 Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FORMPROT );
     586           1 :                 break;
     587             :             }
     588             :         }
     589             :     }
     590             : 
     591             :     // enable form field shading
     592          56 :     Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FORMSHADE );
     593             : 
     594             :     // size and empty margins of the page
     595          56 :     if( pDoc->GetPageDescCnt() )
     596             :     {
     597             :         // Seeking the first SwFmtPageDesc. If no set, the default is valid
     598          56 :         const SwFmtPageDesc* pSttPgDsc = 0;
     599             :         {
     600          56 :             const SwNode& rSttNd = *pDoc->GetNodes()[
     601         112 :                         pDoc->GetNodes().GetEndOfExtras().GetIndex() + 2 ];
     602          56 :             const SfxItemSet* pSet = 0;
     603             : 
     604          56 :             if( rSttNd.IsCntntNode() )
     605          53 :                 pSet = &rSttNd.GetCntntNode()->GetSwAttrSet();
     606           3 :             else if( rSttNd.IsTableNode() )
     607           3 :                 pSet = &rSttNd.GetTableNode()->GetTable().
     608           3 :                             GetFrmFmt()->GetAttrSet();
     609           0 :             else if( rSttNd.IsSectionNode() )
     610           0 :                 pSet = &rSttNd.GetSectionNode()->GetSection().
     611           0 :                             GetFmt()->GetAttrSet();
     612             : 
     613          56 :             if( pSet )
     614             :             {
     615             :                 sal_uInt16 nPosInDoc;
     616          56 :                 pSttPgDsc = (SwFmtPageDesc*)&pSet->Get( RES_PAGEDESC );
     617          56 :                 if( !pSttPgDsc->GetPageDesc() )
     618          10 :                     pSttPgDsc = 0;
     619          92 :                 else if( pDoc->FindPageDescByName( pSttPgDsc->
     620          92 :                                     GetPageDesc()->GetName(), &nPosInDoc ))
     621             :                 {
     622          46 :                     Strm().WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PGDSCNO );
     623          46 :                     OutULong( nPosInDoc ).WriteChar( '}' );
     624             :                 }
     625             :             }
     626             :         }
     627             :         const SwPageDesc& rPageDesc = pSttPgDsc ? *pSttPgDsc->GetPageDesc()
     628          56 :             : pDoc->GetPageDesc( 0 );
     629          56 :         const SwFrmFmt &rFmtPage = rPageDesc.GetMaster();
     630             : 
     631             :         {
     632          56 :             if( rPageDesc.GetLandscape() )
     633           0 :                 Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LANDSCAPE );
     634             : 
     635          56 :             const SwFmtFrmSize& rSz = rFmtPage.GetFrmSize();
     636             :             // Clipboard document is always created without a printer, then
     637             :             // the size will be always LONG_MAX! Solution then is to use A4
     638          56 :             if( LONG_MAX == rSz.GetHeight() || LONG_MAX == rSz.GetWidth() )
     639             :             {
     640           0 :                 Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PAPERH );
     641           0 :                 Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4);
     642           0 :                 OutULong( a4.Height() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PAPERW );
     643           0 :                 OutULong( a4.Width() );
     644             :             }
     645             :             else
     646             :             {
     647          56 :                 Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PAPERH );
     648          56 :                 OutULong( rSz.GetHeight() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PAPERW );
     649          56 :                 OutULong( rSz.GetWidth() );
     650             :             }
     651             :         }
     652             : 
     653             :         {
     654          56 :             const SvxLRSpaceItem& rLR = rFmtPage.GetLRSpace();
     655          56 :             Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGL );
     656          56 :             OutLong( rLR.GetLeft() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGR );
     657          56 :             OutLong( rLR.GetRight() );
     658             :         }
     659             : 
     660             :         {
     661          56 :             const SvxULSpaceItem& rUL = rFmtPage.GetULSpace();
     662          56 :             Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGT );
     663          56 :             OutLong( rUL.GetUpper() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MARGB );
     664          56 :             OutLong( rUL.GetLower() );
     665             :         }
     666             : 
     667          56 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SECTD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SBKNONE );
     668             :         // All sections are unlocked by default
     669          56 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED );
     670          56 :         OutLong(1);
     671          56 :         OutPageDescription( rPageDesc, false, true );   // Changed bCheckForFirstPage to sal_True so headers
     672             :                                                             // following title page are correctly added - i13107
     673          56 :         if( pSttPgDsc )
     674             :         {
     675          46 :             pAktPageDesc = &rPageDesc;
     676             :         }
     677             :     }
     678             : 
     679             :     // line numbering
     680          56 :     const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo();
     681          56 :     if ( rLnNumInfo.IsPaintLineNumbers() )
     682           1 :         AttrOutput().SectionLineNumbering( 0, rLnNumInfo );
     683             : 
     684             :     {
     685             :         // write the footnotes and endnotes-out Info
     686          56 :         const SwFtnInfo& rFtnInfo = pDoc->GetFtnInfo();
     687             : 
     688          56 :         const char* pOut = FTNPOS_CHAPTER == rFtnInfo.ePos
     689             :                             ? OOO_STRING_SVTOOLS_RTF_ENDDOC
     690          56 :                             : OOO_STRING_SVTOOLS_RTF_FTNBJ;
     691          56 :         Strm().WriteCharPtr( pOut ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_FTNSTART );
     692          56 :         OutLong( rFtnInfo.nFtnOffset + 1 );
     693             : 
     694          56 :         switch( rFtnInfo.eNum )
     695             :         {
     696           1 :             case FTNNUM_PAGE:       pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTPG; break;
     697          55 :             case FTNNUM_DOC:        pOut = OOO_STRING_SVTOOLS_RTF_FTNRSTCONT;   break;
     698           0 :             default:                pOut = OOO_STRING_SVTOOLS_RTF_FTNRESTART;   break;
     699             :         }
     700          56 :         Strm().WriteCharPtr( pOut );
     701             : 
     702          56 :         switch( rFtnInfo.aFmt.GetNumberingType() )
     703             :         {
     704             :             case SVX_NUM_CHARS_LOWER_LETTER:
     705           0 :             case SVX_NUM_CHARS_LOWER_LETTER_N:  pOut = OOO_STRING_SVTOOLS_RTF_FTNNALC;  break;
     706             :             case SVX_NUM_CHARS_UPPER_LETTER:
     707           0 :             case SVX_NUM_CHARS_UPPER_LETTER_N:  pOut = OOO_STRING_SVTOOLS_RTF_FTNNAUC;  break;
     708           0 :             case SVX_NUM_ROMAN_LOWER:           pOut = OOO_STRING_SVTOOLS_RTF_FTNNRLC;  break;
     709           0 :             case SVX_NUM_ROMAN_UPPER:           pOut = OOO_STRING_SVTOOLS_RTF_FTNNRUC;  break;
     710           0 :             case SVX_NUM_CHAR_SPECIAL:          pOut = OOO_STRING_SVTOOLS_RTF_FTNNCHI;  break;
     711          56 :             default:                    pOut = OOO_STRING_SVTOOLS_RTF_FTNNAR;       break;
     712             :         }
     713          56 :         Strm().WriteCharPtr( pOut );
     714             : 
     715          56 :         const SwEndNoteInfo& rEndNoteInfo = pDoc->GetEndNoteInfo();
     716             : 
     717          56 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_AENDDOC ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_AFTNRSTCONT )
     718          56 :               .WriteCharPtr( OOO_STRING_SVTOOLS_RTF_AFTNSTART );
     719          56 :         OutLong( rEndNoteInfo.nFtnOffset + 1 );
     720             : 
     721          56 :         switch( rEndNoteInfo.aFmt.GetNumberingType() )
     722             :         {
     723             :             case SVX_NUM_CHARS_LOWER_LETTER:
     724           0 :             case SVX_NUM_CHARS_LOWER_LETTER_N:  pOut = OOO_STRING_SVTOOLS_RTF_AFTNNALC; break;
     725             :             case SVX_NUM_CHARS_UPPER_LETTER:
     726           0 :             case SVX_NUM_CHARS_UPPER_LETTER_N:  pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAUC; break;
     727          55 :             case SVX_NUM_ROMAN_LOWER:           pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRLC; break;
     728           0 :             case SVX_NUM_ROMAN_UPPER:           pOut = OOO_STRING_SVTOOLS_RTF_AFTNNRUC; break;
     729           0 :             case SVX_NUM_CHAR_SPECIAL:          pOut = OOO_STRING_SVTOOLS_RTF_AFTNNCHI; break;
     730           1 :             default:                    pOut = OOO_STRING_SVTOOLS_RTF_AFTNNAR;  break;
     731             :         }
     732          56 :         Strm().WriteCharPtr( pOut );
     733             :     }
     734             : 
     735          56 :     Strm().WriteCharPtr( SAL_NEWLINE_STRING );
     736             : 
     737          56 :     WriteFootnoteSettings();
     738             : 
     739          56 :     WriteMainText();
     740             : 
     741          56 :     Strm().WriteChar( '}' );
     742          56 : }
     743             : 
     744           8 : void RtfExport::PrepareNewPageDesc( const SfxItemSet* pSet,
     745             :         const SwNode& rNd, const SwFmtPageDesc* pNewPgDescFmt,
     746             :         const SwPageDesc* pNewPgDesc )
     747             : {
     748             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     749           8 :     const SwSectionFmt* pFmt = GetSectionFormat( rNd );
     750           8 :     const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );
     751             : 
     752             :     OSL_ENSURE( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );
     753             : 
     754           8 :     if ( pNewPgDescFmt )
     755           7 :         m_pSections->AppendSection( *pNewPgDescFmt, rNd, pFmt, nLnNm );
     756           1 :     else if ( pNewPgDesc )
     757           1 :         m_pSections->AppendSection( pNewPgDesc, rNd, pFmt, nLnNm );
     758             : 
     759             :     // Don't insert a page break, when we're changing page style just because the next page has to be a different one.
     760           8 :     if (!m_pAttrOutput->m_pPrevPageDesc || m_pAttrOutput->m_pPrevPageDesc->GetFollow() != pNewPgDesc)
     761           5 :         AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
     762           8 : }
     763             : 
     764         379 : bool RtfExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
     765             : {
     766         379 :     bool bRet( false );
     767             : 
     768             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     769             : 
     770         379 :     if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
     771             :     {
     772         378 :         if (const SwFmt *pParent = rFmt.DerivedFrom())
     773             :         {
     774         378 :             if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
     775             :             {
     776             :                 // Level 9 disables the outline
     777           0 :                 Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LEVEL ).WriteInt32( sal_Int32(9) );
     778             : 
     779           0 :                 bRet = true;
     780             :             }
     781             :         }
     782             :     }
     783             : 
     784         379 :     return bRet;
     785             : }
     786             : 
     787           0 : void RtfExport::OutputGrfNode( const SwGrfNode& )
     788             : {
     789             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     790             : 
     791             :     /* noop, see RtfAttributeOutput::FlyFrameGraphic */
     792           0 : }
     793             : 
     794           0 : void RtfExport::OutputOLENode( const SwOLENode& )
     795             : {
     796             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     797             : 
     798             :     /* noop, see RtfAttributeOutput::FlyFrameOLE */
     799           0 : }
     800             : 
     801           0 : void RtfExport::OutputLinkedOLE( const OUString& )
     802             : {
     803             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     804           0 : }
     805             : 
     806         521 : void RtfExport::OutputTextNode( const SwTxtNode& rNode )
     807             : {
     808         521 :     m_nCurrentNodeIndex = rNode.GetIndex();
     809         521 :     if ( !m_bOutOutlineOnly || rNode.IsOutline( ) )
     810         521 :         MSWordExportBase::OutputTextNode( rNode );
     811         521 :     m_nCurrentNodeIndex = 0;
     812         521 : }
     813             : 
     814           0 : void RtfExport::AppendSection( const SwPageDesc* pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
     815             : {
     816             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     817             : 
     818           0 :     m_pSections->AppendSection( pPageDesc, pFmt, nLnNum );
     819           0 :     AttrOutput().SectionBreak( msword::PageBreak, m_pSections->CurrentSectionInfo() );
     820           0 : }
     821             : 
     822          56 : RtfExport::RtfExport( RtfExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam, Writer* pWriter, bool bOutOutlineOnly )
     823             :     : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ),
     824             :       m_pFilter( pFilter ),
     825             :       m_pWriter( pWriter ),
     826             :       m_pAttrOutput(),
     827             :       m_pSections( NULL ),
     828             :       m_pSdrExport(),
     829             :       m_bOutOutlineOnly( bOutOutlineOnly ),
     830             :       eDefaultEncoding(
     831             :               rtl_getTextEncodingFromWindowsCharset(
     832          56 :                   sw::ms::rtl_TextEncodingToWinCharset(DEF_ENCODING))),
     833             :       eCurrentEncoding(eDefaultEncoding),
     834             :       bRTFFlySyntax(false),
     835         112 :       m_nCurrentNodeIndex(0)
     836             : {
     837          56 :     mbExportModeRTF = true;
     838             :     // the attribute output for the document
     839          56 :     m_pAttrOutput.reset(new RtfAttributeOutput(*this));
     840             :     // that just causes problems for RTF
     841          56 :     bSubstituteBullets = false;
     842             :     // needed to have a complete font table
     843          56 :     maFontHelper.bLoadAllFonts = true;
     844             :     // the related SdrExport
     845          56 :     m_pSdrExport.reset(new RtfSdrExport(*this));
     846             : 
     847          56 :     if (!m_pWriter)
     848          55 :         m_pWriter = &m_pFilter->m_aWriter;
     849          56 : }
     850             : 
     851          56 : RtfExport::~RtfExport()
     852             : {
     853          56 : }
     854             : 
     855       16396 : SvStream& RtfExport::Strm()
     856             : {
     857       16396 :     return m_pWriter->Strm();
     858             : }
     859             : 
     860        3503 : SvStream& RtfExport::OutULong( sal_uLong nVal )
     861             : {
     862        3503 :     return m_pWriter->OutULong( Strm(), nVal );
     863             : }
     864             : 
     865         624 : SvStream& RtfExport::OutLong( long nVal )
     866             : {
     867         624 :     return m_pWriter->OutLong( Strm(), nVal );
     868             : }
     869             : 
     870         330 : void RtfExport::OutUnicode(const sal_Char *pToken, const OUString &rContent, bool bUpr)
     871             : {
     872         330 :     if (!rContent.isEmpty())
     873             :     {
     874          16 :         if (!bUpr)
     875             :         {
     876          13 :             Strm().WriteChar( '{' ).WriteCharPtr( pToken ).WriteChar( ' ' );
     877          13 :             Strm().WriteCharPtr( msfilter::rtfutil::OutString( rContent, eCurrentEncoding ).getStr() );
     878          13 :             Strm().WriteChar( '}' );
     879             :         }
     880             :         else
     881           3 :             Strm().WriteCharPtr( msfilter::rtfutil::OutStringUpr(pToken, rContent, eCurrentEncoding).getStr() );
     882             :     }
     883         330 : }
     884             : 
     885         165 : void RtfExport::OutDateTime(const sal_Char* pStr, const util::DateTime& rDT )
     886             : {
     887         165 :     Strm().WriteChar( '{' ).WriteCharPtr( pStr ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_YR );
     888         165 :     OutULong( rDT.Year ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MO );
     889         165 :     OutULong( rDT.Month ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_DY );
     890         165 :     OutULong( rDT.Day ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_HR );
     891         165 :     OutULong( rDT.Hours ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_MIN );
     892         165 :     OutULong( rDT.Minutes ).WriteChar( '}' );
     893         165 : }
     894             : 
     895         649 : sal_uInt16 RtfExport::GetColor( const Color& rColor ) const
     896             : {
     897        1235 :     for (RtfColorTbl::const_iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); ++it )
     898        1235 :         if ((*it).second == rColor) {
     899             :             SAL_INFO("sw.rtf", OSL_THIS_FUNC << " returning " << (*it).first << " (" << rColor.GetRed() << "," << rColor.GetGreen() << "," << rColor.GetBlue() << ")");
     900         649 :             return (*it).first;
     901             :         }
     902             :     OSL_FAIL( "No such Color in m_aColTbl!" );
     903           0 :     return 0;
     904             : }
     905             : 
     906         618 : void RtfExport::InsColor( const Color& rCol )
     907             : {
     908             :     sal_uInt16 n;
     909         618 :     bool bAutoColorInTable = false;
     910        1112 :     for (RtfColorTbl::iterator it=m_aColTbl.begin() ; it != m_aColTbl.end(); ++it )
     911         926 :         if ((*it).second == rCol)
     912        1050 :             return; // Already in the table
     913         494 :         else if ((*it).second == COL_AUTO)
     914         265 :             bAutoColorInTable = true;
     915         186 :     if (rCol.GetColor() == COL_AUTO)
     916             :         // COL_AUTO gets value 0
     917          56 :         n = 0;
     918             :     else
     919             :     {
     920             :         // other colors get values >0
     921         130 :         n = m_aColTbl.size();
     922         130 :         if (!bAutoColorInTable)
     923             :             // reserve value "0" for COL_AUTO (if COL_AUTO wasn't inserted until now)
     924          57 :             n++;
     925             :     }
     926         186 :     m_aColTbl.insert(std::pair<sal_uInt16,Color>( n, rCol ));
     927             : }
     928             : 
     929          56 : void RtfExport::InsColorLine( const SvxBoxItem& rBox )
     930             : {
     931          56 :     const SvxBorderLine* pLine = 0;
     932             : 
     933          56 :     if( rBox.GetTop() )
     934          45 :         InsColor( (pLine = rBox.GetTop())->GetColor() );
     935          56 :     if( rBox.GetBottom() && pLine != rBox.GetBottom() )
     936          51 :         InsColor( (pLine = rBox.GetBottom())->GetColor() );
     937          56 :     if( rBox.GetLeft() && pLine != rBox.GetLeft()  )
     938          50 :         InsColor( (pLine = rBox.GetLeft())->GetColor() );
     939          56 :     if( rBox.GetRight() && pLine != rBox.GetRight()  )
     940          46 :         InsColor( rBox.GetRight()->GetColor() );
     941          56 : }
     942          56 : void RtfExport::OutColorTable()
     943             : {
     944             :     // Build the table from rPool since the colors provided to
     945             :     // RtfAttributeOutput callbacks are too late.
     946             :     sal_uInt32 nMaxItem;
     947          56 :     const SfxItemPool& rPool = pDoc->GetAttrPool();
     948             : 
     949             :     // char color
     950             :     {
     951             :         const SvxColorItem* pCol = (const SvxColorItem*)GetDfltAttr(
     952          56 :                                                 RES_CHRATR_COLOR );
     953          56 :         InsColor( pCol->GetValue() );
     954          56 :         if( 0 != ( pCol = (const SvxColorItem*)rPool.GetPoolDefaultItem(
     955             :                 RES_CHRATR_COLOR ) ))
     956          55 :             InsColor( pCol->GetValue() );
     957          56 :         nMaxItem = rPool.GetItemCount2(RES_CHRATR_COLOR);
     958         170 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
     959             :         {
     960         114 :             if( 0 != (pCol = (const SvxColorItem*)rPool.GetItem2(
     961             :                 RES_CHRATR_COLOR, n ) ) )
     962          15 :                 InsColor( pCol->GetValue() );
     963             :         }
     964             : 
     965          56 :         const SvxUnderlineItem* pUnder = (const SvxUnderlineItem*)GetDfltAttr( RES_CHRATR_UNDERLINE );
     966          56 :         InsColor( pUnder->GetColor() );
     967          56 :         nMaxItem = rPool.GetItemCount2(RES_CHRATR_UNDERLINE);
     968          64 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
     969             :         {
     970           8 :             if( 0 != (pUnder = (const SvxUnderlineItem*)rPool.GetItem2( RES_CHRATR_UNDERLINE, n ) ) )
     971           8 :                 InsColor( pUnder->GetColor() );
     972             : 
     973             :         }
     974             : 
     975          56 :         const SvxOverlineItem* pOver = (const SvxOverlineItem*)GetDfltAttr( RES_CHRATR_OVERLINE );
     976          56 :         InsColor( pOver->GetColor() );
     977          56 :         nMaxItem = rPool.GetItemCount2(RES_CHRATR_OVERLINE);
     978          57 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
     979             :         {
     980           1 :             if( 0 != (pOver = (const SvxOverlineItem*)rPool.GetItem2( RES_CHRATR_OVERLINE, n ) ) )
     981           1 :                 InsColor( pOver->GetColor() );
     982             : 
     983             :         }
     984             : 
     985             :     }
     986             : 
     987             :     // background color
     988             :     static const sal_uInt16 aBrushIds[] = {
     989             :                                 RES_BACKGROUND, RES_CHRATR_BACKGROUND, 0 };
     990             : 
     991         168 :     for( const sal_uInt16* pIds = aBrushIds; *pIds; ++pIds )
     992             :     {
     993         112 :         const SvxBrushItem* pBkgrd = (const SvxBrushItem*)GetDfltAttr( *pIds );
     994         112 :         InsColor( pBkgrd->GetColor() );
     995         112 :         if( 0 != ( pBkgrd = (const SvxBrushItem*)rPool.GetPoolDefaultItem(
     996         112 :                         *pIds ) ))
     997             :         {
     998           0 :             InsColor( pBkgrd->GetColor() );
     999             :         }
    1000         112 :         nMaxItem = rPool.GetItemCount2( *pIds );
    1001         117 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
    1002             :         {
    1003           5 :             if( 0 != (pBkgrd = (const SvxBrushItem*)rPool.GetItem2(
    1004           5 :                     *pIds , n ) ))
    1005             :             {
    1006           5 :                 InsColor( pBkgrd->GetColor() );
    1007             :             }
    1008             :     }
    1009             :     }
    1010             : 
    1011             :     // shadow color
    1012             :     {
    1013             :         const SvxShadowItem* pShadow = (const SvxShadowItem*)GetDfltAttr(
    1014          56 :                                                             RES_SHADOW );
    1015          56 :         InsColor( pShadow->GetColor() );
    1016          56 :         if( 0 != ( pShadow = (const SvxShadowItem*)rPool.GetPoolDefaultItem(
    1017             :                         RES_SHADOW ) ))
    1018             :         {
    1019           0 :             InsColor( pShadow->GetColor() );
    1020             :         }
    1021          56 :         nMaxItem = rPool.GetItemCount2(RES_SHADOW);
    1022          62 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
    1023             :         {
    1024           6 :             if( 0 != (pShadow = (const SvxShadowItem*)rPool.GetItem2(
    1025             :                 RES_SHADOW, n ) ) )
    1026             :             {
    1027           6 :                 InsColor( pShadow->GetColor() );
    1028             :             }
    1029             :     }
    1030             :     }
    1031             : 
    1032             :     // frame border color
    1033             :     {
    1034             :         const SvxBoxItem* pBox;
    1035          56 :         if( 0 != ( pBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
    1036             :                         RES_BOX ) ))
    1037           0 :             InsColorLine( *pBox );
    1038          56 :         nMaxItem = rPool.GetItemCount2(RES_BOX);
    1039         118 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
    1040             :         {
    1041          62 :             if( 0 != (pBox = (const SvxBoxItem*)rPool.GetItem2( RES_BOX, n ) ))
    1042          54 :                 InsColorLine( *pBox );
    1043             :         }
    1044             :     }
    1045             : 
    1046             :     {
    1047             :         const SvxBoxItem* pCharBox;
    1048          56 :         if( 0 != ( pCharBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
    1049             :                         RES_CHRATR_BOX ) ))
    1050           0 :             InsColorLine( *pCharBox );
    1051          56 :         nMaxItem = rPool.GetItemCount2(RES_CHRATR_BOX);
    1052          60 :         for (sal_uInt32 n = 0; n < nMaxItem; ++n)
    1053             :         {
    1054           4 :             if( 0 != (pCharBox = (const SvxBoxItem*)rPool.GetItem2( RES_CHRATR_BOX, n ) ))
    1055           2 :                 InsColorLine( *pCharBox );
    1056             :         }
    1057             :     }
    1058             : 
    1059         242 :     for (size_t n = 0; n < m_aColTbl.size(); ++n)
    1060             :     {
    1061         186 :         const Color& rCol = m_aColTbl[ n ];
    1062         186 :         if( n || COL_AUTO != rCol.GetColor() )
    1063             :         {
    1064         130 :             Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RED );
    1065         130 :             OutULong( rCol.GetRed() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_GREEN );
    1066         130 :             OutULong( rCol.GetGreen() ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_BLUE );
    1067         130 :             OutULong( rCol.GetBlue() );
    1068             :         }
    1069         186 :         Strm().WriteChar( ';' );
    1070             :     }
    1071          56 : }
    1072             : 
    1073         482 : void RtfExport::InsStyle( sal_uInt16 nId, const OString& rStyle )
    1074             : {
    1075         482 :     m_aStyTbl.insert(std::pair<sal_uInt16,OString>(nId, rStyle) );
    1076         482 : }
    1077             : 
    1078         569 : OString* RtfExport::GetStyle( sal_uInt16 nId )
    1079             : {
    1080         569 :     std::map<sal_uInt16,OString>::iterator i = m_aStyTbl.find(nId);
    1081         569 :     if (i != m_aStyTbl.end())
    1082         527 :         return &i->second;
    1083          42 :     return NULL;
    1084             : }
    1085             : 
    1086           0 : sal_uInt16 RtfExport::GetRedline( const OUString& rAuthor )
    1087             : {
    1088           0 :     std::map<OUString,sal_uInt16>::iterator i = m_aRedlineTbl.find(rAuthor);
    1089           0 :     if (i != m_aRedlineTbl.end())
    1090           0 :         return i->second;
    1091             :     else
    1092             :     {
    1093           0 :         int nId = m_aRedlineTbl.size();
    1094           0 :         m_aRedlineTbl.insert(std::pair<OUString,sal_uInt16>(rAuthor,nId));
    1095           0 :         return nId;
    1096             :     }
    1097             : }
    1098             : 
    1099           0 : const OUString* RtfExport::GetRedline( sal_uInt16 nId )
    1100             : {
    1101           0 :     for(std::map<OUString,sal_uInt16>::iterator aIter = m_aRedlineTbl.begin(); aIter != m_aRedlineTbl.end(); ++aIter)
    1102           0 :         if ((*aIter).second == nId)
    1103           0 :             return &(*aIter).first;
    1104           0 :     return NULL;
    1105             : }
    1106             : 
    1107         128 : void RtfExport::OutPageDescription( const SwPageDesc& rPgDsc, bool bWriteReset, bool bCheckForFirstPage )
    1108             : {
    1109             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
    1110         128 :     const SwPageDesc *pSave = pAktPageDesc;
    1111             : 
    1112         128 :     pAktPageDesc = &rPgDsc;
    1113         184 :     if( bCheckForFirstPage && pAktPageDesc->GetFollow() &&
    1114          56 :             pAktPageDesc->GetFollow() != pAktPageDesc )
    1115           3 :         pAktPageDesc = pAktPageDesc->GetFollow();
    1116             : 
    1117         128 :     if( bWriteReset )
    1118             :     {
    1119           0 :         if( pCurPam->GetPoint()->nNode == pOrigPam->Start()->nNode )
    1120           0 :             Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SECTD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SBKNONE );
    1121             :         else
    1122           0 :             Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SECT ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_SECTD );
    1123             :     }
    1124             : 
    1125         128 :     if( pAktPageDesc->GetLandscape() )
    1126           0 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_LNDSCPSXN );
    1127             : 
    1128         128 :     const SwFmt *pFmt = &pAktPageDesc->GetMaster(); //GetLeft();
    1129         128 :     bOutPageDescs = true;
    1130         128 :     OutputFormat(*pFmt, true, false);
    1131         128 :     bOutPageDescs = false;
    1132             : 
    1133             :     // normal header / footer (without a style)
    1134             :     const SfxPoolItem* pItem;
    1135         256 :     if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_HEADER, false,
    1136         128 :                 &pItem ) == SFX_ITEM_SET)
    1137         126 :         WriteHeaderFooter(*pItem, true);
    1138         256 :     if( pAktPageDesc->GetLeft().GetAttrSet().GetItemState( RES_FOOTER, false,
    1139         128 :                 &pItem ) == SFX_ITEM_SET)
    1140         126 :         WriteHeaderFooter(*pItem, false);
    1141             : 
    1142             :     // title page
    1143         128 :     if( pAktPageDesc != &rPgDsc )
    1144             :     {
    1145           3 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TITLEPG );
    1146           3 :         pAktPageDesc = &rPgDsc;
    1147           6 :         if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_HEADER,
    1148           3 :                     false, &pItem ) == SFX_ITEM_SET )
    1149           3 :             WriteHeaderFooter(*pItem, true);
    1150           6 :         if( pAktPageDesc->GetMaster().GetAttrSet().GetItemState( RES_FOOTER,
    1151           3 :                     false, &pItem ) == SFX_ITEM_SET )
    1152           3 :             WriteHeaderFooter(*pItem, false);
    1153             :     }
    1154             : 
    1155             :     // numbering type
    1156         128 :     AttrOutput().SectionPageNumbering(pAktPageDesc->GetNumType().GetNumberingType(), boost::none);
    1157             : 
    1158         128 :     pAktPageDesc = pSave;
    1159             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
    1160         128 : }
    1161             : 
    1162         258 : void RtfExport::WriteHeaderFooter(const SfxPoolItem& rItem, bool bHeader)
    1163             : {
    1164         258 :     if (bHeader)
    1165             :     {
    1166         129 :         const SwFmtHeader& rHeader = (const SwFmtHeader&)rItem;
    1167         129 :         if (!rHeader.IsActive())
    1168         124 :             return;
    1169             :     }
    1170             :     else
    1171             :     {
    1172         129 :         const SwFmtFooter& rFooter = (const SwFmtFooter&)rItem;
    1173         129 :         if (!rFooter.IsActive())
    1174         122 :             return;
    1175             :     }
    1176             : 
    1177             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
    1178             : 
    1179          12 :     const sal_Char* pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADER : OOO_STRING_SVTOOLS_RTF_FOOTER);
    1180             :     /* is this a title page? */
    1181          12 :     if( pAktPageDesc->GetFollow() && pAktPageDesc->GetFollow() != pAktPageDesc )
    1182             :     {
    1183           0 :         Strm().WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TITLEPG );
    1184           0 :         pStr = (bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERF : OOO_STRING_SVTOOLS_RTF_FOOTERF);
    1185             :     }
    1186          12 :     Strm().WriteChar( '{' ).WriteCharPtr( pStr );
    1187          12 :     WriteHeaderFooterText(pAktPageDesc->GetMaster(), bHeader);
    1188          12 :     Strm().WriteChar( '}' );
    1189             : 
    1190             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
    1191             : }
    1192             : 
    1193           6 : void RtfExport::WriteHeaderFooter(const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr, bool bTitlepg)
    1194             : {
    1195             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
    1196             : 
    1197           6 :     m_pAttrOutput->WriteHeaderFooter_Impl( rFmt, bHeader, pStr, bTitlepg );
    1198             : 
    1199             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
    1200           6 : }
    1201             : 
    1202             : /// Glue class to call RtfExport as an internal filter, needed by copy&paste support.
    1203             : class SwRTFWriter : public Writer
    1204             : {
    1205             :     private:
    1206             :         bool m_bOutOutlineOnly;
    1207             : 
    1208             :     public:
    1209             :         SwRTFWriter( const OUString& rFilterName, const OUString& rBaseURL );
    1210             :         virtual ~SwRTFWriter();
    1211             :                virtual sal_uLong WriteStream() SAL_OVERRIDE;
    1212             : };
    1213             : 
    1214           1 : SwRTFWriter::SwRTFWriter( const OUString& rFltName, const OUString & rBaseURL )
    1215             : {
    1216             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
    1217           1 :     SetBaseURL( rBaseURL );
    1218             :     // export outline nodes, only (send outline to clipboard/presentation)
    1219           1 :     m_bOutOutlineOnly = rFltName.startsWith("O");
    1220           1 : }
    1221             : 
    1222           2 : SwRTFWriter::~SwRTFWriter()
    1223           2 : {}
    1224             : 
    1225           1 : sal_uLong SwRTFWriter::WriteStream()
    1226             : {
    1227             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
    1228           1 :     SwPaM aPam(*pCurPam->End(), *pCurPam->Start());
    1229           2 :     RtfExport aExport( NULL, pDoc, &aPam, pCurPam, this, m_bOutOutlineOnly );
    1230           1 :     aExport.ExportDocument( true );
    1231           2 :     return 0;
    1232             : }
    1233             : 
    1234           1 : extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportRTF( const OUString& rFltName, const OUString& rBaseURL, WriterRef& xRet )
    1235             : {
    1236             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
    1237           1 :     xRet = new SwRTFWriter( rFltName, rBaseURL );
    1238          34 : }
    1239             : 
    1240             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10