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

Generated by: LCOV version 1.11