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

Generated by: LCOV version 1.10