LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - wrtww8.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1535 2005 76.6 %
Date: 2014-11-03 Functions: 127 148 85.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 <iostream>
      21             : 
      22             : #include <boost/noncopyable.hpp>
      23             : #include <com/sun/star/embed/ElementModes.hpp>
      24             : #include <com/sun/star/embed/XStorage.hpp>
      25             : #include <unotools/ucbstreamhelper.hxx>
      26             : #include <algorithm>
      27             : #include <map>
      28             : #include <set>
      29             : #include <hintids.hxx>
      30             : #include <string.h>
      31             : #include <osl/endian.h>
      32             : #include <docsh.hxx>
      33             : #include <drawdoc.hxx>
      34             : 
      35             : #include <unotools/fltrcfg.hxx>
      36             : #include <vcl/salbtype.hxx>
      37             : #include <sot/storage.hxx>
      38             : #include <svl/zformat.hxx>
      39             : #include <sfx2/docinf.hxx>
      40             : #include <editeng/tstpitem.hxx>
      41             : #include <svx/svdmodel.hxx>
      42             : #include <svx/svdpage.hxx>
      43             : #include <editeng/hyphenzoneitem.hxx>
      44             : #include <editeng/langitem.hxx>
      45             : #include <filter/msfilter/msoleexp.hxx>
      46             : #include <editeng/lrspitem.hxx>
      47             : #include <editeng/ulspitem.hxx>
      48             : #include <editeng/boxitem.hxx>
      49             : #include <editeng/brushitem.hxx>
      50             : #include <swtypes.hxx>
      51             : #include <swrect.hxx>
      52             : #include <swtblfmt.hxx>
      53             : #include <txatbase.hxx>
      54             : #include <fmtcntnt.hxx>
      55             : #include <fmtpdsc.hxx>
      56             : #include <fmtrowsplt.hxx>
      57             : #include <frmatr.hxx>
      58             : #include <doc.hxx>
      59             : #include <IDocumentSettingAccess.hxx>
      60             : #include <IDocumentDrawModelAccess.hxx>
      61             : #include <IDocumentStylePoolAccess.hxx>
      62             : #include <IDocumentStatistics.hxx>
      63             : #include <IDocumentLayoutAccess.hxx>
      64             : #include <IDocumentExternalData.hxx>
      65             : #include <viewopt.hxx>
      66             : #include <docary.hxx>
      67             : #include <pam.hxx>
      68             : #include <ndtxt.hxx>
      69             : #include <shellio.hxx>
      70             : #include <docstat.hxx>
      71             : #include <pagedesc.hxx>
      72             : #include <IMark.hxx>
      73             : #include <swtable.hxx>
      74             : #include <wrtww8.hxx>
      75             : #include <ww8par.hxx>
      76             : #include <fltini.hxx>
      77             : #include <swmodule.hxx>
      78             : #include <section.hxx>
      79             : #include <swfltopt.hxx>
      80             : #include <fmtinfmt.hxx>
      81             : #include <txtinet.hxx>
      82             : #include <fmturl.hxx>
      83             : #include <fesh.hxx>
      84             : #include <svtools/imap.hxx>
      85             : #include <svtools/imapobj.hxx>
      86             : #include <tools/urlobj.hxx>
      87             : #include <mdiexp.hxx>
      88             : #include <statstr.hrc>
      89             : #include <fmtline.hxx>
      90             : #include <fmtfsize.hxx>
      91             : #include <comphelper/extract.hxx>
      92             : #include <comphelper/string.hxx>
      93             : #include <sprmids.hxx>
      94             : 
      95             : #include "writerhelper.hxx"
      96             : #include "writerwordglue.hxx"
      97             : #include "ww8attributeoutput.hxx"
      98             : #include <IDocumentMarkAccess.hxx>
      99             : #include <xmloff/odffields.hxx>
     100             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
     101             : #include <com/sun/star/document/XDocumentProperties.hpp>
     102             : #include "dbgoutsw.hxx"
     103             : #include <sfx2/docfile.hxx>
     104             : #include <sfx2/request.hxx>
     105             : #include <sfx2/frame.hxx>
     106             : #include <svl/stritem.hxx>
     107             : #include <unotools/tempfile.hxx>
     108             : #include <filter/msfilter/mscodec.hxx>
     109             : #include <filter/msfilter/svxmsbas.hxx>
     110             : #include <osl/time.h>
     111             : #include <rtl/random.h>
     112             : #include <vcl/svapp.hxx>
     113             : #include "WW8Sttbf.hxx"
     114             : #include <editeng/charrotateitem.hxx>
     115             : #include "WW8FibData.hxx"
     116             : #include "numrule.hxx"
     117             : #include "fmtclds.hxx"
     118             : 
     119             : using namespace css;
     120             : using namespace sw::util;
     121             : using namespace sw::types;
     122             : 
     123             : /** FKP - Formatted disK Page
     124             : */
     125             : class WW8_WrFkp
     126             : {
     127             :     sal_uInt8* pFkp;         // Fkp total ( first and only FCs and Sprms )
     128             :     sal_uInt8* pOfs;         // pointer to the offset area, later copied to pFkp
     129             :     ePLCFT ePlc;
     130             :     short nStartGrp;    // ab hier grpprls
     131             :     short nOldStartGrp;
     132             :     sal_uInt8 nItemSize;
     133             :     sal_uInt8 nIMax;         // number of entry pairs
     134             :     sal_uInt8 nOldVarLen;
     135             :     bool bCombined;     // true : paste not allowed
     136             : 
     137             :     sal_uInt8 SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms );
     138             : public:
     139             :     WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8);
     140             :     ~WW8_WrFkp();
     141             :     bool Append( WW8_FC nEndFc, sal_uInt16 nVarLen = 0, const sal_uInt8* pSprms = 0 );
     142             :     bool Combine();
     143             :     void Write( SvStream& rStrm, SwWW8WrGrf& rGrf );
     144             : 
     145        1698 :     bool IsEqualPos(WW8_FC nEndFc) const
     146        1698 :     {   return !bCombined && nIMax && nEndFc == ((sal_Int32*)pFkp)[nIMax]; }
     147             :     void MergeToNew( short& rVarLen, sal_uInt8 *& pNewSprms );
     148         406 :     bool IsEmptySprm() const
     149         406 :     {   return !bCombined && nIMax && !nOldVarLen;  }
     150         190 :     void SetNewEnd( WW8_FC nEnd )
     151         190 :     {   ((sal_Int32*)pFkp)[nIMax] = nEnd; }
     152             : 
     153             :     WW8_FC GetStartFc() const;
     154             :     WW8_FC GetEndFc() const;
     155             : 
     156             :     sal_uInt8 *CopyLastSprms(sal_uInt8 &rLen, bool bVer8);
     157             : };
     158             : 
     159             : // class WW8_WrPc collects all piece entries for one piece
     160             : class WW8_WrPc
     161             : {
     162             :     WW8_CP nStartCp;                    // Starting character position of the text
     163             :     WW8_FC nStartFc;                    // Starting file position of the text
     164             :     sal_uInt16 nStatus;                     // End of paragraph inside the piece?
     165             : 
     166             : public:
     167          34 :     WW8_WrPc(WW8_FC nSFc, WW8_CP nSCp )
     168          34 :         : nStartCp( nSCp ), nStartFc( nSFc ), nStatus( 0x0040 )
     169          34 :     {}
     170             : 
     171         852 :     void SetStatus()                { nStatus = 0x0050; }
     172          34 :     sal_uInt16 GetStatus()  const       { return nStatus; }
     173         684 :     WW8_CP GetStartCp() const       { return nStartCp; }
     174          34 :     WW8_FC GetStartFc() const       { return nStartFc; }
     175             : };
     176             : 
     177             : typedef std::map<OUString,long> BKMKNames;
     178             : typedef BKMKNames::iterator BKMKNmItr;
     179             : typedef std::pair<bool,OUString> BKMK;
     180             : typedef std::pair<long,BKMK> BKMKCP;
     181             : typedef std::multimap<long,BKMKCP*> BKMKCPs;
     182             : typedef BKMKCPs::iterator CPItr;
     183             : 
     184             : class WW8_WrtBookmarks: private boost::noncopyable
     185             : {
     186             : private:
     187             :     BKMKCPs aSttCps,aEndCps;
     188             :     BKMKNames maSwBkmkNms;
     189             : 
     190             : public:
     191             :     WW8_WrtBookmarks();
     192             :     ~WW8_WrtBookmarks();
     193             :     //! Add a new bookmark to the list OR add an end position to an existing bookmark.
     194             :     void Append( WW8_CP nStartCp, const OUString& rNm, const ::sw::mark::IMark* pBkmk=NULL );
     195             :     //! Write out bookmarks to file.
     196             :     void Write( WW8Export& rWrt );
     197             :     //! Move existing field marks from one position to another.
     198             :     void MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo);
     199             : };
     200             : 
     201          34 : WW8_WrtBookmarks::WW8_WrtBookmarks()
     202          34 : {}
     203             : 
     204          68 : WW8_WrtBookmarks::~WW8_WrtBookmarks()
     205             : {
     206          34 :     CPItr aEnd = aSttCps.end();
     207          48 :     for (CPItr aItr = aSttCps.begin();aItr!=aEnd;++aItr)
     208             :     {
     209          14 :         if (aItr->second)
     210             :         {
     211          14 :             delete aItr->second;
     212          14 :             aItr->second = NULL;
     213             :         }
     214             :     }
     215          34 : }
     216             : 
     217          24 : void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const OUString& rNm, const ::sw::mark::IMark*)
     218             : {
     219          24 :     std::pair<BKMKNmItr,bool> aResult = maSwBkmkNms.insert(std::pair<OUString,long>(rNm,0L));
     220          24 :     if (aResult.second)
     221             :     {
     222          14 :         BKMK aBK(false,rNm);
     223          14 :         BKMKCP* pBKCP = new BKMKCP((long)nStartCp,aBK);
     224          14 :         aSttCps.insert(std::pair<long,BKMKCP*>(nStartCp,pBKCP));
     225          14 :         aResult.first->second = (long)nStartCp;
     226             :     }
     227             :     else
     228             :     {
     229          10 :         std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(aResult.first->second);
     230          12 :         for (CPItr aItr = aRange.first;aItr != aRange.second;++aItr)
     231             :         {
     232          12 :             if (aItr->second && aItr->second->second.second == rNm)
     233             :             {
     234          10 :                 if (aItr->second->second.first)
     235           0 :                     nStartCp--;
     236          10 :                 aItr->second->first = (long)nStartCp;
     237          10 :                 break;
     238             :             }
     239             :         }
     240             :     }
     241          24 : }
     242             : 
     243          34 : void WW8_WrtBookmarks::Write( WW8Export& rWrt)
     244             : {
     245          34 :     if (aSttCps.empty())
     246          64 :         return;
     247           4 :     CPItr aItr;
     248             :     long n;
     249           4 :     std::vector<OUString> aNames;
     250           8 :     SvMemoryStream aTempStrm1(65535,65535);
     251           8 :     SvMemoryStream aTempStrm2(65535,65535);
     252          18 :     for (aItr = aSttCps.begin();aItr!=aSttCps.end();++aItr)
     253             :     {
     254          14 :         if (aItr->second)
     255             :         {
     256          14 :             aEndCps.insert(std::pair<long,BKMKCP*>(aItr->second->first,aItr->second));
     257          14 :             aNames.push_back(aItr->second->second.second);
     258          14 :             SwWW8Writer::WriteLong( aTempStrm1, aItr->first);
     259             :         }
     260             :     }
     261             : 
     262           4 :     aTempStrm1.Seek(0L);
     263          18 :     for (aItr = aEndCps.begin(), n = 0;aItr != aEndCps.end();++aItr,++n)
     264             :     {
     265          14 :         if (aItr->second)
     266             :         {
     267          14 :             aItr->second->first = n;
     268          14 :             SwWW8Writer::WriteLong( aTempStrm2, aItr->first);
     269             :         }
     270             :     }
     271             : 
     272           4 :     aTempStrm2.Seek(0L);
     273           4 :     rWrt.WriteAsStringTable(aNames, rWrt.pFib->fcSttbfbkmk,rWrt.pFib->lcbSttbfbkmk);
     274           4 :     SvStream& rStrm = rWrt.bWrtWW8 ? *rWrt.pTableStrm : rWrt.Strm();
     275           4 :     rWrt.pFib->fcPlcfbkf = rStrm.Tell();
     276           4 :     rStrm.WriteStream( aTempStrm1 );
     277           4 :     SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
     278          18 :     for (aItr = aSttCps.begin();aItr!=aSttCps.end();++aItr)
     279             :     {
     280          14 :         if (aItr->second)
     281             :         {
     282          14 :             SwWW8Writer::WriteLong(rStrm, aItr->second->first);
     283             :         }
     284             :     }
     285           4 :     rWrt.pFib->lcbPlcfbkf = rStrm.Tell() - rWrt.pFib->fcPlcfbkf;
     286           4 :     rWrt.pFib->fcPlcfbkl = rStrm.Tell();
     287           4 :     rStrm.WriteStream( aTempStrm2 );
     288           4 :     SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx);
     289           8 :     rWrt.pFib->lcbPlcfbkl = rStrm.Tell() - rWrt.pFib->fcPlcfbkl;
     290             : }
     291             : 
     292           0 : void WW8_WrtBookmarks::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
     293             : {
     294           0 :     std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(nFrom);
     295           0 :     CPItr aItr = aRange.first;
     296           0 :     while (aItr != aRange.second)
     297             :     {
     298           0 :         if (aItr->second)
     299             :         {
     300           0 :             if (aItr->second->first == (long)nFrom)
     301             :             {
     302           0 :                 aItr->second->second.first = true;
     303           0 :                 aItr->second->first = nTo;
     304             :             }
     305           0 :             aSttCps.insert(std::pair<long,BKMKCP*>(nTo,aItr->second));
     306           0 :             aItr->second = NULL;
     307           0 :             aRange = aSttCps.equal_range(nFrom);
     308           0 :             aItr = aRange.first;
     309           0 :             continue;
     310             :         }
     311           0 :         ++aItr;
     312             :     }
     313           0 : }
     314             : 
     315             : #define ANZ_DEFAULT_STYLES 16
     316             : 
     317             : // Names of the storage streams
     318             : #define sMainStream OUString("WordDocument")
     319             : #define sCompObj OUString("\1CompObj")
     320             : 
     321          34 : static void WriteDop( WW8Export& rWrt )
     322             : {
     323          34 :     WW8Dop& rDop = *rWrt.pDop;
     324             : 
     325             :     // i#78951#, store the value of unknown compatibility options
     326          34 :     rDop.SetCompatibilityOptions( rWrt.pDoc->getIDocumentSettingAccess().Getn32DummyCompatibilityOptions1());
     327          34 :     rDop.SetCompatibilityOptions2( rWrt.pDoc->getIDocumentSettingAccess().Getn32DummyCompatibilityOptions2());
     328             : 
     329          34 :     rDop.fNoLeading = !rWrt.pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::ADD_EXT_LEADING);
     330          34 :     rDop.fUsePrinterMetrics = !rWrt.pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE);
     331             : 
     332             :     // write default TabStop
     333             :     const SvxTabStopItem& rTabStop =
     334          34 :         DefaultItemGet<SvxTabStopItem>(*rWrt.pDoc, RES_PARATR_TABSTOP);
     335          34 :     rDop.dxaTab = (sal_uInt16)rTabStop[0].GetTabPos();
     336             : 
     337             :     // Zoom factor
     338          34 :     SwViewShell *pViewShell(rWrt.pDoc->getIDocumentLayoutAccess().GetCurrentViewShell());
     339          34 :     if (pViewShell && pViewShell->GetViewOptions()->GetZoomType() == SVX_ZOOM_PERCENT)
     340          34 :         rDop.wScaleSaved = pViewShell->GetViewOptions()->GetZoom();
     341             : 
     342             :     // Werte aus der DocStatistik (werden aufjedenfall fuer die
     343             :     // DocStat-Felder benoetigt!)
     344          34 :     rDop.fWCFtnEdn = true; // because they are included in StarWriter
     345             : 
     346          34 :     const SwDocStat& rDStat = rWrt.pDoc->getIDocumentStatistics().GetDocStat();
     347          34 :     rDop.cWords = rDStat.nWord;
     348          34 :     rDop.cCh = rDStat.nChar;
     349          34 :     rDop.cPg = static_cast< sal_Int16 >(rDStat.nPage);
     350          34 :     rDop.cParas = rDStat.nPara;
     351          34 :     rDop.cLines = rDStat.nPara;
     352             : 
     353          34 :     SwDocShell *pDocShell(rWrt.pDoc->GetDocShell());
     354             :     OSL_ENSURE(pDocShell, "no SwDocShell");
     355          34 :     uno::Reference<document::XDocumentProperties> xDocProps;
     356          68 :     uno::Reference<beans::XPropertySet> xProps;
     357          34 :     if (pDocShell) {
     358             :         uno::Reference<lang::XComponent> xModelComp(pDocShell->GetModel(),
     359          34 :            uno::UNO_QUERY);
     360          68 :         xProps = uno::Reference<beans::XPropertySet>(xModelComp,
     361          34 :            uno::UNO_QUERY);
     362             :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
     363          68 :             xModelComp, uno::UNO_QUERY_THROW);
     364          34 :         xDocProps = xDPS->getDocumentProperties();
     365             :         OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
     366             : 
     367          68 :         rDop.lKeyProtDoc = pDocShell->GetModifyPasswordHash();
     368             :     }
     369             : 
     370          68 :     if ((rWrt.pSepx && rWrt.pSepx->DocumentIsProtected()) ||
     371          34 :         rDop.lKeyProtDoc != 0)
     372             :     {
     373           0 :         rDop.fProtEnabled =  true;
     374             :     }
     375             :     else
     376             :     {
     377          34 :         rDop.fProtEnabled = false;
     378             :     }
     379             : 
     380          34 :     if (!xDocProps.is())
     381             :     {
     382           0 :         rDop.dttmCreated = rDop.dttmRevised = rDop.dttmLastPrint = 0x45FBAC69;
     383             :     }
     384             :     else
     385             :     {
     386          34 :         ::util::DateTime uDT = xDocProps->getCreationDate();
     387          34 :         Date aD(uDT.Day, uDT.Month, uDT.Year);
     388          34 :         tools::Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
     389          34 :         rDop.dttmCreated = sw::ms::DateTime2DTTM(DateTime(aD,aT));
     390          34 :         uDT = xDocProps->getModificationDate();
     391          34 :         Date aD2(uDT.Day, uDT.Month, uDT.Year);
     392          34 :         tools::Time aT2(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
     393          34 :         rDop.dttmRevised = sw::ms::DateTime2DTTM(DateTime(aD2,aT2));
     394          34 :         uDT = xDocProps->getPrintDate();
     395          34 :         Date aD3(uDT.Day, uDT.Month, uDT.Year);
     396          34 :         tools::Time aT3(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.NanoSeconds);
     397          34 :         rDop.dttmLastPrint = sw::ms::DateTime2DTTM(DateTime(aD3,aT3));
     398             :     }
     399             : 
     400             :     // Also, the DocStat fields in headers, footers are not calculated correctly.
     401             :     // ( we do not have this fields! )
     402             : 
     403             :     // and also for the Headers and Footers
     404          34 :     rDop.cWordsFtnEnd   = rDStat.nWord;
     405          34 :     rDop.cChFtnEdn      = rDStat.nChar;
     406          34 :     rDop.cPgFtnEdn      = (sal_Int16)rDStat.nPage;
     407          34 :     rDop.cParasFtnEdn   = rDStat.nPara;
     408          34 :     rDop.cLinesFtnEdn   = rDStat.nPara;
     409             : 
     410          34 :     rDop.fDontUseHTMLAutoSpacing = rWrt.pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::PARA_SPACE_MAX);
     411             : 
     412          34 :     rDop.fExpShRtn = !rWrt.pDoc->getIDocumentSettingAccess().get(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK); // #i56856#
     413             : 
     414          68 :     rDop.Write( *rWrt.pTableStrm, *rWrt.pFib );
     415          34 : }
     416             : 
     417         158 : const sal_Unicode *WW8DopTypography::GetJapanNotBeginLevel1()
     418             : {
     419             :     static const sal_Unicode aJapanNotBeginLevel1[nMaxFollowing] =
     420             :     //Japanese Level 1
     421             :     {
     422             :         0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
     423             :         0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032,
     424             :         0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d,
     425             :         0x300f, 0x3011, 0x3015, 0x309b, 0x309c, 0x309d, 0x309e, 0x30fb,
     426             :         0x30fd, 0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a,
     427             :         0xff1b, 0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65,
     428             :         0xff9e, 0xff9f, 0xffe0
     429             :     };
     430         158 :     return &aJapanNotBeginLevel1[0];
     431             : }
     432             : 
     433         158 : const sal_Unicode *WW8DopTypography::GetJapanNotEndLevel1()
     434             : {
     435             :     static const sal_Unicode aJapanNotEndLevel1[nMaxLeading] =
     436             :     //Japanese Level 1
     437             :     {
     438             :         0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018,
     439             :         0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04,
     440             :         0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5
     441             :     };
     442         158 :     return &aJapanNotEndLevel1[0];
     443             : }
     444             : 
     445          56 : static int lcl_CmpBeginEndChars( const OUString& rSWStr,
     446             :     const sal_Unicode* pMSStr, int nMSStrByteLen )
     447             : {
     448          56 :     nMSStrByteLen /= sizeof( sal_Unicode );
     449          56 :     if( nMSStrByteLen > rSWStr.getLength() )
     450          56 :         nMSStrByteLen = rSWStr.getLength()+1;
     451          56 :     nMSStrByteLen *= sizeof( sal_Unicode );
     452             : 
     453          56 :     return memcmp( rSWStr.getStr(), pMSStr, nMSStrByteLen );
     454             : }
     455             : 
     456             : /*
     457             : Converts the OOo Asian Typography into a best fit match for Microsoft
     458             : Asian typography. This structure is actually dumped to disk within the
     459             : Dop Writer. Assumption is that rTypo is cleared to 0 on entry
     460             : */
     461          34 : void WW8Export::ExportDopTypography(WW8DopTypography &rTypo)
     462             : {
     463             :     static const sal_Unicode aLangNotBegin[4][WW8DopTypography::nMaxFollowing]=
     464             :     {
     465             :         //Japanese Level 1
     466             :         {
     467             :             0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
     468             :             0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032,
     469             :             0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d,
     470             :             0x300f, 0x3011, 0x3015, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049,
     471             :             0x3063, 0x3083, 0x3085, 0x3087, 0x308e, 0x309b, 0x309c, 0x309d,
     472             :             0x309e, 0x30a1, 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30c3, 0x30e3,
     473             :             0x30e5, 0x30e7, 0x30ee, 0x30f5, 0x30f6, 0x30fb, 0x30fc, 0x30fd,
     474             :             0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b,
     475             :             0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65, 0xff67,
     476             :             0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f,
     477             :             0xff70, 0xff9e, 0xff9f, 0xffe0
     478             :         },
     479             :         //Simplified Chinese
     480             :         {
     481             :             0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d,
     482             :             0x007d, 0x00a8, 0x00b7, 0x02c7, 0x02c9, 0x2015, 0x2016, 0x2019,
     483             :             0x201d, 0x2026, 0x2236, 0x3001, 0x3002, 0x3003, 0x3005, 0x3009,
     484             :             0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x3017, 0xff01, 0xff02,
     485             :             0xff07, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d,
     486             :             0xff40, 0xff5c, 0xff5d, 0xff5e, 0xffe0
     487             :         },
     488             :         //Korean
     489             :         {
     490             :             0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f,
     491             :             0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2032, 0x2033,
     492             :             0x2103, 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0xff01,
     493             :             0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d,
     494             :             0xff5d, 0xffe0
     495             :         },
     496             :         //Traditional Chinese
     497             :         {
     498             :             0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d,
     499             :             0x007d, 0x00a2, 0x00b7, 0x2013, 0x2014, 0x2019, 0x201d, 0x2022,
     500             :             0x2025, 0x2026, 0x2027, 0x2032, 0x2574, 0x3001, 0x3002, 0x3009,
     501             :             0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x301e, 0xfe30, 0xfe31,
     502             :             0xfe33, 0xfe34, 0xfe36, 0xfe38, 0xfe3a, 0xfe3c, 0xfe3e, 0xfe40,
     503             :             0xfe42, 0xfe44, 0xfe4f, 0xfe50, 0xfe51, 0xfe52, 0xfe54, 0xfe55,
     504             :             0xfe56, 0xfe57, 0xfe5a, 0xfe5c, 0xfe5e, 0xff01, 0xff09, 0xff0c,
     505             :             0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff5c, 0xff5d, 0xff64
     506             :         },
     507             :     };
     508             : 
     509             :     static const sal_Unicode aLangNotEnd[4][WW8DopTypography::nMaxLeading] =
     510             :     {
     511             :         //Japanese Level 1
     512             :         {
     513             :             0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018,
     514             :             0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04,
     515             :             0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5
     516             :         },
     517             :         //Simplified Chinese
     518             :         {
     519             :             0x0028, 0x005b, 0x007b, 0x00b7, 0x2018, 0x201c, 0x3008, 0x300a,
     520             :             0x300c, 0x300e, 0x3010, 0x3014, 0x3016, 0xff08, 0xff0e, 0xff3b,
     521             :             0xff5b, 0xffe1, 0xffe5
     522             :         },
     523             :         //Korean
     524             :         {
     525             :             0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c,
     526             :             0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04, 0xff08,
     527             :             0xff3b, 0xff5b, 0xffe6
     528             :         },
     529             :         //Traditional Chinese
     530             :         {
     531             :             0x0028, 0x005b, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c, 0x2035,
     532             :             0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0x301d, 0xfe35,
     533             :             0xfe37, 0xfe39, 0xfe3b, 0xfe3d, 0xfe3f, 0xfe41, 0xfe43, 0xfe59,
     534             :             0xfe5b, 0xfe5d, 0xff08, 0xff5b
     535             :         },
     536             :     };
     537             : 
     538          34 :     const i18n::ForbiddenCharacters *pForbidden = 0;
     539          34 :     const i18n::ForbiddenCharacters *pUseMe = 0;
     540          34 :     sal_uInt8 nUseReserved=0;
     541          34 :     int nNoNeeded=0;
     542             :     /*
     543             :     Now we have some minor difficult issues, to wit...
     544             :     a. MicroSoft Office can only store one set of begin and end characters in
     545             :     a given document, not one per language.
     546             :     b. StarOffice has only a concept of one set of begin and end characters for
     547             :     a given language, i.e. not the two levels of kinsoku in japanese
     548             : 
     549             :     What is unknown as yet is if our default begin and end chars for
     550             :     japanese, chinese tradition, chinese simplified and korean are different
     551             :     in Word and Writer. I already suspect that they are different between
     552             :     different version of word itself.
     553             : 
     554             :     So what have come up with is to simply see if any of the four languages
     555             :     in OOo have been changed away from OUR defaults, and if one has then
     556             :     export that. If more than one has in the future we may hack in something
     557             :     which examines our document properties to see which language is used the
     558             :     most and choose that, for now we choose the first and throw an ASSERT
     559             :     */
     560             : 
     561             :     /*Our default Japanese Level is 2, this is a special MS hack to set this*/
     562          34 :     rTypo.reserved2 = 1;
     563             : 
     564         170 :     for (rTypo.reserved1=8;rTypo.reserved1>0;rTypo.reserved1-=2)
     565             :     {
     566         408 :         if (0 != (pForbidden = pDoc->getIDocumentSettingAccess().getForbiddenCharacters(rTypo.GetConvertedLang(),
     567         272 :             false)))
     568             :         {
     569          14 :             int nIdx = (rTypo.reserved1-2)/2;
     570          14 :             if( lcl_CmpBeginEndChars( pForbidden->endLine,
     571          28 :                     aLangNotEnd[ nIdx ], sizeof(aLangNotEnd[ nIdx ]) ) ||
     572             :                 lcl_CmpBeginEndChars( pForbidden->beginLine,
     573          14 :                     aLangNotBegin[ nIdx ], sizeof(aLangNotBegin[ nIdx ]) ) )
     574             :             {
     575             :                 //One exception for Japanese, if it matches a level 1 we
     576             :                 //can use one extra flag for that, rather than use a custom
     577          14 :                 if (rTypo.GetConvertedLang() == LANGUAGE_JAPANESE)
     578             :                 {
     579          14 :                     if (
     580             :                           !lcl_CmpBeginEndChars
     581             :                             (
     582             :                                 pForbidden->endLine,
     583             :                                 WW8DopTypography::GetJapanNotEndLevel1(),
     584             :                                 rTypo.nMaxLeading * sizeof(sal_Unicode)
     585          14 :                             )
     586          28 :                         &&
     587             :                           !lcl_CmpBeginEndChars
     588             :                             (
     589             :                                 pForbidden->beginLine,
     590             :                                 WW8DopTypography::GetJapanNotBeginLevel1(),
     591             :                                 rTypo.nMaxFollowing * sizeof(sal_Unicode)
     592          14 :                             )
     593             :                         )
     594             :                     {
     595          14 :                         rTypo.reserved2 = 0;
     596          14 :                         continue;
     597             :                     }
     598             :                 }
     599             : 
     600           0 :                 if (!pUseMe)
     601             :                 {
     602           0 :                     pUseMe = pForbidden;
     603           0 :                     nUseReserved = rTypo.reserved1;
     604           0 :                     rTypo.iLevelOfKinsoku = 2;
     605             :                 }
     606           0 :                 nNoNeeded++;
     607             :             }
     608             :         }
     609             :     }
     610             : 
     611             :     OSL_ENSURE( nNoNeeded<=1, "Example of unexportable forbidden chars" );
     612          34 :     rTypo.reserved1=nUseReserved;
     613          34 :     if (rTypo.iLevelOfKinsoku && pUseMe)
     614             :     {
     615             :         rTypo.cchFollowingPunct = msword_cast<sal_Int16>
     616           0 :             (pUseMe->beginLine.getLength());
     617           0 :         if (rTypo.cchFollowingPunct > WW8DopTypography::nMaxFollowing - 1)
     618           0 :             rTypo.cchFollowingPunct = WW8DopTypography::nMaxFollowing - 1;
     619             : 
     620             :         rTypo.cchLeadingPunct = msword_cast<sal_Int16>
     621           0 :             (pUseMe->endLine.getLength());
     622           0 :         if (rTypo.cchLeadingPunct > WW8DopTypography::nMaxLeading - 1)
     623           0 :             rTypo.cchLeadingPunct = WW8DopTypography::nMaxLeading -1;
     624             : 
     625           0 :         memcpy(rTypo.rgxchFPunct,pUseMe->beginLine.getStr(),
     626           0 :             (rTypo.cchFollowingPunct+1)*2);
     627             : 
     628           0 :         memcpy(rTypo.rgxchLPunct,pUseMe->endLine.getStr(),
     629           0 :             (rTypo.cchLeadingPunct+1)*2);
     630             :     }
     631             : 
     632          34 :     const IDocumentSettingAccess* pIDocumentSettingAccess = GetWriter().getIDocumentSettingAccess();
     633             : 
     634          34 :     rTypo.fKerningPunct = sal_uInt16(pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION));
     635          34 :     rTypo.iJustification = pDoc->getIDocumentSettingAccess().getCharacterCompressionType();
     636          34 : }
     637             : 
     638             : // It can only be found something with this method, if it is used within
     639             : // WW8_SwAttrIter::OutAttr() and WW8Export::OutputItemSet()
     640        6448 : const SfxPoolItem* MSWordExportBase::HasItem( sal_uInt16 nWhich ) const
     641             : {
     642        6448 :     const SfxPoolItem* pItem=0;
     643        6448 :     if (pISet)
     644             :     {
     645             :         // if write a EditEngine text, then the WhichIds are greater as
     646             :         // ourer own Ids. So the Id have to translate from our into the
     647             :         // EditEngine Range
     648        5514 :         nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich);
     649        5514 :         if (nWhich && SfxItemState::SET != pISet->GetItemState(nWhich, true, &pItem))
     650        4132 :             pItem = 0;
     651             :     }
     652         934 :     else if( pChpIter )
     653          74 :         pItem = pChpIter->HasTextItem( nWhich );
     654             :     else
     655             :     {
     656             :         OSL_ENSURE( false, "Where is my ItemSet / pChpIter ?" );
     657         860 :         pItem = 0;
     658             :     }
     659        6448 :     return pItem;
     660             : }
     661             : 
     662         864 : const SfxPoolItem& MSWordExportBase::GetItem(sal_uInt16 nWhich) const
     663             : {
     664             :     const SfxPoolItem* pItem;
     665         864 :     if (pISet)
     666             :     {
     667             :         // if write a EditEngine text, then the WhichIds are greater as
     668             :         // ourer own Ids. So the Id have to translate from our into the
     669             :         // EditEngine Range
     670         556 :         nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich);
     671             :         OSL_ENSURE(nWhich != 0, "All broken, Impossible");
     672         556 :         pItem = &pISet->Get(nWhich, true);
     673             :     }
     674         308 :     else if( pChpIter )
     675         308 :         pItem = &pChpIter->GetItem( nWhich );
     676             :     else
     677             :     {
     678             :         OSL_ENSURE( false, "Where is my ItemSet / pChpIter ?" );
     679           0 :         pItem = 0;
     680             :     }
     681         864 :     return *pItem;
     682             : }
     683             : 
     684         272 : WW8_WrPlc1::WW8_WrPlc1( sal_uInt16 nStructSz )
     685         272 :     : nStructSiz( nStructSz )
     686             : {
     687         272 :     nDataLen = 16 * nStructSz;
     688         272 :     pData = new sal_uInt8[ nDataLen ];
     689         272 : }
     690             : 
     691         544 : WW8_WrPlc1::~WW8_WrPlc1()
     692             : {
     693         272 :     delete[] pData;
     694         272 : }
     695             : 
     696           0 : WW8_CP WW8_WrPlc1::Prev() const
     697             : {
     698           0 :     bool b = !aPos.empty();
     699             :     OSL_ENSURE(b,"Prev called on empty list");
     700           0 :     return b ? aPos.back() : 0;
     701             : }
     702             : 
     703          70 : void WW8_WrPlc1::Append( WW8_CP nCp, const void* pNewData )
     704             : {
     705          70 :     sal_uLong nInsPos = aPos.size() * nStructSiz;
     706          70 :     aPos.push_back( nCp );
     707          70 :     if( nDataLen < nInsPos + nStructSiz )
     708             :     {
     709           0 :         sal_uInt8* pNew = new sal_uInt8[ 2 * nDataLen ];
     710           0 :         memcpy( pNew, pData, nDataLen );
     711           0 :         delete[] pData;
     712           0 :         pData = pNew;
     713           0 :         nDataLen *= 2;
     714             :     }
     715          70 :     memcpy( pData + nInsPos, pNewData, nStructSiz );
     716          70 : }
     717             : 
     718         272 : void WW8_WrPlc1::Finish( sal_uLong nLastCp, sal_uLong nSttCp )
     719             : {
     720         272 :     if( !aPos.empty() )
     721             :     {
     722          40 :         aPos.push_back( nLastCp );
     723          40 :         if( nSttCp )
     724          38 :             for( sal_uInt32 n = 0; n < aPos.size(); ++n )
     725          34 :                 aPos[ n ] -= nSttCp;
     726             :     }
     727         272 : }
     728             : 
     729          40 : void WW8_WrPlc1::Write( SvStream& rStrm )
     730             : {
     731             :     sal_uInt32 i;
     732         150 :     for( i = 0; i < aPos.size(); ++i )
     733         110 :         SwWW8Writer::WriteLong( rStrm, aPos[i] );
     734          40 :     if( i )
     735          40 :         rStrm.Write( pData, (i-1) * nStructSiz );
     736          40 : }
     737             : 
     738             : // Class WW8_WrPlcFld for fields
     739             : 
     740         238 : bool WW8_WrPlcFld::Write( WW8Export& rWrt )
     741             : {
     742         238 :     if( WW8_WrPlc1::Count() <= 1 )
     743         232 :         return false;
     744             : 
     745             :     WW8_FC *pfc;
     746             :     sal_Int32 *plc;
     747           6 :     switch (nTxtTyp)
     748             :     {
     749             :         case TXT_MAINTEXT:
     750           2 :             pfc = &rWrt.pFib->fcPlcffldMom;
     751           2 :             plc = &rWrt.pFib->lcbPlcffldMom;
     752           2 :             break;
     753             :         case TXT_HDFT:
     754           2 :             pfc = &rWrt.pFib->fcPlcffldHdr;
     755           2 :             plc = &rWrt.pFib->lcbPlcffldHdr;
     756           2 :             break;
     757             : 
     758             :         case TXT_FTN:
     759           0 :             pfc = &rWrt.pFib->fcPlcffldFtn;
     760           0 :             plc = &rWrt.pFib->lcbPlcffldFtn;
     761           0 :             break;
     762             : 
     763             :         case TXT_EDN:
     764           0 :             pfc = &rWrt.pFib->fcPlcffldEdn;
     765           0 :             plc = &rWrt.pFib->lcbPlcffldEdn;
     766           0 :             break;
     767             : 
     768             :         case TXT_ATN:
     769           0 :             pfc = &rWrt.pFib->fcPlcffldAtn;
     770           0 :             plc = &rWrt.pFib->lcbPlcffldAtn;
     771           0 :             break;
     772             : 
     773             :         case TXT_TXTBOX:
     774           2 :             pfc = &rWrt.pFib->fcPlcffldTxbx;
     775           2 :             plc = &rWrt.pFib->lcbPlcffldTxbx;
     776           2 :             break;
     777             : 
     778             :         case TXT_HFTXTBOX:
     779           0 :             pfc = &rWrt.pFib->fcPlcffldHdrTxbx;
     780           0 :             plc = &rWrt.pFib->lcbPlcffldHdrTxbx;
     781           0 :             break;
     782             : 
     783             :         default:
     784           0 :             pfc = plc = 0;
     785           0 :             break;
     786             :     }
     787             : 
     788           6 :     if( pfc && plc )
     789             :     {
     790           6 :         sal_uLong nFcStart = rWrt.pTableStrm->Tell();
     791           6 :         WW8_WrPlc1::Write( *rWrt.pTableStrm );
     792           6 :         *pfc = nFcStart;
     793           6 :         *plc = rWrt.pTableStrm->Tell() - nFcStart;
     794             :     }
     795           6 :     return true;
     796             : }
     797             : 
     798          34 : bool WW8_WrMagicTable::Write( WW8Export& rWrt )
     799             : {
     800          34 :     if( WW8_WrPlc1::Count() <= 1 )
     801           0 :         return false;
     802          34 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
     803          34 :     WW8_WrPlc1::Write( *rWrt.pTableStrm );
     804          34 :     rWrt.pFib->fcPlcfTch = nFcStart;
     805          34 :     rWrt.pFib->lcbPlcfTch = rWrt.pTableStrm->Tell() - nFcStart;
     806          34 :     return true;
     807             : }
     808             : 
     809          34 : void WW8_WrMagicTable::Append( WW8_CP nCp, sal_uLong nData)
     810             : {
     811             :     SVBT32 nLittle;
     812             :     /*
     813             :     Tell the undocumented table hack that everything between here and the last
     814             :     table position is nontable text, don't do it if the previous position is
     815             :     the same as this one, as that would be a region of 0 length
     816             :     */
     817          34 :     if ((!Count()) || (Prev() != nCp))
     818             :     {
     819          34 :         UInt32ToSVBT32(nData,nLittle);
     820          34 :         WW8_WrPlc1::Append(nCp, nLittle);
     821             :     }
     822          34 : }
     823             : 
     824         478 : void SwWW8Writer::FillCount( SvStream& rStrm, sal_uLong nCount )
     825             : {
     826             :     static const sal_uInt32 aNulls[16] =
     827             :     {
     828             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // 64 Byte
     829             :     };
     830             : 
     831        2202 :     while (nCount > 64)
     832             :     {
     833        1246 :         rStrm.Write( aNulls, 64 );          // in steps of 64-Byte
     834        1246 :         nCount -= 64;
     835             :     }
     836         478 :     rStrm.Write( aNulls, nCount );          // write the rest ( 0 .. 64 Bytes )
     837         478 : }
     838             : 
     839         102 : sal_uLong SwWW8Writer::FillUntil( SvStream& rStrm, sal_uLong nEndPos )
     840             : {
     841         102 :     sal_uLong nCurPos = rStrm.Tell();
     842         102 :     if( !nEndPos )                          // nEndPos == 0 -> next Page
     843          68 :         nEndPos = (nCurPos + 0x1ff) & ~0x1ffUL;
     844             : 
     845         102 :     if( nEndPos > nCurPos )
     846          68 :         SwWW8Writer::FillCount( rStrm, nEndPos - nCurPos );
     847             : #if OSL_DEBUG_LEVEL > 0
     848             :     else
     849             :         OSL_ENSURE( nEndPos == nCurPos, "Falsches FillUntil()" );
     850             : #endif
     851         102 :     return rStrm.Tell();
     852             : }
     853             : 
     854          68 : WW8_WrPlcPn::WW8_WrPlcPn(WW8Export& rWr, ePLCFT ePl, WW8_FC nStartFc)
     855             :     : rWrt(rWr)
     856             :     , nFkpStartPage(0)
     857             :     , ePlc(ePl)
     858             :     , bWrtWW8(true)
     859          68 :     , nMark(0)
     860             : {
     861          68 :     WW8_WrFkp* pF = new WW8_WrFkp( ePlc, nStartFc, rWrt.bWrtWW8 );
     862          68 :     aFkps.push_back( pF );
     863          68 : }
     864             : 
     865          68 : WW8_WrPlcPn::~WW8_WrPlcPn()
     866             : {
     867          68 : }
     868             : 
     869          34 : sal_uInt8 *WW8_WrPlcPn::CopyLastSprms(sal_uInt8 &rLen)
     870             : {
     871          34 :     WW8_WrFkp& rF = aFkps.back();
     872          34 :     return rF.CopyLastSprms(rLen, rWrt.bWrtWW8);
     873             : }
     874             : 
     875        2112 : void WW8_WrPlcPn::AppendFkpEntry(WW8_FC nEndFc,short nVarLen,const sal_uInt8* pSprms)
     876             : {
     877        2112 :     WW8_WrFkp* pF = &aFkps.back();
     878             : 
     879             :     // big sprm? build the sprmPHugePapx
     880        2112 :     sal_uInt8* pNewSprms = (sal_uInt8*)pSprms;
     881             :     sal_uInt8 aHugePapx[ 8 ];
     882        2112 :     if( rWrt.bWrtWW8 && PAP == ePlc && 488 < nVarLen )
     883             :     {
     884           8 :         sal_uInt8* p = aHugePapx;
     885           8 :         *p++ = *pSprms++;           // set style Id
     886           8 :         *p++ = *pSprms++;
     887           8 :         nVarLen -= 2;
     888             : 
     889           8 :         long nDataPos = rWrt.pDataStrm->Tell();
     890           8 :         SwWW8Writer::WriteShort( *rWrt.pDataStrm, nVarLen );
     891           8 :         rWrt.pDataStrm->Write( pSprms, nVarLen );
     892             : 
     893           8 :         Set_UInt16( p, 0x6646 );    // set SprmCode
     894           8 :         Set_UInt32( p, nDataPos );  // set startpos (FC) in the datastream
     895           8 :         nVarLen = static_cast< short >(p - aHugePapx);
     896           8 :         pSprms = pNewSprms = aHugePapx;
     897             :     }
     898             :     // if append at the same FC-EndPos and there are sprms, then get the old
     899             :     // sprms and erase it; they will append now with the new sprms
     900        2104 :     else if( nVarLen && pF->IsEqualPos( nEndFc ))
     901          14 :         pF->MergeToNew( nVarLen, pNewSprms );
     902             :     // has the prev EndFC an empty sprm and the current is empty too, then
     903             :     // expand only the old EndFc to the new EndFc
     904        2090 :     else if( !nVarLen && pF->IsEmptySprm() )
     905             :     {
     906         190 :         pF->SetNewEnd( nEndFc );
     907         190 :         return ;
     908             :     }
     909             : 
     910        1922 :     bool bOk = pF->Append(nEndFc, nVarLen, pNewSprms);
     911        1922 :     if( !bOk )
     912             :     {
     913          88 :         pF->Combine();
     914          88 :         pF = new WW8_WrFkp( ePlc, pF->GetEndFc(), rWrt.bWrtWW8 ); // Start new Fkp == end of old Fkp
     915             : 
     916          88 :         aFkps.push_back( pF );
     917          88 :         if( !pF->Append( nEndFc, nVarLen, pNewSprms ) )
     918             :         {
     919             :             OSL_ENSURE( false, "Sprm liess sich nicht einfuegen" );
     920             :         }
     921             :     }
     922        1922 :     if( pNewSprms != pSprms )   //Merge to new has created a new block
     923          14 :         delete[] pNewSprms;
     924             : }
     925             : 
     926          68 : void WW8_WrPlcPn::WriteFkps()
     927             : {
     928          68 :     nFkpStartPage = (sal_uInt16) ( SwWW8Writer::FillUntil( rWrt.Strm() ) >> 9 );
     929             : 
     930         224 :     for( sal_uInt16 i = 0; i < aFkps.size(); i++ )
     931         156 :         aFkps[ i ].Write( rWrt.Strm(), *rWrt.pGrf );
     932             : 
     933          68 :     if( CHP == ePlc )
     934             :     {
     935          34 :         rWrt.pFib->pnChpFirst = nFkpStartPage;
     936          34 :         rWrt.pFib->cpnBteChp = aFkps.size();
     937             :     }
     938             :     else
     939             :     {
     940          34 :         rWrt.pFib->pnPapFirst = nFkpStartPage;
     941          34 :         rWrt.pFib->cpnBtePap = aFkps.size();
     942             :     }
     943          68 : }
     944             : 
     945          68 : void WW8_WrPlcPn::WritePlc()
     946             : {
     947          68 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
     948             :     sal_uInt16 i;
     949             : 
     950         224 :     for( i = 0; i < aFkps.size(); i++ )
     951             :         SwWW8Writer::WriteLong( *rWrt.pTableStrm,
     952         156 :                                 aFkps[ i ].GetStartFc() );
     953             : 
     954             :     SwWW8Writer::WriteLong( *rWrt.pTableStrm,
     955          68 :                                 aFkps[ i - 1 ].GetEndFc() );
     956             : 
     957             :     // fuer jedes FKP die Page ausgeben
     958          68 :     if( rWrt.bWrtWW8)                   // for WW97 Long output
     959         224 :         for ( i = 0; i < aFkps.size(); i++)
     960         156 :             SwWW8Writer::WriteLong( *rWrt.pTableStrm, i + nFkpStartPage );
     961             :     else                            // for WW95 Short output
     962           0 :         for ( i = 0; i < aFkps.size(); i++)
     963           0 :             SwWW8Writer::WriteShort( *rWrt.pTableStrm, i + nFkpStartPage );
     964             : 
     965          68 :     if( CHP == ePlc )
     966             :     {
     967          34 :         rWrt.pFib->fcPlcfbteChpx = nFcStart;
     968          34 :         rWrt.pFib->lcbPlcfbteChpx = rWrt.pTableStrm->Tell() - nFcStart;
     969             :     }
     970             :     else
     971             :     {
     972          34 :         rWrt.pFib->fcPlcfbtePapx = nFcStart;
     973          34 :         rWrt.pFib->lcbPlcfbtePapx = rWrt.pTableStrm->Tell() - nFcStart;
     974             :     }
     975          68 : }
     976             : 
     977         156 : WW8_WrFkp::WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8)
     978             :     : ePlc(ePl), nStartGrp(511), nOldStartGrp(511),
     979             :     nItemSize( ( CHP == ePl ) ? 1 : ( bWrtWW8 ? 13 : 7 )),
     980         156 :     nIMax(0), nOldVarLen(0), bCombined(false)
     981             : {
     982         156 :     pFkp = (sal_uInt8*)new sal_Int32[128];           // 512 Byte
     983         156 :     pOfs = (sal_uInt8*)new sal_Int32[128];           // 512 Byte
     984         156 :     memset( pFkp, 0, 4 * 128 );
     985         156 :     memset( pOfs, 0, 4 * 128 );
     986         156 :     ( (sal_Int32*)pFkp )[0] = nStartFc;         // 0th entry FC at nStartFc
     987         156 : }
     988             : 
     989         156 : WW8_WrFkp::~WW8_WrFkp()
     990             : {
     991         156 :     delete[] (sal_Int32 *)pFkp;
     992         156 :     delete[] (sal_Int32 *)pOfs;
     993         156 : }
     994             : 
     995        1794 : sal_uInt8 WW8_WrFkp::SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms )
     996             : {
     997        1794 :     if( 3 < nVarLen )
     998             :     {
     999             :         // if the sprms contained picture-references then never equal!
    1000       34286 :         for( sal_uInt8 n = static_cast< sal_uInt8 >(nVarLen - 1); 3 < n; --n )
    1001       32810 :             if( pSprms[ n ] == GRF_MAGIC_3 &&
    1002           6 :                 pSprms[ n-1 ] == GRF_MAGIC_2 &&
    1003           2 :                 pSprms[ n-2 ] == GRF_MAGIC_1 )
    1004           2 :                     return 0;
    1005             :     }
    1006             : 
    1007             :     short i;
    1008       14500 :     for( i = 0; i < nIMax; i++ )
    1009             :     {
    1010       13530 :         sal_uInt8 nStart = pOfs[i * nItemSize];
    1011       13530 :         if( nStart )
    1012             :         {                               // has Sprms
    1013       12362 :             const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
    1014       24724 :             if( ( CHP == ePlc
    1015        7666 :                     ? (*p++ == nVarLen)
    1016        4696 :                     : (((sal_uInt16)*p++ << 1 ) == (( nVarLen+1) & 0xfffe)) )
    1017       24724 :                 && !memcmp( p, pSprms, nVarLen ) )
    1018         822 :                     return nStart;                      // found it
    1019             :         }
    1020             :     }
    1021         970 :     return 0;           // didn't found it
    1022             : }
    1023             : 
    1024          34 : sal_uInt8 *WW8_WrFkp::CopyLastSprms(sal_uInt8 &rLen, bool bVer8)
    1025             : {
    1026          34 :     rLen=0;
    1027          34 :     sal_uInt8 *pStart=0,*pRet=0;
    1028             : 
    1029          34 :     if (!bCombined)
    1030          34 :         pStart = pOfs;
    1031             :     else
    1032           0 :         pStart = pFkp + ( nIMax + 1 ) * 4;
    1033             : 
    1034          34 :     sal_uInt8 nStart = *(pStart + (nIMax-1) * nItemSize);
    1035             : 
    1036          34 :     const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
    1037             : 
    1038          34 :     if (!*p && bVer8)
    1039          28 :         p++;
    1040             : 
    1041          34 :     if (*p)
    1042             :     {
    1043          34 :         rLen = *p++;
    1044          34 :         if (PAP == ePlc)
    1045          34 :             rLen *= 2;
    1046          34 :         pRet = new sal_uInt8[rLen];
    1047          34 :         memcpy(pRet,p,rLen);
    1048             :     }
    1049          34 :     return pRet;
    1050             : }
    1051             : 
    1052        2010 : bool WW8_WrFkp::Append( WW8_FC nEndFc, sal_uInt16 nVarLen, const sal_uInt8* pSprms )
    1053             : {
    1054             :     assert((!nVarLen || pSprms) && "Item pointer missing");
    1055             : 
    1056             :     OSL_ENSURE( nVarLen < ( ( ePlc == PAP ) ? 497U : 502U ), "Sprms too long !" );
    1057             : 
    1058        2010 :     if( bCombined )
    1059             :     {
    1060             :         OSL_ENSURE( false, "Fkp::Append: Fkp is already combined" );
    1061           0 :         return false;
    1062             :     }
    1063        2010 :     sal_Int32 n = ((sal_Int32*)pFkp)[nIMax];        // last entry
    1064        2010 :     if( nEndFc <= n )
    1065             :     {
    1066             :         OSL_ENSURE( nEndFc >= n, "+Fkp: FC backwards" );
    1067             :         OSL_ENSURE( !nVarLen || !pSprms || nEndFc != n,
    1068             :                                     "+Fkp: selber FC mehrfach benutzt" );
    1069             :                         // selber FC ohne Sprm wird ohne zu mosern ignoriert.
    1070             : 
    1071          50 :         return true;    // ignore (do not create a new Fkp)
    1072             :     }
    1073             : 
    1074        1960 :     sal_uInt8 nOldP = ( nVarLen ) ? SearchSameSprm( nVarLen, pSprms ) : 0;
    1075             :                                             // Combine equal entries
    1076        1960 :     short nOffset=0, nPos = nStartGrp;
    1077        1960 :     if (nVarLen && !nOldP)
    1078             :     {
    1079         972 :         nPos = PAP == ePlc
    1080         748 :                 ? ( 13 == nItemSize     // HACK: PAP and bWrtWW8 !!
    1081             :                      ? (nStartGrp & 0xFFFE ) - nVarLen - 1
    1082             :                      : (nStartGrp - (((nVarLen + 1) & 0xFFFE)+1)) & 0xFFFE )
    1083        1720 :                 : ((nStartGrp - nVarLen - 1) & 0xFFFE);
    1084         972 :         if( nPos < 0 )
    1085          26 :             return false;           // doesn't fit at all
    1086         946 :         nOffset = nPos;             // save offset (can also be uneven!)
    1087         946 :         nPos &= 0xFFFE;             // Pos for Sprms ( gerade Pos )
    1088             :     }
    1089             : 
    1090        1934 :     if( (sal_uInt16)nPos <= ( nIMax + 2U ) * 4U + ( nIMax + 1U ) * nItemSize )
    1091             :                                             // does it fits behind the CPs and offsets?
    1092          62 :         return false;                       // no
    1093             : 
    1094        1872 :     ((sal_Int32*)pFkp)[nIMax + 1] = nEndFc;     // insert FC
    1095             : 
    1096        1872 :     nOldVarLen = (sal_uInt8)nVarLen;
    1097        1872 :     if( nVarLen && !nOldP )
    1098             :     {               // insert it for real
    1099         904 :         nOldStartGrp = nStartGrp;
    1100             : 
    1101         904 :         nStartGrp = nPos;
    1102         904 :         pOfs[nIMax * nItemSize] = (sal_uInt8)( nStartGrp >> 1 );
    1103             :                                             // ( DatenAnfg >> 1 ) insert
    1104         904 :         sal_uInt8 nCnt = static_cast< sal_uInt8 >(CHP == ePlc
    1105             :                         ? ( nVarLen < 256 ) ? (sal_uInt8) nVarLen : 255
    1106         904 :                         : ( ( nVarLen + 1 ) >> 1 ));
    1107             : 
    1108         904 :         pFkp[ nOffset ] = nCnt;                     // Enter data length
    1109         904 :         memcpy( pFkp + nOffset + 1, pSprms, nVarLen );  // store Sprms
    1110             :     }
    1111             :     else
    1112             :     {
    1113             :         // do not enter for real ( no Sprms or recurrence )
    1114             :         // DatenAnfg 0 ( no data ) or recurrence
    1115         968 :         pOfs[nIMax * nItemSize] = nOldP;
    1116             :     }
    1117        1872 :     nIMax++;
    1118        1872 :     return true;
    1119             : }
    1120             : 
    1121         244 : bool WW8_WrFkp::Combine()
    1122             : {
    1123         244 :     if( bCombined )
    1124          88 :         return false;
    1125         156 :     if( nIMax )
    1126         156 :         memcpy( pFkp + ( nIMax + 1 ) * 4, pOfs, nIMax * nItemSize );
    1127         156 :     delete[] pOfs;
    1128         156 :     pOfs = 0;
    1129         156 :     ((sal_uInt8*)pFkp)[511] = nIMax;
    1130         156 :     bCombined = true;
    1131             : 
    1132             : #if defined OSL_BIGENDIAN           // only the FCs will be rotated here
    1133             :     sal_uInt16 i;                   // the Sprms must be rotated elsewhere
    1134             : 
    1135             :     sal_uInt32* p;
    1136             :     for( i = 0, p = (sal_uInt32*)pFkp; i <= nIMax; i++, p++ )
    1137             :         *p = OSL_SWAPDWORD( *p );
    1138             : #endif // ifdef OSL_BIGENDIAN
    1139             : 
    1140         156 :     return true;
    1141             : }
    1142             : 
    1143         156 : void WW8_WrFkp::Write( SvStream& rStrm, SwWW8WrGrf& rGrf )
    1144             : {
    1145         156 :     Combine();                      // If not already combined
    1146             : 
    1147             :     sal_uInt8* p;               //  Suche Magic fuer nPicLocFc
    1148         156 :     sal_uInt8* pEnd = pFkp + nStartGrp;
    1149       29396 :     for( p = pFkp + 511 - 4; p >= pEnd; p-- )
    1150             :     {
    1151       29240 :         if( *p != GRF_MAGIC_1 )     // search for signature 0x12 0x34 0x56 0xXX
    1152       58278 :             continue;
    1153         200 :         if( *(p+1) != GRF_MAGIC_2 )
    1154         198 :             continue;
    1155           2 :         if( *(p+2) != GRF_MAGIC_3 )
    1156           0 :             continue;
    1157             : 
    1158             :         SVBT32 nPos;                // signature found
    1159           2 :         UInt32ToSVBT32( rGrf.GetFPos(), nPos );   // FilePos the graphics
    1160           2 :         memcpy( p, nPos, 4 );       // patch FilePos over the signature
    1161             :     }
    1162         156 :     rStrm.Write( pFkp, 512 );
    1163         156 : }
    1164             : 
    1165          14 : void WW8_WrFkp::MergeToNew( short& rVarLen, sal_uInt8 *& rpNewSprms )
    1166             : {
    1167          14 :     sal_uInt8 nStart = pOfs[ (nIMax-1) * nItemSize ];
    1168          14 :     if( nStart )
    1169             :     {   // has Sprms
    1170          14 :         sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 );
    1171             : 
    1172             :         // old and new equal? Then copy only one into the new sprms
    1173          14 :         if( nOldVarLen == rVarLen && !memcmp( p+1, rpNewSprms, nOldVarLen ))
    1174             :         {
    1175           0 :             sal_uInt8* pNew = new sal_uInt8[ nOldVarLen ];
    1176           0 :             memcpy( pNew, p+1, nOldVarLen );
    1177           0 :             rpNewSprms = pNew;
    1178             :         }
    1179             :         else
    1180             :         {
    1181          14 :             sal_uInt8* pNew = new sal_uInt8[ nOldVarLen + rVarLen ];
    1182          14 :             memcpy( pNew, p+1, nOldVarLen );
    1183          14 :             memcpy( pNew + nOldVarLen, rpNewSprms, rVarLen );
    1184             : 
    1185          14 :             rpNewSprms = pNew;
    1186          14 :             rVarLen = rVarLen + nOldVarLen;
    1187             :         }
    1188          14 :         --nIMax;
    1189             :         // if this sprms dont used from others, remove it
    1190          14 :         bool bFnd = false;
    1191         252 :         for (sal_uInt16 n = 0; n < nIMax; ++n)
    1192             :         {
    1193         244 :             if (nStart == pOfs[n * nItemSize])
    1194             :             {
    1195           6 :                 bFnd = true;
    1196           6 :                 break;
    1197             :             }
    1198             :         }
    1199          14 :         if (!bFnd)
    1200             :         {
    1201           8 :             nStartGrp = nOldStartGrp;
    1202           8 :             memset( p, 0, nOldVarLen+1 );
    1203             :         }
    1204             :     }
    1205          14 : }
    1206             : 
    1207         156 : WW8_FC WW8_WrFkp::GetStartFc() const
    1208             : {
    1209             : // wenn bCombined, dann ist das Array ab pFkp schon Bytemaessig auf LittleEndian
    1210             : // umgedreht, d.h. zum Herausholen der Anfangs- und Endpositionen muss
    1211             : // zurueckgedreht werden.
    1212         156 :     if( bCombined )
    1213         156 :         return SVBT32ToUInt32( pFkp );        // 0. Element
    1214           0 :     return ((sal_Int32*)pFkp)[0];
    1215             : }
    1216             : 
    1217         156 : WW8_FC WW8_WrFkp::GetEndFc() const
    1218             : {
    1219         156 :     if( bCombined )
    1220         156 :         return SVBT32ToUInt32( &(pFkp[nIMax*4]) );    // nIMax-tes SVBT32-Element
    1221           0 :     return ((sal_Int32*)pFkp)[nIMax];
    1222             : }
    1223             : 
    1224             : // Method for managing the piece table
    1225          34 : WW8_WrPct::WW8_WrPct(WW8_FC nfcMin, bool bSaveUniCode)
    1226          34 :     : nOldFc(nfcMin), bIsUni(bSaveUniCode)
    1227             : {
    1228          34 :     AppendPc( nOldFc, bIsUni );
    1229          34 : }
    1230             : 
    1231          34 : WW8_WrPct::~WW8_WrPct()
    1232             : {
    1233          34 : }
    1234             : 
    1235             : // Fill the piece and create a new one
    1236          34 : void WW8_WrPct::AppendPc(WW8_FC nStartFc, bool bIsUnicode)
    1237             : {
    1238          34 :     WW8_CP nStartCp = nStartFc - nOldFc;    // substract the beginning of the text
    1239          34 :     if ( !nStartCp )
    1240             :     {
    1241          34 :         if ( !aPcts.empty() )
    1242             :         {
    1243             :             OSL_ENSURE( 1 == aPcts.size(), "Leeres Piece !!");
    1244           0 :             aPcts.pop_back( );
    1245             :         }
    1246             :     }
    1247             : 
    1248          34 :     nOldFc = nStartFc;                      // remember StartFc as old
    1249             : 
    1250          34 :     if( bIsUni )
    1251          34 :         nStartCp >>= 1;                 // for Unicode: number of characters / 2
    1252             : 
    1253          34 :     if ( !bIsUnicode )
    1254             :     {
    1255           0 :         nStartFc <<= 1;                 // Address * 2
    1256           0 :         nStartFc |= 0x40000000;         // second last bit for non-Unicode
    1257             :     }
    1258             : 
    1259          34 :     if( !aPcts.empty() )
    1260           0 :         nStartCp += aPcts.back().GetStartCp();
    1261             : 
    1262          34 :     WW8_WrPc* pPc = new WW8_WrPc( nStartFc, nStartCp );
    1263          34 :     aPcts.push_back( pPc );
    1264             : 
    1265          34 :     bIsUni = bIsUnicode;
    1266          34 : }
    1267             : 
    1268          34 : void WW8_WrPct::WritePc( WW8Export& rWrt )
    1269             : {
    1270             :     sal_uLong nPctStart;
    1271             :     sal_uLong nOldPos, nEndPos;
    1272          34 :     boost::ptr_vector<WW8_WrPc>::iterator aIter;
    1273             : 
    1274          34 :     nPctStart = rWrt.pTableStrm->Tell();                    // Start piece table
    1275          34 :     rWrt.pTableStrm->WriteChar( ( char )0x02 );                       // Status byte PCT
    1276          34 :     nOldPos = nPctStart + 1;                                // remember Position
    1277          34 :     SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );          // then the length
    1278             : 
    1279          68 :     for( aIter = aPcts.begin(); aIter != aPcts.end(); ++aIter )     // ranges
    1280             :         SwWW8Writer::WriteLong( *rWrt.pTableStrm,
    1281          34 :                                 aIter->GetStartCp() );
    1282             : 
    1283             :     // calculate the last Pos
    1284          34 :     sal_uLong nStartCp = rWrt.pFib->fcMac - nOldFc;
    1285          34 :     if( bIsUni )
    1286          34 :         nStartCp >>= 1;             // For Unicode: number of characters / 2
    1287          34 :     nStartCp += aPcts.back().GetStartCp();
    1288          34 :     SwWW8Writer::WriteLong( *rWrt.pTableStrm, nStartCp );
    1289             : 
    1290             :     // piece references
    1291          68 :     for ( aIter = aPcts.begin(); aIter != aPcts.end(); ++aIter )
    1292             :     {
    1293          34 :         SwWW8Writer::WriteShort( *rWrt.pTableStrm, aIter->GetStatus());
    1294          34 :         SwWW8Writer::WriteLong( *rWrt.pTableStrm, aIter->GetStartFc());
    1295          34 :         SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0);          // PRM=0
    1296             :     }
    1297             : 
    1298             :     // entries in the FIB
    1299          34 :     rWrt.pFib->fcClx = nPctStart;
    1300          34 :     nEndPos = rWrt.pTableStrm->Tell();
    1301          34 :     rWrt.pFib->lcbClx = nEndPos - nPctStart;
    1302             : 
    1303             :     // and register the length as well
    1304             :     SwWW8Writer::WriteLong( *rWrt.pTableStrm, nOldPos,
    1305          34 :                             nEndPos - nPctStart-5 );
    1306             : 
    1307          34 : }
    1308             : 
    1309         852 : void WW8_WrPct::SetParaBreak()
    1310             : {
    1311             :     OSL_ENSURE( !aPcts.empty(),"SetParaBreak : aPcts.empty()" );
    1312         852 :     aPcts.back().SetStatus();
    1313         852 : }
    1314             : 
    1315         616 : WW8_CP WW8_WrPct::Fc2Cp( sal_uLong nFc ) const
    1316             : {
    1317             :     OSL_ENSURE( nFc >= (sal_uLong)nOldFc, "FilePos lies in front of last piece" );
    1318             :     OSL_ENSURE( ! aPcts.empty(), "Fc2Cp no piece available" );
    1319             : 
    1320         616 :     nFc -= nOldFc;
    1321         616 :     if( bIsUni )
    1322         616 :         nFc /= 2;
    1323         616 :     return nFc + aPcts.back().GetStartCp();
    1324             : }
    1325             : 
    1326        1474 : void WW8Export::AppendBookmarks( const SwTxtNode& rNd, sal_Int32 nAktPos, sal_Int32 nLen )
    1327             : {
    1328        1474 :     std::vector< const ::sw::mark::IMark* > aArr;
    1329             :     sal_uInt16 nCntnt;
    1330        1474 :     const sal_Int32 nAktEnd = nAktPos + nLen;
    1331        1474 :     if( GetWriter().GetBookmarks( rNd, nAktPos, nAktEnd, aArr ))
    1332             :     {
    1333          20 :         sal_uLong nNd = rNd.GetIndex(), nSttCP = Fc2Cp( Strm().Tell() );
    1334          44 :         for( sal_uInt16 n = 0; n < aArr.size(); ++n )
    1335             :         {
    1336          24 :             const ::sw::mark::IMark& rBkmk = *(aArr[ n ]);
    1337          24 :             if(dynamic_cast< const ::sw::mark::IFieldmark *>(&rBkmk))
    1338           0 :                 continue;
    1339             : 
    1340          24 :             const SwPosition* pPos = &rBkmk.GetMarkPos();
    1341          24 :             const SwPosition* pOPos = 0;
    1342          24 :             if(rBkmk.IsExpanded())
    1343          20 :                 pOPos = &rBkmk.GetOtherMarkPos();
    1344          44 :             if( pOPos && pOPos->nNode == pPos->nNode &&
    1345          20 :                 pOPos->nContent < pPos->nContent )
    1346             :             {
    1347           0 :                 pPos = pOPos;
    1348           0 :                 pOPos = &rBkmk.GetMarkPos();
    1349             :             }
    1350             : 
    1351          78 :             if( !pOPos || ( nNd == pPos->nNode.GetIndex() &&
    1352          50 :                 ( nCntnt = pPos->nContent.GetIndex() ) >= nAktPos &&
    1353          10 :                 nCntnt < nAktEnd ) )
    1354             :             {
    1355          14 :                 sal_uLong nCp = nSttCP + pPos->nContent.GetIndex() - nAktPos;
    1356          14 :                 pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk);
    1357             :             }
    1358          84 :             if( pOPos && nNd == pOPos->nNode.GetIndex() &&
    1359          84 :                 ( nCntnt = pOPos->nContent.GetIndex() ) >= nAktPos &&
    1360          20 :                 nCntnt < nAktEnd )
    1361             :             {
    1362          10 :                 sal_uLong nCp = nSttCP + pOPos->nContent.GetIndex() - nAktPos;
    1363          10 :                 pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk);
    1364             :             }
    1365             :         }
    1366        1474 :     }
    1367        1474 : }
    1368             : 
    1369        1474 : void WW8Export::AppendAnnotationMarks(const SwTxtNode& rNode, sal_Int32 nAktPos, sal_Int32 nLen)
    1370             : {
    1371        1474 :     IMarkVector aMarks;
    1372        1474 :     if (GetAnnotationMarks(rNode, nAktPos, nAktPos + nLen, aMarks))
    1373             :     {
    1374          52 :         for (IMarkVector::const_iterator it = aMarks.begin(), end = aMarks.end(); it != end; ++it)
    1375             :         {
    1376          30 :             sw::mark::IMark* pMark = (*it);
    1377          30 :             const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
    1378          30 :             if (nStart == nAktPos)
    1379             :             {
    1380           8 :                 pAtn->AddRangeStartPosition(pMark->GetName(), Fc2Cp(Strm().Tell()));
    1381        1490 :                 return;
    1382             :             }
    1383             :         }
    1384        1466 :     }
    1385             : }
    1386             : 
    1387           0 : void WW8Export::MoveFieldMarks(WW8_CP nFrom, WW8_CP nTo)
    1388             : {
    1389           0 :     pBkmks->MoveFieldMarks(nFrom, nTo);
    1390           0 : }
    1391             : 
    1392           0 : void WW8Export::AppendBookmark( const OUString& rName, bool bSkip )
    1393             : {
    1394           0 :     sal_uLong nSttCP = Fc2Cp( Strm().Tell() ) + ( bSkip? 1: 0 );
    1395           0 :     pBkmks->Append( nSttCP, rName );
    1396           0 : }
    1397             : 
    1398             : // #i120928 collect all the graphics of bullets applied to paragraphs
    1399         870 : int MSWordExportBase::CollectGrfsOfBullets()
    1400             : {
    1401         870 :     m_vecBulletPic.clear();
    1402             : 
    1403         870 :     if ( pDoc )
    1404             :     {
    1405         870 :         size_t nCountRule = pDoc->GetNumRuleTbl().size();
    1406       14116 :         for (size_t n = 0; n < nCountRule; ++n)
    1407             :         {
    1408       13246 :             const SwNumRule &rRule = *( pDoc->GetNumRuleTbl().at(n) );
    1409       13246 :             sal_uInt16 nLevels = rRule.IsContinusNum() ? 1 : 9;
    1410      132316 :             for (sal_uInt16 nLvl = 0; nLvl < nLevels; ++nLvl)
    1411             :             {
    1412      119070 :                 const SwNumFmt &rFmt = rRule.Get(nLvl);
    1413      119070 :                 if (SVX_NUM_BITMAP != rFmt.GetNumberingType())
    1414             :                 {
    1415      119040 :                     continue;
    1416             :                 }
    1417          30 :                 const Graphic *pGraf = rFmt.GetBrush()? rFmt.GetBrush()->GetGraphic():0;
    1418          30 :                 if ( pGraf )
    1419             :                 {
    1420          30 :                     bool bHas = false;
    1421          32 :                     for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
    1422             :                     {
    1423           2 :                         if (m_vecBulletPic[i]->GetChecksum() == pGraf->GetChecksum())
    1424             :                         {
    1425           0 :                             bHas = true;
    1426           0 :                             break;
    1427             :                         }
    1428             :                     }
    1429          30 :                     if (!bHas)
    1430             :                     {
    1431          30 :                         Size aSize(pGraf->GetPrefSize());
    1432          30 :                         if (0 != aSize.Height() && 0 != aSize.Width())
    1433          14 :                            m_vecBulletPic.push_back(pGraf);
    1434             :                     }
    1435             :                 }
    1436             :             }
    1437             :         }
    1438             :     }
    1439             : 
    1440         870 :     return m_vecBulletPic.size();
    1441             : }
    1442             : 
    1443          80 : void MSWordExportBase::BulletDefinitions()
    1444             : {
    1445          90 :     for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
    1446             :     {
    1447          10 :         const MapMode aMapMode(MAP_TWIP);
    1448          10 :         const Graphic& rGraphic = *m_vecBulletPic[i];
    1449          10 :         Size aSize(rGraphic.GetPrefSize());
    1450          10 :         if (MAP_PIXEL == rGraphic.GetPrefMapMode().GetMapUnit())
    1451           0 :             aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapMode);
    1452             :         else
    1453          10 :             aSize = OutputDevice::LogicToLogic(aSize,rGraphic.GetPrefMapMode(), aMapMode);
    1454             : 
    1455          10 :         if (0 != aSize.Height() && 0 != aSize.Width())
    1456          10 :             AttrOutput().BulletDefinition(i, rGraphic, aSize);
    1457          10 :     }
    1458          80 : }
    1459             : 
    1460             : //Export Graphic of Bullets
    1461          34 : void WW8Export::ExportGrfBullet(const SwTxtNode& rNd)
    1462             : {
    1463          34 :     int nCount = CollectGrfsOfBullets();
    1464          34 :     if (nCount > 0)
    1465             :     {
    1466           0 :         SwPosition aPos(rNd);
    1467           0 :         OUString aPicBullets("_PictureBullets");
    1468           0 :         AppendBookmark(aPicBullets);
    1469           0 :         for (int i = 0; i < nCount; i++)
    1470             :         {
    1471           0 :             sw::Frame aFrame(*(m_vecBulletPic[i]), aPos);
    1472           0 :             OutGrfBullets(aFrame);
    1473           0 :         }
    1474           0 :         AppendBookmark(aPicBullets);
    1475             :     }
    1476          34 : }
    1477             : 
    1478             : static sal_uInt8 nAttrMagicIdx = 0;
    1479           0 : void WW8Export::OutGrfBullets(const sw::Frame & rFrame)
    1480             : {
    1481           0 :     if ( !pGrf || !pChpPlc || !pO )
    1482           0 :         return;
    1483             : 
    1484           0 :     pGrf->Insert(rFrame);
    1485           0 :     pChpPlc->AppendFkpEntry( Strm().Tell(), pO->size(), pO->data() );
    1486           0 :     pO->clear();
    1487             :     //if links...
    1488           0 :     WriteChar( (char)1 );
    1489             : 
    1490             :     sal_uInt8 aArr[ 22 ];
    1491           0 :     sal_uInt8* pArr = aArr;
    1492             : 
    1493             :     // sprmCFSpec
    1494           0 :     if( bWrtWW8 )
    1495           0 :         Set_UInt16( pArr, 0x855 );
    1496             :     else
    1497           0 :         Set_UInt8( pArr, 117 );
    1498           0 :     Set_UInt8( pArr, 1 );
    1499             : 
    1500           0 :     Set_UInt16( pArr, 0x083c );
    1501           0 :     Set_UInt8( pArr, 0x81 );
    1502             : 
    1503             :     // sprmCPicLocation
    1504           0 :     if( bWrtWW8 )
    1505           0 :         Set_UInt16( pArr, 0x6a03 );
    1506             :     else
    1507             :     {
    1508           0 :         Set_UInt8( pArr, 68 );
    1509           0 :         Set_UInt8( pArr, 4 );
    1510             :     }
    1511           0 :     Set_UInt32( pArr, GRF_MAGIC_321 );
    1512             : 
    1513             :     //extern  nAttrMagicIdx;
    1514           0 :     --pArr;
    1515           0 :     Set_UInt8( pArr, nAttrMagicIdx++ );
    1516           0 :     pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
    1517             : }
    1518             : 
    1519           8 : int MSWordExportBase::GetGrfIndex(const SvxBrushItem& rBrush)
    1520             : {
    1521           8 :     int nIndex = -1;
    1522             : 
    1523           8 :     const Graphic* pGraphic = rBrush.GetGraphic();
    1524           8 :     if (pGraphic)
    1525             :     {
    1526          10 :         for (size_t i = 0; i < m_vecBulletPic.size(); ++i)
    1527             :         {
    1528           8 :             if (m_vecBulletPic[i]->GetChecksum() == pGraphic->GetChecksum())
    1529             :             {
    1530           6 :                 nIndex = i;
    1531           6 :                 break;
    1532             :             }
    1533             :         }
    1534             :     }
    1535             : 
    1536           8 :     return nIndex;
    1537             : }
    1538             : 
    1539           0 : void MSWordExportBase::AppendWordBookmark( const OUString& rName )
    1540             : {
    1541           0 :     AppendBookmark( BookmarkToWord( rName ) );
    1542           0 : }
    1543             : 
    1544           6 : void WW8_WrtRedlineAuthor::Write( Writer& rWrt )
    1545             : {
    1546           6 :     WW8Export & rWW8Wrt = *(((SwWW8Writer&)rWrt).m_pExport);
    1547             :     rWW8Wrt.WriteAsStringTable(maAuthors, rWW8Wrt.pFib->fcSttbfRMark,
    1548           6 :         rWW8Wrt.pFib->lcbSttbfRMark, rWW8Wrt.bWrtWW8 ? 0 : 2);
    1549           6 : }
    1550             : 
    1551          10 : sal_uInt16 WW8Export::AddRedlineAuthor( sal_uInt16 nId )
    1552             : {
    1553          10 :     if( !pRedlAuthors )
    1554             :     {
    1555           6 :         pRedlAuthors = new WW8_WrtRedlineAuthor;
    1556           6 :         pRedlAuthors->AddName(OUString("Unknown"));
    1557             :     }
    1558          10 :     return pRedlAuthors->AddName( SW_MOD()->GetRedlineAuthor( nId ) );
    1559             : }
    1560             : 
    1561          26 : void WW8Export::WriteAsStringTable(const std::vector<OUString>& rStrings,
    1562             :     sal_Int32& rfcSttbf, sal_Int32& rlcbSttbf, sal_uInt16 nExtraLen)
    1563             : {
    1564          26 :     sal_uInt16 n, nCount = static_cast< sal_uInt16 >(rStrings.size());
    1565          26 :     if( nCount )
    1566             :     {
    1567             :         // we have some Redlines found in the document -> the
    1568             :         // Author Name Stringtable
    1569          22 :         SvStream& rStrm = bWrtWW8 ? *pTableStrm : Strm();
    1570          22 :         rfcSttbf = rStrm.Tell();
    1571          22 :         if( bWrtWW8 )
    1572             :         {
    1573          22 :             SwWW8Writer::WriteShort( rStrm, -1 );
    1574          22 :             SwWW8Writer::WriteLong( rStrm, nCount );
    1575         264 :             for( n = 0; n < nCount; ++n )
    1576             :             {
    1577         242 :                 const OUString& rNm = rStrings[n];
    1578         242 :                 SwWW8Writer::WriteShort( rStrm, rNm.getLength() );
    1579         242 :                 SwWW8Writer::WriteString16(rStrm, rNm, false);
    1580         242 :                 if( nExtraLen )
    1581           0 :                     SwWW8Writer::FillCount(rStrm, nExtraLen);
    1582             :             }
    1583             :         }
    1584             :         else
    1585             :         {
    1586           0 :             SwWW8Writer::WriteShort( rStrm, 0 );
    1587           0 :             for( n = 0; n < nCount; ++n )
    1588             :             {
    1589           0 :                 const OUString &rString = rStrings[n];
    1590           0 :                 const OUString aNm(rString.copy(0, std::min<sal_Int32>(rString.getLength(), 255)));
    1591           0 :                 rStrm.WriteUChar( aNm.getLength() );
    1592             :                 SwWW8Writer::WriteString8(rStrm, aNm, false,
    1593           0 :                     RTL_TEXTENCODING_MS_1252);
    1594           0 :                 if (nExtraLen)
    1595           0 :                     SwWW8Writer::FillCount(rStrm, nExtraLen);
    1596           0 :             }
    1597             :         }
    1598          22 :         rlcbSttbf = rStrm.Tell() - rfcSttbf;
    1599          22 :         if( !bWrtWW8 )
    1600           0 :             SwWW8Writer::WriteShort( rStrm, rfcSttbf, (sal_uInt16)rlcbSttbf );
    1601             :     }
    1602          26 : }
    1603             : 
    1604             : // WriteShort() traegt an FilePos nPos den Wert nVal ein und seekt auf die
    1605             : // alte FilePos zurueck. Benutzt zum Nachtragen von Laengen.
    1606          34 : void SwWW8Writer::WriteShort( SvStream& rStrm, sal_uLong nPos, sal_Int16 nVal )
    1607             : {
    1608          34 :     sal_uLong nOldPos = rStrm.Tell();       // remember Pos
    1609          34 :     rStrm.Seek( nPos );
    1610          34 :     SwWW8Writer::WriteShort( rStrm, nVal );
    1611          34 :     rStrm.Seek( nOldPos );
    1612          34 : }
    1613             : 
    1614          84 : void SwWW8Writer::WriteLong( SvStream& rStrm, sal_uLong nPos, sal_Int32 nVal )
    1615             : {
    1616          84 :     sal_uLong nOldPos = rStrm.Tell();       // remember Pos
    1617          84 :     rStrm.Seek( nPos );
    1618          84 :     SwWW8Writer::WriteLong( rStrm, nVal );
    1619          84 :     rStrm.Seek( nOldPos );
    1620          84 : }
    1621             : 
    1622       45114 : void SwWW8Writer::InsUInt16(ww::bytes &rO, sal_uInt16 n)
    1623             : {
    1624             :     SVBT16 nL;
    1625       45114 :     ShortToSVBT16( n, nL );
    1626       45114 :     rO.push_back(nL[0]);
    1627       45114 :     rO.push_back(nL[1]);
    1628       45114 : }
    1629             : 
    1630        1844 : void SwWW8Writer::InsUInt32(ww::bytes &rO, sal_uInt32 n)
    1631             : {
    1632             :     SVBT32 nL;
    1633        1844 :     UInt32ToSVBT32( n, nL );
    1634        1844 :     rO.push_back(nL[0]);
    1635        1844 :     rO.push_back(nL[1]);
    1636        1844 :     rO.push_back(nL[2]);
    1637        1844 :     rO.push_back(nL[3]);
    1638        1844 : }
    1639             : 
    1640        2204 : void SwWW8Writer::InsAsString16(ww::bytes &rO, const OUString& rStr)
    1641             : {
    1642        2204 :     const sal_Unicode* pStr = rStr.getStr();
    1643       25364 :     for (sal_Int32 n = 0, nLen = rStr.getLength(); n < nLen; ++n, ++pStr)
    1644       23160 :         SwWW8Writer::InsUInt16( rO, *pStr );
    1645        2204 : }
    1646             : 
    1647           0 : void SwWW8Writer::InsAsString8(ww::bytes &rO, const OUString& rStr,
    1648             :         rtl_TextEncoding eCodeSet)
    1649             : {
    1650           0 :     OString sTmp(OUStringToOString(rStr, eCodeSet));
    1651           0 :     const sal_Char *pStart = sTmp.getStr();
    1652           0 :     const sal_Char *pEnd = pStart + sTmp.getLength();
    1653           0 :     rO.reserve(rO.size() + sTmp.getLength());
    1654             : 
    1655           0 :     std::copy(pStart, pEnd, std::inserter(rO, rO.end()));
    1656           0 : }
    1657             : 
    1658        1390 : void SwWW8Writer::WriteString16(SvStream& rStrm, const OUString& rStr,
    1659             :     bool bAddZero)
    1660             : {
    1661        1390 :     ww::bytes aBytes;
    1662        1390 :     SwWW8Writer::InsAsString16(aBytes, rStr);
    1663        1390 :     if (bAddZero)
    1664         464 :         SwWW8Writer::InsUInt16(aBytes, 0);
    1665             :     //vectors are guaranteed to have contiguous memory, so we can do
    1666             :     //this while migrating away from WW8Bytes. Meyers Effective STL, item 16
    1667        1390 :     if (!aBytes.empty())
    1668        1042 :         rStrm.Write(&aBytes[0], aBytes.size());
    1669        1390 : }
    1670             : 
    1671           0 : void SwWW8Writer::WriteString_xstz(SvStream& rStrm, const OUString& rStr, bool bAddZero)
    1672             : {
    1673           0 :     ww::bytes aBytes;
    1674           0 :     SwWW8Writer::InsUInt16(aBytes, rStr.getLength());
    1675           0 :     SwWW8Writer::InsAsString16(aBytes, rStr);
    1676           0 :     if (bAddZero)
    1677           0 :         SwWW8Writer::InsUInt16(aBytes, 0);
    1678           0 :     rStrm.Write(&aBytes[0], aBytes.size());
    1679           0 : }
    1680             : 
    1681           0 : void SwWW8Writer::WriteString8(SvStream& rStrm, const OUString& rStr,
    1682             :     bool bAddZero, rtl_TextEncoding eCodeSet)
    1683             : {
    1684           0 :     ww::bytes aBytes;
    1685           0 :     SwWW8Writer::InsAsString8(aBytes, rStr, eCodeSet);
    1686           0 :     if (bAddZero)
    1687           0 :         aBytes.push_back(0);
    1688             :     //vectors are guaranteed to have contiguous memory, so we can do
    1689             :     ////this while migrating away from WW8Bytes. Meyers Effective STL, item 16
    1690           0 :     if (!aBytes.empty())
    1691           0 :         rStrm.Write(&aBytes[0], aBytes.size());
    1692           0 : }
    1693             : 
    1694         136 : void WW8Export::WriteStringAsPara( const OUString& rTxt, sal_uInt16 nStyleId )
    1695             : {
    1696         136 :     if( !rTxt.isEmpty() )
    1697           0 :         OutSwString( rTxt, 0, rTxt.getLength(), IsUnicode(), RTL_TEXTENCODING_MS_1252 );
    1698         136 :     WriteCR();              // CR thereafter
    1699             : 
    1700         136 :     ww::bytes aArr;
    1701         136 :     SwWW8Writer::InsUInt16( aArr, nStyleId );
    1702         136 :     if( bOutTable )
    1703             :     {                                               // Tab-Attr
    1704             :         // sprmPFInTable
    1705           0 :         if( bWrtWW8 )
    1706           0 :             SwWW8Writer::InsUInt16( aArr, NS_sprm::LN_PFInTable );
    1707             :         else
    1708           0 :             aArr.push_back( 24 );
    1709           0 :         aArr.push_back( 1 );
    1710             :     }
    1711             : 
    1712         136 :     sal_uLong nPos = Strm().Tell();
    1713         136 :     pPapPlc->AppendFkpEntry( nPos, aArr.size(), aArr.data() );
    1714         136 :     pChpPlc->AppendFkpEntry( nPos );
    1715         136 : }
    1716             : 
    1717         674 : void MSWordExportBase::WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp )
    1718             : {
    1719         674 :     sal_uInt8 nOldTyp = nTxtTyp;
    1720         674 :     nTxtTyp = nTTyp;
    1721         674 :     SwPaM* pOldPam = pCurPam;       //!! Simply shifting the PaM without restoring should do the job too
    1722         674 :     SwPaM* pOldEnd = pOrigPam;
    1723         674 :     bool bOldPageDescs = bOutPageDescs;
    1724         674 :     bOutPageDescs = false;
    1725             :                                     // bOutKF was setted / stored in WriteKF1
    1726         674 :     pCurPam = Writer::NewSwPaM( *pDoc, nStart, nEnd );
    1727             : 
    1728             :     // Tabelle in Sonderbereichen erkennen
    1729         734 :     if ( ( nStart != pCurPam->GetMark()->nNode.GetIndex() ) &&
    1730          60 :          pDoc->GetNodes()[ nStart ]->IsTableNode() )
    1731             :     {
    1732          60 :         pCurPam->GetMark()->nNode = nStart;
    1733             :     }
    1734             : 
    1735         674 :     pOrigPam = pCurPam;
    1736         674 :     pCurPam->Exchange();
    1737             : 
    1738         674 :     WriteText();
    1739             : 
    1740         674 :     bOutPageDescs = bOldPageDescs;
    1741         674 :     delete pCurPam;                    // delete Pam
    1742         674 :     pCurPam = pOldPam;
    1743         674 :     pOrigPam = pOldEnd;
    1744         674 :     nTxtTyp = nOldTyp;
    1745         674 : }
    1746             : 
    1747         430 : void WW8Export::OutSwString(const OUString& rStr, sal_Int32 nStt,
    1748             :     sal_Int32 nLen, bool bUnicode, rtl_TextEncoding eChrSet)
    1749             : 
    1750             : {
    1751             :     SAL_INFO( "sw.ww8.level2", "<OutSwString>" );
    1752             : 
    1753         430 :     if( nLen )
    1754             :     {
    1755         430 :         if ( bUnicode != pPiece->IsUnicode() )
    1756           0 :             pPiece->AppendPc ( Strm().Tell(), bUnicode );
    1757             : 
    1758         430 :         if( nStt || nLen != rStr.getLength() )
    1759             :         {
    1760           0 :             OUString sOut( rStr.copy( nStt, nLen ) );
    1761             : 
    1762             :             SAL_INFO( "sw.ww8.level2", sOut );
    1763             : 
    1764           0 :             if (bUnicode)
    1765           0 :                 SwWW8Writer::WriteString16(Strm(), sOut, false);
    1766             :             else
    1767           0 :                 SwWW8Writer::WriteString8(Strm(), sOut, false, eChrSet);
    1768             :         }
    1769             :         else
    1770             :         {
    1771             :             SAL_INFO( "sw.ww8.level2", rStr );
    1772             : 
    1773         430 :             if (bUnicode)
    1774         430 :                 SwWW8Writer::WriteString16(Strm(), rStr, false);
    1775             :             else
    1776           0 :                 SwWW8Writer::WriteString8(Strm(), rStr, false, eChrSet);
    1777             :         }
    1778             :     }
    1779             : 
    1780             :     SAL_INFO( "sw.ww8.level2", "</OutSwString>" );
    1781         430 : }
    1782             : 
    1783         850 : void WW8Export::WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
    1784             : {
    1785         850 :     if (pTableTextNodeInfoInner.get() != NULL && pTableTextNodeInfoInner->getDepth() == 1 && pTableTextNodeInfoInner->isEndOfCell())
    1786         268 :         WriteChar('\007');
    1787             :     else
    1788         582 :         WriteChar( '\015' );
    1789             : 
    1790         850 :     pPiece->SetParaBreak();
    1791         850 : }
    1792             : 
    1793        1018 : void WW8Export::WriteChar( sal_Unicode c )
    1794             : {
    1795        1018 :     if( pPiece->IsUnicode() )
    1796        1018 :         Strm().WriteUInt16( c );
    1797             :     else
    1798           0 :         Strm().WriteUChar( c );
    1799        1018 : }
    1800             : 
    1801         618 : void MSWordExportBase::SaveData( sal_uLong nStt, sal_uLong nEnd )
    1802             : {
    1803             :     MSWordSaveData aData;
    1804             : 
    1805             :     // WW8Export only stuff - zeroed here not to issue warnings
    1806         618 :     aData.pOOld = NULL;
    1807             : 
    1808             :     // Common stuff
    1809         618 :     aData.pOldPam = pCurPam;
    1810         618 :     aData.pOldEnd = pOrigPam;
    1811         618 :     aData.pOldFlyFmt = mpParentFrame;
    1812         618 :     aData.pOldPageDesc = pAktPageDesc;
    1813             : 
    1814         618 :     aData.pOldFlyOffset = pFlyOffset;
    1815         618 :     aData.eOldAnchorType = eNewAnchorType;
    1816             : 
    1817         618 :     aData.bOldOutTable = bOutTable;
    1818         618 :     aData.bOldFlyFrmAttrs = bOutFlyFrmAttrs;
    1819         618 :     aData.bOldStartTOX = bStartTOX;
    1820         618 :     aData.bOldInWriteTOX = bInWriteTOX;
    1821             : 
    1822         618 :     pCurPam = Writer::NewSwPaM( *pDoc, nStt, nEnd );
    1823             : 
    1824             :     // Recognize tables in special cases
    1825         666 :     if ( nStt != pCurPam->GetMark()->nNode.GetIndex() &&
    1826          48 :          pDoc->GetNodes()[ nStt ]->IsTableNode() )
    1827             :     {
    1828          48 :         pCurPam->GetMark()->nNode = nStt;
    1829             :     }
    1830             : 
    1831         618 :     pOrigPam = pCurPam;
    1832         618 :     pCurPam->Exchange();
    1833             : 
    1834         618 :     bOutTable = false;
    1835             :     // Caution: bIsInTable should not be set here
    1836         618 :     bOutFlyFrmAttrs = false;
    1837         618 :     bStartTOX = false;
    1838         618 :     bInWriteTOX = false;
    1839             : 
    1840         618 :     maSaveData.push( aData );
    1841         618 : }
    1842             : 
    1843         618 : void MSWordExportBase::RestoreData()
    1844             : {
    1845         618 :     MSWordSaveData &rData = maSaveData.top();
    1846             : 
    1847         618 :     delete pCurPam;
    1848         618 :     pCurPam = rData.pOldPam;
    1849         618 :     pOrigPam = rData.pOldEnd;
    1850             : 
    1851         618 :     bOutTable = rData.bOldOutTable;
    1852         618 :     bOutFlyFrmAttrs = rData.bOldFlyFrmAttrs;
    1853         618 :     bStartTOX = rData.bOldStartTOX;
    1854         618 :     bInWriteTOX = rData.bOldInWriteTOX;
    1855             : 
    1856         618 :     mpParentFrame = rData.pOldFlyFmt;
    1857         618 :     pAktPageDesc = rData.pOldPageDesc;
    1858             : 
    1859         618 :     eNewAnchorType = rData.eOldAnchorType;
    1860         618 :     pFlyOffset = rData.pOldFlyOffset;
    1861             : 
    1862         618 :     maSaveData.pop();
    1863         618 : }
    1864             : 
    1865           2 : void WW8Export::SaveData( sal_uLong nStt, sal_uLong nEnd )
    1866             : {
    1867           2 :     MSWordExportBase::SaveData( nStt, nEnd );
    1868             : 
    1869           2 :     MSWordSaveData &rData = maSaveData.top();
    1870             : 
    1871           2 :     if ( !pO->empty() )
    1872             :     {
    1873           0 :         rData.pOOld = pO;
    1874           0 :         pO = new ww::bytes();
    1875             :     }
    1876             :     else
    1877           2 :         rData.pOOld = 0; // reuse pO
    1878             : 
    1879           2 :     rData.bOldWriteAll = GetWriter().bWriteAll;
    1880           2 :     GetWriter().bWriteAll = true;
    1881           2 : }
    1882             : 
    1883           2 : void WW8Export::RestoreData()
    1884             : {
    1885           2 :     MSWordSaveData &rData = maSaveData.top();
    1886             : 
    1887           2 :     GetWriter().bWriteAll = rData.bOldWriteAll;
    1888             : 
    1889             :     OSL_ENSURE( pO->empty(), "pO is not empty in WW8Export::RestoreData()" );
    1890           2 :     if ( rData.pOOld )
    1891             :     {
    1892           0 :         delete pO;
    1893           0 :         pO = rData.pOOld;
    1894             :     }
    1895             : 
    1896           2 :     MSWordExportBase::RestoreData();
    1897           2 : }
    1898             : 
    1899         486 : void WW8AttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    1900             : {
    1901         486 :     sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth();
    1902             : 
    1903         486 :     if ( nDepth > 0 )
    1904             :     {
    1905             :         /* Cell */
    1906         486 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable );
    1907         486 :         m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1908         486 :         m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth );
    1909         486 :         m_rWW8Export.InsUInt32( nDepth );
    1910             : 
    1911         486 :         if ( nDepth > 1 && pTableTextNodeInfoInner->isEndOfCell() )
    1912             :         {
    1913           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_PCell );
    1914           0 :             m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1915             :         }
    1916             :     }
    1917         486 : }
    1918             : 
    1919          72 : void WW8AttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    1920             : {
    1921          72 :     sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth();
    1922             : 
    1923          72 :     if ( nDepth > 0 )
    1924             :     {
    1925             :         /* Row */
    1926          72 :         if ( pTableTextNodeInfoInner->isEndOfLine() )
    1927             :         {
    1928          72 :             m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable );
    1929          72 :             m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1930             : 
    1931          72 :             if ( nDepth == 1 )
    1932             :             {
    1933          72 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_PFTtp );
    1934          72 :                 m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1935             :             }
    1936             : 
    1937          72 :             m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth );
    1938          72 :             m_rWW8Export.InsUInt32( nDepth );
    1939             : 
    1940          72 :             if ( nDepth > 1 )
    1941             :             {
    1942           0 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_PCell );
    1943           0 :                 m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1944           0 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_PRow );
    1945           0 :                 m_rWW8Export.pO->push_back( (sal_uInt8)0x1 );
    1946             :             }
    1947             : 
    1948          72 :             TableDefinition( pTableTextNodeInfoInner );
    1949          72 :             TableHeight( pTableTextNodeInfoInner );
    1950          72 :             TableBackgrounds( pTableTextNodeInfoInner );
    1951          72 :             TableDefaultBorders( pTableTextNodeInfoInner );
    1952          72 :             TableCanSplit( pTableTextNodeInfoInner );
    1953          72 :             TableBidi( pTableTextNodeInfoInner );
    1954          72 :             TableVerticalCell( pTableTextNodeInfoInner );
    1955          72 :             TableOrientation( pTableTextNodeInfoInner );
    1956          72 :             TableSpacing( pTableTextNodeInfoInner );
    1957          72 :             TableCellBorders( pTableTextNodeInfoInner );
    1958             :         }
    1959             :     }
    1960          72 : }
    1961             : 
    1962         268 : static sal_uInt16 lcl_TCFlags(SwDoc &rDoc, const SwTableBox * pBox, sal_Int32 nRowSpan)
    1963             : {
    1964         268 :     sal_uInt16 nFlags = 0;
    1965             : 
    1966         268 :     if (nRowSpan > 1)
    1967           0 :         nFlags |= (3 << 5);
    1968         268 :     else if (nRowSpan < 0)
    1969           0 :         nFlags |= (1 << 5);
    1970             : 
    1971         268 :     if (pBox != NULL)
    1972             :     {
    1973         268 :         const SwFrmFmt * pFmt = pBox->GetFrmFmt();
    1974         268 :         switch (pFmt->GetVertOrient().GetVertOrient())
    1975             :         {
    1976             :             case text::VertOrientation::CENTER:
    1977          32 :                 nFlags |= (1 << 7);
    1978          32 :                 break;
    1979             :             case text::VertOrientation::BOTTOM:
    1980           0 :                 nFlags |= (2 << 7);
    1981           0 :                 break;
    1982             :             default:
    1983         236 :                 break;
    1984             :         }
    1985         268 :         const SwStartNode * pSttNd = pBox->GetSttNd();
    1986         268 :         if(pSttNd)
    1987             :         {
    1988         268 :             SwNodeIndex aIdx( *pSttNd );
    1989         268 :             const SwCntntNode * pCNd = pSttNd->GetNodes().GoNext( &aIdx );
    1990         268 :             if( pCNd && pCNd->IsTxtNode())
    1991             :             {
    1992         268 :                 SfxItemSet aCoreSet(rDoc.GetAttrPool(), RES_CHRATR_ROTATE, RES_CHRATR_ROTATE);
    1993         268 :                 ((SwTxtNode*)pCNd)->GetAttr( aCoreSet, 0, ((SwTxtNode*)pCNd)->GetTxt().getLength());
    1994         268 :                 const SvxCharRotateItem * pRotate = NULL;
    1995             :                 const SfxPoolItem * pRotItem;
    1996         268 :                 if ( SfxItemState::SET == aCoreSet.GetItemState(RES_CHRATR_ROTATE, true, &pRotItem))
    1997             :                 {
    1998           0 :                     pRotate = (SvxCharRotateItem*)pRotItem;
    1999           0 :                     if(pRotate && pRotate->GetValue() == 900)
    2000             :                     {
    2001           0 :                         nFlags = nFlags | 0x0004 | 0x0008;
    2002             :                     }
    2003           0 :                     else if(pRotate && pRotate->GetValue() == 2700 )
    2004             :                     {
    2005           0 :                         nFlags = nFlags | 0x0004 | 0x0010;
    2006             :                     }
    2007         268 :                 }
    2008         268 :             }
    2009             :         }
    2010             :     }
    2011             : 
    2012         268 :     return nFlags;
    2013             : }
    2014             : 
    2015          72 : void WW8AttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2016             : {
    2017          72 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2018          72 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2019          72 :     const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes();
    2020             : 
    2021          72 :     sal_uInt8 nBoxes = rTblBoxes.size();
    2022         340 :     for ( sal_uInt8 n = 0; n < nBoxes; n++ )
    2023             :     {
    2024         268 :         const SwTableBox * pTabBox1 = rTblBoxes[n];
    2025         268 :         const SwFrmFmt * pFrmFmt = pTabBox1->GetFrmFmt();
    2026             : 
    2027         268 :         if ( FRMDIR_VERT_TOP_RIGHT == m_rWW8Export.TrueFrameDirection( *pFrmFmt ) )
    2028             :         {
    2029           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TTextFlow );
    2030           0 :             m_rWW8Export.pO->push_back( sal_uInt8(n) );        //start range
    2031           0 :             m_rWW8Export.pO->push_back( sal_uInt8(n + 1) );    //end range
    2032           0 :             m_rWW8Export.InsUInt16( 5 ); //Equals vertical writing
    2033             :         }
    2034             :     }
    2035          72 : }
    2036             : 
    2037          72 : void WW8AttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2038             : {
    2039          72 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2040          72 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2041          72 :     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
    2042             : 
    2043             :     /*
    2044             :      By default the row can be split in word, and now in writer we have a
    2045             :      feature equivalent to this, Word stores 1 for fCantSplit if the row
    2046             :      cannot be split, we set true if we can split it. An example is #i4569#
    2047             :      */
    2048             : 
    2049          72 :     const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit();
    2050          72 :     sal_uInt8 nCantSplit = (!rSplittable.GetValue()) ? 1 : 0;
    2051          72 :     if ( m_rWW8Export.bWrtWW8 )
    2052             :     {
    2053          72 :         m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit );
    2054          72 :         m_rWW8Export.pO->push_back( nCantSplit );
    2055          72 :         m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit90 ); // also write fCantSplit90
    2056             :     }
    2057             :     else
    2058             :     {
    2059           0 :         m_rWW8Export.pO->push_back( 185 );
    2060             :     }
    2061          72 :     m_rWW8Export.pO->push_back( nCantSplit );
    2062          72 : }
    2063             : 
    2064          72 : void WW8AttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2065             : {
    2066          72 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2067          72 :     const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
    2068             : 
    2069          72 :     if ( m_rWW8Export.bWrtWW8 )
    2070             :     {
    2071          72 :         if ( m_rWW8Export.TrueFrameDirection(*pFrmFmt) == FRMDIR_HORI_RIGHT_TOP )
    2072             :         {
    2073           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TFBiDi );
    2074           0 :             m_rWW8Export.InsUInt16( 1 );
    2075             :         }
    2076             :     }
    2077          72 : }
    2078             : 
    2079           0 : void WW8AttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
    2080             : {
    2081           0 : }
    2082             : 
    2083           0 : void WW8AttributeOutput::TableCellRedline( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
    2084             : {
    2085           0 : }
    2086             : 
    2087          72 : void WW8AttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2088             : {
    2089          72 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2090          72 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2091          72 :     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
    2092             : 
    2093             :     // Zeilenhoehe ausgeben   sprmTDyaRowHeight
    2094          72 :     long nHeight = 0;
    2095          72 :     const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
    2096          72 :     if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
    2097             :     {
    2098          60 :         if ( ATT_MIN_SIZE == rLSz.GetHeightSizeType() )
    2099          16 :             nHeight = rLSz.GetHeight();
    2100             :         else
    2101          44 :             nHeight = -rLSz.GetHeight();
    2102             :     }
    2103             : 
    2104          72 :     if ( nHeight )
    2105             :     {
    2106          60 :         if ( m_rWW8Export.bWrtWW8 )
    2107          60 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TDyaRowHeight );
    2108             :         else
    2109           0 :             m_rWW8Export.pO->push_back( 189 );
    2110          60 :         m_rWW8Export.InsUInt16( (sal_uInt16)nHeight );
    2111             :     }
    2112             : 
    2113          72 : }
    2114             : 
    2115          72 : void WW8AttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2116             : {
    2117          72 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2118             : 
    2119          72 :     const SwFrmFmt *pFmt = pTable->GetFrmFmt();
    2120             :     OSL_ENSURE(pFmt,"Impossible");
    2121          72 :     if (!pFmt)
    2122          72 :         return;
    2123             : 
    2124          72 :     const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
    2125          72 :     const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
    2126             : 
    2127          72 :     if (
    2128          72 :         (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
    2129           0 :          text::RelOrientation::FRAME == rHori.GetRelationOrient())
    2130         216 :         &&
    2131          72 :         (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
    2132           0 :          text::RelOrientation::FRAME == rVert.GetRelationOrient())
    2133             :         )
    2134             :     {
    2135          72 :         sal_Int16 eHOri = rHori.GetHoriOrient();
    2136          72 :         switch (eHOri)
    2137             :         {
    2138             :             case text::HoriOrientation::CENTER:
    2139             :             case text::HoriOrientation::RIGHT:
    2140           0 :                 if ( m_rWW8Export.bWrtWW8 )
    2141           0 :                     m_rWW8Export.InsUInt16( NS_sprm::LN_TJc90 );
    2142             :                 else
    2143           0 :                     m_rWW8Export.pO->push_back( 182 );
    2144           0 :                 m_rWW8Export.InsUInt16( text::HoriOrientation::RIGHT == eHOri ? 2 : 1 );
    2145           0 :                 break;
    2146             :             default:
    2147          72 :                 break;
    2148             :         }
    2149             :     }
    2150             : }
    2151             : 
    2152          72 : void WW8AttributeOutput::TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
    2153             : {
    2154          72 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2155          72 :     const SwTableFmt * pTableFmt = pTable->GetTableFmt();
    2156             : 
    2157             :     // Writing these SPRM's will make the table a floating one, so only write
    2158             :     // them in case the table is already inside a frame.
    2159          72 :     if (pTableFmt != NULL && pTable->GetTableNode()->GetFlyFmt())
    2160             :     {
    2161           6 :         const SvxULSpaceItem & rUL = pTableFmt->GetULSpace();
    2162             : 
    2163           6 :         if (rUL.GetUpper() > 0)
    2164             :         {
    2165           0 :             sal_uInt8 nPadding = 2;
    2166           0 :             sal_uInt8 nPcVert = 0;
    2167           0 :             sal_uInt8 nPcHorz = 0;
    2168             : 
    2169           0 :             sal_uInt8 nTPc = (nPadding << 4) | (nPcVert << 2) | nPcHorz;
    2170             : 
    2171           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TPc);
    2172           0 :             m_rWW8Export.pO->push_back( nTPc );
    2173             : 
    2174           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaAbs);
    2175           0 :             m_rWW8Export.InsUInt16(rUL.GetUpper());
    2176             : 
    2177           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromText);
    2178           0 :             m_rWW8Export.InsUInt16(rUL.GetUpper());
    2179             :         }
    2180             : 
    2181           6 :         if (rUL.GetLower() > 0)
    2182             :         {
    2183           0 :             m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromTextBottom);
    2184           0 :             m_rWW8Export.InsUInt16(rUL.GetLower());
    2185             :         }
    2186             :     }
    2187          72 : }
    2188             : 
    2189          72 : void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2190             : {
    2191          72 :     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
    2192             : 
    2193          72 :     if ( pTable->GetRowsToRepeat() > pTableTextNodeInfoInner->getRow() )
    2194             :     {
    2195           0 :         if( m_rWW8Export.bWrtWW8 )
    2196           0 :             m_rWW8Export.InsUInt16( NS_sprm::LN_TTableHeader );
    2197             :         else
    2198           0 :             m_rWW8Export.pO->push_back( 186 );
    2199           0 :         m_rWW8Export.pO->push_back( 1 );
    2200             :     }
    2201             : 
    2202             :     ww8::TableBoxVectorPtr pTableBoxes =
    2203          72 :         pTableTextNodeInfoInner->getTableBoxesOfRow();
    2204             :     // number of cell written
    2205          72 :     sal_uInt32 nBoxes = pTableBoxes->size();
    2206          72 :     if (nBoxes > ww8::MAXTABLECELLS)
    2207           0 :         nBoxes = ww8::MAXTABLECELLS;
    2208             : 
    2209             :     // sprm header
    2210          72 :     m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTable );
    2211          72 :     sal_uInt16 nSprmSize = 2 + (nBoxes + 1) * 2 + nBoxes * 20;
    2212          72 :     m_rWW8Export.InsUInt16( nSprmSize ); // length
    2213             : 
    2214             :     // number of boxes
    2215          72 :     m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nBoxes) );
    2216             : 
    2217             :     /* cellxs */
    2218             :     /*
    2219             :      ALWAYS relative when text::HoriOrientation::NONE (nPageSize + ( nPageSize / 10 )) < nTblSz,
    2220             :      in that case the cell width's and table width's are not real. The table
    2221             :      width is maxed and cells relative, so we need the frame (generally page)
    2222             :      width that the table is in to work out the true widths.
    2223             :      */
    2224             :     //const bool bNewTableModel = pTbl->IsNewModel();
    2225          72 :     const SwFrmFmt *pFmt = pTable->GetFrmFmt();
    2226             :     OSL_ENSURE(pFmt,"Impossible");
    2227          72 :     if (!pFmt)
    2228          72 :         return;
    2229             : 
    2230          72 :     const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
    2231          72 :     const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
    2232             : 
    2233          72 :     sal_uInt16 nTblOffset = 0;
    2234             : 
    2235          72 :     if (
    2236          72 :         (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
    2237           0 :          text::RelOrientation::FRAME == rHori.GetRelationOrient())
    2238         216 :         &&
    2239          72 :         (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
    2240           0 :          text::RelOrientation::FRAME == rVert.GetRelationOrient())
    2241             :         )
    2242             :     {
    2243          72 :         sal_Int16 eHOri = rHori.GetHoriOrient();
    2244          72 :         switch ( eHOri )
    2245             :         {
    2246             :             case text::HoriOrientation::CENTER:
    2247             :             case text::HoriOrientation::RIGHT:
    2248           0 :                 break;
    2249             : 
    2250             :             default:
    2251          72 :                 nTblOffset = rHori.GetPos();
    2252          72 :                 const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace();
    2253          72 :                 nTblOffset += rLRSp.GetLeft();
    2254          72 :                 break;
    2255             :         }
    2256             :     }
    2257             : 
    2258          72 :      m_rWW8Export.InsUInt16( nTblOffset );
    2259             : 
    2260          72 :     ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner );
    2261         412 :     for ( ww8::GridCols::const_iterator it = pGridCols->begin(),
    2262          72 :               end = pGridCols->end(); it != end; ++it )
    2263             :      {
    2264         268 :          m_rWW8Export.InsUInt16( static_cast<sal_uInt16>( *it ) + nTblOffset );
    2265             :      }
    2266             : 
    2267             :      /* TCs */
    2268         144 :     ww8::RowSpansPtr pRowSpans = pTableTextNodeInfoInner->getRowSpansOfRow();
    2269          72 :     ww8::RowSpans::const_iterator aItRowSpans = pRowSpans->begin();
    2270          72 :     ww8::TableBoxVector::const_iterator aIt;
    2271          72 :     ww8::TableBoxVector::const_iterator aItEnd = pTableBoxes->end();
    2272             : 
    2273             : #if OSL_DEBUG_LEVEL > 1
    2274             :     size_t nRowSpans = pRowSpans->size();
    2275             :     size_t nTableBoxes = pTableBoxes->size();
    2276             :     (void) nRowSpans;
    2277             :     (void) nTableBoxes;
    2278             : #endif
    2279             : 
    2280         340 :     for( aIt = pTableBoxes->begin(); aIt != aItEnd; ++aIt, ++aItRowSpans)
    2281             :     {
    2282         268 :         sal_uInt16 npOCount = m_rWW8Export.pO->size();
    2283             : 
    2284         268 :         const SwTableBox * pTabBox1 = *aIt;
    2285         268 :         const SwFrmFmt * pBoxFmt = NULL;
    2286         268 :         if (pTabBox1 != NULL)
    2287         268 :             pBoxFmt = pTabBox1->GetFrmFmt();
    2288             : 
    2289         268 :         if ( m_rWW8Export.bWrtWW8 )
    2290             :         {
    2291             :             sal_uInt16 nFlags =
    2292         268 :                 lcl_TCFlags(*m_rWW8Export.pDoc, pTabBox1, *aItRowSpans);
    2293         268 :              m_rWW8Export.InsUInt16( nFlags );
    2294             :         }
    2295             : 
    2296             :         static sal_uInt8 aNullBytes[] = { 0x0, 0x0 };
    2297             : 
    2298         268 :         m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aNullBytes, aNullBytes+2 );   // dummy
    2299         268 :         if (pBoxFmt != NULL)
    2300             :         {
    2301         268 :             const SvxBoxItem & rBoxItem = pBoxFmt->GetBox();
    2302             : 
    2303         268 :             m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, &rBoxItem ); // 8/16 Byte
    2304             :         }
    2305             :         else
    2306           0 :             m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, NULL); // 8/16 Byte
    2307             : 
    2308             :         SAL_INFO( "sw.ww8.level2", "<tclength>" << ( m_rWW8Export.pO->size() - npOCount ) << "</tclength>" );
    2309          72 :     }
    2310             : }
    2311             : 
    2312        4794 : ww8::GridColsPtr AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2313             : {
    2314        4794 :     return pTableTextNodeInfoInner->getGridColsOfRow(*this);
    2315             : }
    2316             : 
    2317         264 : ww8::WidthsPtr AttributeOutputBase::GetColumnWidths( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2318             : {
    2319             :     // Get the column widths based on ALL the rows, not just the current row
    2320         264 :     return pTableTextNodeInfoInner->getGridColsOfRow(*this, true);
    2321             : }
    2322             : 
    2323        5590 : void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize )
    2324             : {
    2325        5590 :     sal_uInt32 nPageSize = 0;
    2326             : 
    2327        5590 :     const SwNode *pTxtNd = pTableTextNodeInfoInner->getNode( );
    2328        5590 :     const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
    2329             : 
    2330        5590 :     const SwFrmFmt *pFmt = pTable->GetFrmFmt();
    2331             :     OSL_ENSURE(pFmt,"Impossible");
    2332        5590 :     if (!pFmt)
    2333        5590 :         return;
    2334             : 
    2335        5590 :     const SwFmtFrmSize &rSize = pFmt->GetFrmSize();
    2336        5590 :     int nWidthPercent = rSize.GetWidthPercent();
    2337        5590 :     bool bManualAligned = pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::NONE;
    2338        5590 :     if ( (pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::FULL) || bManualAligned )
    2339         598 :         nWidthPercent = 100;
    2340        5590 :     bool bRelBoxSize = nWidthPercent != 0;
    2341        5590 :     unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth());
    2342        5590 :     if (nTblSz > USHRT_MAX/2 && !bRelBoxSize)
    2343             :     {
    2344             :         OSL_ENSURE(bRelBoxSize, "huge table width but not relative, suspicious");
    2345           0 :         bRelBoxSize = true;
    2346             :     }
    2347             : 
    2348        5590 :     if ( bRelBoxSize )
    2349             :     {
    2350         904 :         Point aPt;
    2351         904 :         SwRect aRect( pFmt->FindLayoutRect( false, &aPt ) );
    2352         904 :         if ( aRect.IsEmpty() )
    2353             :         {
    2354             :             // dann besorge mal die Seitenbreite ohne Raender !!
    2355             :             const SwFrmFmt* pParentFmt =
    2356          44 :                 GetExport().mpParentFrame ?
    2357           2 :                 &(GetExport().mpParentFrame->GetFrmFmt()) :
    2358          46 :                     GetExport().pDoc->GetPageDesc(0).GetPageFmtOfNode(*pTxtNd, false);
    2359          44 :             aRect = pParentFmt->FindLayoutRect(true);
    2360          44 :             if ( 0 == ( nPageSize = aRect.Width() ) )
    2361             :             {
    2362          44 :                 const SvxLRSpaceItem& rLR = pParentFmt->GetLRSpace();
    2363          88 :                 nPageSize = pParentFmt->GetFrmSize().GetWidth() - rLR.GetLeft()
    2364          88 :                 - rLR.GetRight();
    2365             :             }
    2366             :         }
    2367             :         else
    2368             :         {
    2369         860 :             nPageSize = aRect.Width();
    2370         860 :             if ( bManualAligned )
    2371             :             {
    2372             :                 // #i37571# For manually aligned tables
    2373         558 :                 const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
    2374         558 :                 nPageSize -= (rLR.GetLeft() + rLR.GetRight());
    2375             :             }
    2376             : 
    2377             :         }
    2378             : 
    2379             :         OSL_ENSURE(nWidthPercent, "Impossible");
    2380         904 :         if (nWidthPercent)
    2381             :         {
    2382         904 :             nPageSize *= nWidthPercent;
    2383         904 :             nPageSize /= 100;
    2384             :         }
    2385             :     }
    2386             :     else
    2387             :     {
    2388             :         // As the table width is not relative, the TablePageSize equals its width
    2389        4686 :         nPageSize = nTblSz;
    2390             :     }
    2391             : 
    2392        5590 :     rPageSize = nPageSize;
    2393        5590 :     rRelBoxSize = bRelBoxSize;
    2394             : }
    2395             : 
    2396          72 : void WW8AttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2397             : {
    2398          72 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2399          72 :     const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
    2400             : 
    2401             :     //Set Default, just taken from the first cell of the first
    2402             :     //row
    2403             :     static const sal_uInt16 aBorders[] =
    2404             :     {
    2405             :         BOX_LINE_TOP, BOX_LINE_LEFT,
    2406             :         BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    2407             :     };
    2408             : 
    2409         360 :     for ( int i = 0; i < 4; ++i )
    2410             :     {
    2411         288 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, 0xD634 );
    2412         288 :         m_rWW8Export.pO->push_back( sal_uInt8(6) );
    2413         288 :         m_rWW8Export.pO->push_back( sal_uInt8(0) );
    2414         288 :         m_rWW8Export.pO->push_back( sal_uInt8(1) );
    2415         288 :         m_rWW8Export.pO->push_back( sal_uInt8(1 << i) );
    2416         288 :         m_rWW8Export.pO->push_back( sal_uInt8(3) );
    2417             : 
    2418             :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO,
    2419         288 :                 pFrmFmt->GetBox().GetDistance( aBorders[i] ) );
    2420             :     }
    2421          72 : }
    2422             : 
    2423          72 : void WW8AttributeOutput::TableCellBorders(
    2424             :     ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2425             : {
    2426          72 :     if (!m_rWW8Export.bWrtWW8)
    2427          72 :         return;
    2428             : 
    2429          72 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2430          72 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2431          72 :     const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
    2432          72 :     sal_uInt8 nBoxes = std::min<size_t>(rTabBoxes.size(), 255);
    2433          72 :     const SvxBoxItem * pLastBox = 0;
    2434          72 :     sal_uInt8 nSeqStart = 0; // start of sequence of cells with same borders
    2435             : 
    2436             :     // Detect sequences of cells which have the same borders, and output
    2437             :     // a border description for each such cell range.
    2438         412 :     for ( unsigned n = 0; n <= nBoxes; ++n )
    2439             :     {
    2440         340 :         const SvxBoxItem * pBox = (n == nBoxes) ? 0 :
    2441         340 :             &rTabBoxes[n]->GetFrmFmt()->GetBox();
    2442         340 :         if( !pLastBox )
    2443          72 :             pLastBox = pBox;
    2444         268 :         else if( !pBox || *pLastBox != *pBox )
    2445             :         {
    2446             :             // This cell has different borders than the previous cell,
    2447             :             // so output the borders for the preceding cell range.
    2448         184 :             m_rWW8Export.Out_CellRangeBorders(pLastBox, nSeqStart, n);
    2449         184 :             nSeqStart = n;
    2450         184 :             pLastBox = pBox;
    2451             :         }
    2452             :     }
    2453             : }
    2454             : 
    2455          72 : void WW8AttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
    2456             : {
    2457          72 :     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
    2458          72 :     const SwTableLine * pTabLine = pTabBox->GetUpper();
    2459          72 :     const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
    2460             : 
    2461          72 :     sal_uInt8 nBoxes = rTabBoxes.size();
    2462          72 :     if ( m_rWW8Export.bWrtWW8 )
    2463          72 :         m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTableShd80 );
    2464             :     else
    2465           0 :         m_rWW8Export.pO->push_back( (sal_uInt8)191 );
    2466          72 :     m_rWW8Export.pO->push_back( (sal_uInt8)(nBoxes * 2) );  // Len
    2467             : 
    2468         340 :     for ( sal_uInt8 n = 0; n < nBoxes; n++ )
    2469             :     {
    2470         268 :         const SwTableBox * pBox1 = rTabBoxes[n];
    2471         268 :         const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
    2472         268 :         const SfxPoolItem * pI = NULL;
    2473         268 :         Color aColor;
    2474             : 
    2475         268 :         if ( SfxItemState::SET == pFrmFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) )
    2476             :         {
    2477          46 :             aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
    2478             :         }
    2479             :         else
    2480         222 :             aColor = COL_AUTO;
    2481             : 
    2482         268 :         WW8_SHD aShd;
    2483         268 :         m_rWW8Export.TransBrush( aColor, aShd );
    2484         268 :         m_rWW8Export.InsUInt16( aShd.GetValue() );
    2485             :     }
    2486             : 
    2487          72 :     if ( m_rWW8Export.bWrtWW8 )
    2488             :     {
    2489             :         sal_uInt32 aSprmIds[] = { NS_sprm::LN_TDefTableShd,
    2490          72 :                                   NS_sprm::LN_TDefTableShdRaw };
    2491          72 :         sal_uInt8 nBoxes0 = rTabBoxes.size();
    2492          72 :         if (nBoxes0 > 21)
    2493           0 :             nBoxes0 = 21;
    2494             : 
    2495         216 :         for (sal_uInt32 m = 0; m < 2; m++)
    2496             :         {
    2497         144 :             m_rWW8Export.InsUInt16( aSprmIds[m] );
    2498         144 :             m_rWW8Export.pO->push_back( static_cast<sal_uInt8>(nBoxes0 * 10) );
    2499             : 
    2500         680 :         for ( sal_uInt8 n = 0; n < nBoxes0; n++ )
    2501             :         {
    2502         536 :             const SwTableBox * pBox1 = rTabBoxes[n];
    2503         536 :             const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
    2504         536 :             const SfxPoolItem * pI = NULL;
    2505         536 :             Color aColor;
    2506             : 
    2507         536 :                 if ( SfxItemState::SET ==
    2508         536 :                          pFrmFmt->GetAttrSet().
    2509         536 :                          GetItemState( RES_BACKGROUND, false, &pI ) )
    2510             :             {
    2511          92 :                 aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
    2512             :             }
    2513             :             else
    2514         444 :                 aColor = COL_AUTO;
    2515             : 
    2516         536 :             WW8SHDLong aSHD;
    2517         536 :             aSHD.setCvFore( 0xFF000000 );
    2518             : 
    2519         536 :             sal_uInt32 nBgColor = aColor.GetColor();
    2520         536 :             if ( nBgColor == COL_AUTO )
    2521         444 :                 aSHD.setCvBack( 0xFF000000 );
    2522             :             else
    2523          92 :                 aSHD.setCvBack( wwUtility::RGBToBGR( nBgColor ) );
    2524             : 
    2525         536 :             aSHD.Write( m_rWW8Export );
    2526         536 :         }
    2527             :         }
    2528             :     }
    2529          72 : }
    2530             : 
    2531         684 : void WW8Export::SectionBreaksAndFrames( const SwTxtNode& rNode )
    2532             : {
    2533             :     // output page/section breaks
    2534         684 :     OutputSectionBreaks( rNode.GetpSwAttrSet(), rNode );
    2535             : 
    2536             :     // all textframes anchored as character for the winword 7- format
    2537         684 :     if ( !bWrtWW8 && !IsInTable() )
    2538           0 :         OutWW6FlyFrmsInCntnt( rNode );
    2539         684 : }
    2540             : 
    2541        2322 : void MSWordExportBase::WriteText()
    2542             : {
    2543       55948 :     while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode ||
    2544        5936 :            ( pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode &&
    2545        2322 :              pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex() ) )
    2546             :     {
    2547       24360 :         SwNode& rNd = pCurPam->GetNode();
    2548             : 
    2549       24360 :         if ( rNd.IsTxtNode() )
    2550       14348 :             SectionBreaksAndFrames( *rNd.GetTxtNode() );
    2551             : 
    2552             :         // output the various types of nodes
    2553       24360 :         if ( rNd.IsCntntNode() )
    2554             :         {
    2555       14350 :             SwCntntNode* pCNd = (SwCntntNode*)&rNd;
    2556             : 
    2557       14350 :             const SwPageDesc* pTemp = rNd.FindPageDesc(false);
    2558       14350 :             if ( pTemp )
    2559       14350 :                 pAktPageDesc = pTemp;
    2560             : 
    2561       14350 :             pCurPam->GetPoint()->nContent.Assign( pCNd, 0 );
    2562       14350 :             OutputContentNode( *pCNd );
    2563             :         }
    2564       10010 :         else if ( rNd.IsTableNode() )
    2565             :         {
    2566         320 :             mpTableInfo->processSwTable( &rNd.GetTableNode()->GetTable() );
    2567             :         }
    2568        9690 :         else if ( rNd.IsSectionNode() && TXT_MAINTEXT == nTxtTyp )
    2569          96 :             OutputSectionNode( *rNd.GetSectionNode() );
    2570       14288 :         else if ( TXT_MAINTEXT == nTxtTyp && rNd.IsEndNode() &&
    2571        4694 :                   rNd.StartOfSectionNode()->IsSectionNode() )
    2572             :         {
    2573          96 :             const SwSection& rSect = rNd.StartOfSectionNode()->GetSectionNode()
    2574          96 :                                         ->GetSection();
    2575          96 :             if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() )
    2576           0 :                 bStartTOX = false;
    2577             : 
    2578          96 :             SwNodeIndex aIdx( rNd, 1 );
    2579          96 :             if ( aIdx.GetNode().IsEndNode() && aIdx.GetNode().StartOfSectionNode()->IsSectionNode() )
    2580             :                 ;
    2581          96 :             else if ( aIdx.GetNode().IsSectionNode() )
    2582             :                 ;
    2583         176 :             else if ( !IsInTable()
    2584          88 :                 && (rSect.GetType() != TOX_CONTENT_SECTION && rSect.GetType() != TOX_HEADER_SECTION )) //No sections in table
    2585             :             {
    2586             :                 //#120140# Do not need to insert a page/section break after a section end. Check this case first
    2587          28 :                 bool bNeedExportBreakHere = true;
    2588          28 :                 if ( aIdx.GetNode().IsTxtNode() )
    2589             :                 {
    2590           4 :                     SwTxtNode *pTempNext = aIdx.GetNode().GetTxtNode();
    2591           4 :                     if ( pTempNext )
    2592             :                     {
    2593           4 :                         const SfxPoolItem * pTempItem = NULL;
    2594          12 :                         if (pTempNext->GetpSwAttrSet() && SfxItemState::SET == pTempNext->GetpSwAttrSet()->GetItemState(RES_PAGEDESC, false, &pTempItem)
    2595           8 :                             && pTempItem && ((SwFmtPageDesc*)pTempItem)->GetRegisteredIn())
    2596             :                         {
    2597             :                             //Next node has a new page style which means this node is a section end. Do not insert another page/section break here
    2598           4 :                             bNeedExportBreakHere = false;
    2599             :                         }
    2600             :                     }
    2601             :                 }
    2602             :                 else
    2603             :                 {
    2604             :                     /* Do not export Section Break in case DOCX containing MultiColumn and
    2605             :                      * aIdx.GetNode().IsTxtNode() is False i.e. Text node is NULL.
    2606             :                      */
    2607          24 :                     const SwFrmFmt* pPgFmt = rSect.GetFmt();
    2608          24 :                     const SwFmtCol& rCol = pPgFmt->GetCol();
    2609          24 :                     sal_uInt16 nColumnCount = rCol.GetNumCols();
    2610          24 :                     if(nColumnCount > 1)
    2611             :                     {
    2612          14 :                         bNeedExportBreakHere = false;
    2613             :                     }
    2614             :                 }
    2615             : 
    2616          28 :                 if (bNeedExportBreakHere)  //#120140# End of check
    2617             :                 {
    2618          10 :                     ReplaceCr( (char)0xc ); // indicator for Page/Section-Break
    2619             : 
    2620          10 :                     const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent();
    2621          10 :                     if ( !pParentFmt )
    2622          10 :                         pParentFmt = (SwSectionFmt*)0xFFFFFFFF;
    2623             : 
    2624             :                     sal_uLong nRstLnNum;
    2625          10 :                     if ( aIdx.GetNode().IsCntntNode() )
    2626           0 :                         nRstLnNum = ((SwCntntNode&)aIdx.GetNode()).GetSwAttrSet().
    2627           0 :                                                 GetLineNumber().GetStartValue();
    2628             :                     else
    2629          10 :                         nRstLnNum = 0;
    2630             : 
    2631          10 :                     AppendSection( pAktPageDesc, pParentFmt, nRstLnNum );
    2632             :                 }
    2633          96 :             }
    2634             :         }
    2635        9498 :         else if ( rNd.IsStartNode() )
    2636             :         {
    2637        4634 :             OutputStartNode( *rNd.GetStartNode() );
    2638             :         }
    2639        4864 :         else if ( rNd.IsEndNode() )
    2640             :         {
    2641        4864 :             OutputEndNode( *rNd.GetEndNode() );
    2642             :         }
    2643             : 
    2644       24360 :         if ( &rNd == &rNd.GetNodes().GetEndOfContent() )
    2645        1030 :             break;
    2646             : 
    2647       23330 :         const SwNode * pCurrentNode = &pCurPam->GetPoint()->nNode.GetNode();
    2648       23330 :         const SwNode * pNextNode = mpTableInfo->getNextNode(pCurrentNode);
    2649             : 
    2650       23330 :         if (pCurrentNode == pNextNode)
    2651             :         {
    2652             :             SAL_WARN("sw.ww8", "loop in TableInfo");
    2653           0 :             pNextNode = NULL;
    2654             :         }
    2655             : 
    2656       23330 :         if (pNextNode != NULL)
    2657       11434 :             pCurPam->GetPoint()->nNode = SwNodeIndex(*pNextNode);
    2658             :         else
    2659       11896 :             pCurPam->GetPoint()->nNode++;
    2660             : 
    2661       23330 :         sal_uLong nPos = pCurPam->GetPoint()->nNode.GetIndex();
    2662       23330 :         ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() );
    2663             :     }
    2664             : 
    2665             :     SAL_INFO( "sw.ww8.level2", "</WriteText>" );
    2666        2322 : }
    2667             : 
    2668          34 : void WW8Export::WriteMainText()
    2669             : {
    2670             :     SAL_INFO( "sw.ww8.level2", "<WriteMainText>" );
    2671             : 
    2672          34 :     pFib->fcMin = Strm().Tell();
    2673             : 
    2674          34 :     pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();
    2675             : 
    2676          34 :     WriteText();
    2677             : 
    2678          34 :     if( 0 == Strm().Tell() - pFib->fcMin )  // no text ?
    2679           0 :         WriteCR();                  // then CR at the end ( otherwise WW will complain )
    2680             : 
    2681          34 :     pFib->ccpText = Fc2Cp( Strm().Tell() );
    2682          34 :     pFldMain->Finish( pFib->ccpText, 0 );
    2683             : 
    2684             :                     // ccpText includes Footnote and KF-text
    2685             :                     // therefore pFib->ccpText may get updated as well
    2686             :     // save the StyleId of the last paragraph. Because WW97 take the style
    2687             :     // from the last CR, that will be writen after footer/Header/footnotes/
    2688             :     // annotation usw.
    2689          34 :     const SwTxtNode* pLastNd = pCurPam->GetMark()->nNode.GetNode().GetTxtNode();
    2690          34 :     if( pLastNd )
    2691           0 :         nLastFmtId = GetId( (SwTxtFmtColl&)pLastNd->GetAnyFmtColl() );
    2692             : 
    2693             :     SAL_INFO( "sw.ww8.level2", "</WriteMainText>" );
    2694          34 : }
    2695             : 
    2696         282 : bool MSWordExportBase::IsInTable() const
    2697             : {
    2698         282 :     bool bResult = false;
    2699             : 
    2700         282 :     if (pCurPam != NULL)
    2701             :     {
    2702         282 :         SwNode& rNode = pCurPam->GetNode();
    2703             : 
    2704         282 :         if (mpTableInfo.get() != NULL)
    2705             :         {
    2706         282 :             ww8::WW8TableNodeInfo::Pointer_t pTableNodeInfo = mpTableInfo->getTableNodeInfo(&rNode);
    2707             : 
    2708         282 :             if (pTableNodeInfo.get() != NULL && pTableNodeInfo->getDepth() > 0)
    2709             :             {
    2710          16 :                 bResult = true;
    2711         282 :             }
    2712             :         }
    2713             :     }
    2714             : 
    2715         282 :     return bResult;
    2716             : }
    2717             : 
    2718             : typedef ww8::WW8Sttb< ww8::WW8Struct >  WW8SttbAssoc;
    2719             : 
    2720          34 : void WW8Export::WriteFkpPlcUsw()
    2721             : {
    2722          34 :     if( !bWrtWW8 )
    2723             :     {
    2724             :         static const sal_uInt8 aSpec[2] =
    2725             :         {
    2726             :             117, 1
    2727             :         };
    2728             : 
    2729           0 :         pChpPlc->AppendFkpEntry( Strm().Tell() );   // Sepx with fSpecial
    2730           0 :         pSepx->WriteSepx( Strm() );                 // Slcx.Sepx
    2731           0 :         pGrf->Write();                              // Graphics
    2732           0 :         pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aSpec ), aSpec );
    2733             : 
    2734           0 :         pChpPlc->WriteFkps();                   // Fkp.Chpx
    2735           0 :         pPapPlc->WriteFkps();                   // Fkp.Papx
    2736           0 :         pStyles->OutputStylesTable();           // Styles
    2737           0 :         pFtn->WritePlc( *this );                // Footnote-Ref & Text Plc
    2738           0 :         pEdn->WritePlc( *this );                // Endnote-Ref & Text Plc
    2739           0 :         pAtn->WritePlc( *this );                // Annotation-Ref & Text Plc
    2740           0 :         pSepx->WritePlcSed( *this );            // Slcx.PlcSed
    2741           0 :         pSepx->WritePlcHdd( *this );            // Slcx.PlcHdd
    2742           0 :         pChpPlc->WritePlc();                    // Plcx.Chpx
    2743           0 :         pPapPlc->WritePlc();                    // Plcx.Papx
    2744           0 :         maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs
    2745           0 :         if( pRedlAuthors )
    2746           0 :             pRedlAuthors->Write( GetWriter() );       // sttbfRMark (RedlineAuthors)
    2747           0 :         pFldMain->Write( *this );               // Fields ( Main Text )
    2748           0 :         pFldHdFt->Write( *this );               // Fields ( Header/Footer )
    2749           0 :         pFldFtn->Write( *this );                // Fields ( FootNotes )
    2750           0 :         pFldEdn->Write( *this );                // Fields ( EndNotes )
    2751           0 :         pFldAtn->Write( *this );                // Fields ( Annotations )
    2752           0 :         pBkmks->Write( *this );                 // Bookmarks - sttbfBkmk/
    2753             :                                                 // plcfBkmkf/plcfBkmkl
    2754           0 :         WriteDop( *this );                      // Document-Properties
    2755             : 
    2756             :     }
    2757             :     else
    2758             :     {
    2759             :         // Graphics in the data stream
    2760          34 :         pGrf->Write();                          // Graphics
    2761             : 
    2762             :         // Ausgabe in WordDocument-Stream
    2763          34 :         pChpPlc->WriteFkps();                   // Fkp.Chpx
    2764          34 :         pPapPlc->WriteFkps();                   // Fkp.Papx
    2765          34 :         pSepx->WriteSepx( Strm() );             // Sepx
    2766             : 
    2767             :         // Ausagbe in Table-Stream
    2768          34 :         pStyles->OutputStylesTable();           // for WW8 StyleTab
    2769          34 :         pFtn->WritePlc( *this );                // Footnote-Ref & Text Plc
    2770          34 :         pEdn->WritePlc( *this );                // Endnote-Ref & Text Plc
    2771          34 :         pTxtBxs->WritePlc( *this );             // Textbox Text Plc
    2772          34 :         pHFTxtBxs->WritePlc( *this );           // Head/Foot-Textbox Text Plc
    2773          34 :         pAtn->WritePlc( *this );                // Annotation-Ref & Text Plc
    2774             : 
    2775          34 :         pSepx->WritePlcSed( *this );            // Slcx.PlcSed
    2776          34 :         pSepx->WritePlcHdd( *this );            // Slcx.PlcHdd
    2777             : 
    2778          34 :         pChpPlc->WritePlc();                    // Plcx.Chpx
    2779          34 :         pPapPlc->WritePlc();                    // Plcx.Papx
    2780             : 
    2781          34 :         if( pRedlAuthors )
    2782           6 :             pRedlAuthors->Write( GetWriter() );       // sttbfRMark (RedlineAuthors)
    2783          34 :         pFldMain->Write( *this );               // Fields ( Main Text )
    2784          34 :         pFldHdFt->Write( *this );               // Fields ( Header/Footer )
    2785          34 :         pFldFtn->Write( *this );                // Fields ( FootNotes )
    2786          34 :         pFldEdn->Write( *this );                // Fields ( EndNotes )
    2787          34 :         pFldAtn->Write( *this );                // Fields ( Annotations )
    2788          34 :         pFldTxtBxs->Write( *this );             // Fields ( Textboxes )
    2789          34 :         pFldHFTxtBxs->Write( *this );           // Fields ( Head/Foot-Textboxes )
    2790             : 
    2791          34 :         if (pEscher || pDoc->ContainsMSVBasic())
    2792             :         {
    2793             :             /*
    2794             :              Everytime MS 2000 creates an escher stream there is always
    2795             :              an ObjectPool dir (even if empty). It turns out that if a copy of
    2796             :              MS 2000 is used to open a document that contains escher graphics
    2797             :              exported from StarOffice without this empty dir then *if* that
    2798             :              copy of MS Office has never been used to open a MSOffice document
    2799             :              that has escher graphics (and an ObjectPool dir of course) and
    2800             :              that copy of office has not been used to draw escher graphics then
    2801             :              our exported graphics do not appear. Once you do open a ms
    2802             :              document with escher graphics or draw an escher graphic with that
    2803             :              copy of word, then all documents from staroffice that contain
    2804             :              escher work from then on. Tricky to track down, some sort of late
    2805             :              binding trickery in MS where solely for first time initialization
    2806             :              the existence of an ObjectPool dir is necessary for triggering
    2807             :              some magic. cmc
    2808             :             */
    2809             :             // avoid memory leak #i120098#, the unnamed obj will be released in destructor.
    2810          16 :             xEscherStg = GetWriter().GetStorage().OpenSotStorage(OUString(SL::aObjectPool),
    2811           8 :                 STREAM_READWRITE | STREAM_SHARE_DENYALL);
    2812             :         }
    2813             : 
    2814             :         // dggInfo - escher stream
    2815          34 :         WriteEscher();
    2816             : 
    2817          34 :         pSdrObjs->WritePlc( *this );
    2818          34 :         pHFSdrObjs->WritePlc( *this );
    2819             :         // spamom - office drawing table
    2820             :         // spahdr - header office drawing table
    2821             : 
    2822          34 :         pBkmks->Write( *this );                 // Bookmarks - sttbfBkmk/
    2823             :                                                 // plcfBkmkf/plcfBkmkl
    2824             : 
    2825          34 :         WriteNumbering();
    2826             : 
    2827          34 :         RestoreMacroCmds();
    2828             : 
    2829          34 :         pMagicTable->Write( *this );
    2830             : 
    2831          34 :         pPiece->WritePc( *this );               // Piece-Table
    2832          34 :         maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs
    2833             : 
    2834             :         //Convert OOo asian typography into MS typography structure
    2835          34 :         ExportDopTypography(pDop->doptypography);
    2836             : 
    2837          34 :         WriteDop( *this );                      // Document-Properties
    2838             : 
    2839             :         // Write SttbfAssoc
    2840             :         WW8SttbAssoc * pSttbfAssoc = dynamic_cast<WW8SttbAssoc *>
    2841          34 :             (pDoc->getIDocumentExternalData().getExternalData(::sw::STTBF_ASSOC).get());
    2842             : 
    2843          34 :         if ( pSttbfAssoc )                      // #i106057#
    2844             :         {
    2845          16 :         ::std::vector<OUString> aStrings;
    2846             : 
    2847          16 :         ::ww8::StringVector_t & aSttbStrings = pSttbfAssoc->getStrings();
    2848          16 :         ::ww8::StringVector_t::const_iterator aItEnd = aSttbStrings.end();
    2849         232 :         for (::ww8::StringVector_t::const_iterator aIt = aSttbStrings.begin();
    2850             :              aIt != aItEnd; ++aIt)
    2851             :         {
    2852         216 :             aStrings.push_back(aIt->getStr());
    2853             :         }
    2854             : 
    2855             :         WriteAsStringTable(aStrings, pFib->fcSttbfAssoc,
    2856          16 :                            pFib->lcbSttbfAssoc);
    2857             :         }
    2858             :     }
    2859          34 :     Strm().Seek( 0 );
    2860             : 
    2861             :     // Reclaim stored FIB data from document.
    2862             :     ::ww8::WW8FibData * pFibData = dynamic_cast<ww8::WW8FibData *>
    2863          34 :           (pDoc->getIDocumentExternalData().getExternalData(::sw::FIB).get());
    2864             : 
    2865          34 :     if ( pFibData )
    2866             :     {
    2867          16 :     pFib->fReadOnlyRecommended =
    2868          32 :         pFibData->getReadOnlyRecommended() ? 1 : 0;
    2869          16 :     pFib->fWriteReservation =
    2870          32 :         pFibData->getWriteReservation() ? 1 : 0;
    2871             :     }
    2872             : 
    2873          34 :     pFib->Write( Strm() );  // FIB
    2874          34 : }
    2875             : 
    2876          34 : void WW8Export::StoreDoc1()
    2877             : {
    2878          34 :     bool bNeedsFinalPara = false;
    2879             :     // Start of Text ( Mangel ueber )
    2880          34 :     SwWW8Writer::FillUntil( Strm(), pFib->fcMin );
    2881             : 
    2882          34 :     WriteMainText();                    // main text
    2883             :     sal_uInt8 nSprmsLen;
    2884          34 :     sal_uInt8 *pLastSprms = pPapPlc->CopyLastSprms(nSprmsLen);
    2885             : 
    2886          34 :     bNeedsFinalPara |= pFtn->WriteTxt( *this );         // Footnote-Text
    2887          34 :     bNeedsFinalPara |= pSepx->WriteKFTxt( *this );          // K/F-Text
    2888          34 :     bNeedsFinalPara |= pAtn->WriteTxt( *this );         // Annotation-Text
    2889          34 :     bNeedsFinalPara |= pEdn->WriteTxt( *this );         // EndNote-Text
    2890             : 
    2891             :     // create the escher streams
    2892          34 :     if( bWrtWW8 )
    2893          34 :         CreateEscher();
    2894             : 
    2895          34 :     bNeedsFinalPara |= pTxtBxs->WriteTxt( *this );  //Textbox Text Plc
    2896          34 :     bNeedsFinalPara |= pHFTxtBxs->WriteTxt( *this );//Head/Foot-Textbox Text Plc
    2897             : 
    2898          34 :     if (bNeedsFinalPara)
    2899             :     {
    2900          20 :         WriteCR();
    2901          20 :         pPapPlc->AppendFkpEntry(Strm().Tell(), nSprmsLen, pLastSprms);
    2902             :     }
    2903          34 :     delete[] pLastSprms;
    2904             : 
    2905          34 :     pSepx->Finish( Fc2Cp( Strm().Tell() ));// Text + Ftn + HdFt als Section-Ende
    2906          34 :     pMagicTable->Finish( Fc2Cp( Strm().Tell() ),0);
    2907             : 
    2908          34 :     pFib->fcMac = Strm().Tell();        // End of all texts
    2909             : 
    2910          34 :     WriteFkpPlcUsw();                   // FKP, PLC, .....
    2911          34 : }
    2912             : 
    2913         430 : void MSWordExportBase::AddLinkTarget(const OUString& rURL)
    2914             : {
    2915         430 :     if( rURL.isEmpty() || rURL[0] != '#' )
    2916         658 :         return;
    2917             : 
    2918         198 :     OUString aURL( BookmarkToWriter( rURL.copy( 1 ) ) );
    2919         198 :     sal_Int32 nPos = aURL.lastIndexOf( cMarkSeparator );
    2920             : 
    2921         198 :     if( nPos < 2 )
    2922         194 :         return;
    2923             : 
    2924           8 :     OUString sCmp(comphelper::string::remove(aURL.copy(nPos+1), ' '));
    2925           4 :     if( sCmp.isEmpty() )
    2926           0 :         return;
    2927             : 
    2928           4 :     sCmp = sCmp.toAsciiLowerCase();
    2929             : 
    2930           4 :     if( sCmp == "outline" )
    2931             :     {
    2932           0 :         SwPosition aPos( *pCurPam->GetPoint() );
    2933           0 :         OUString aOutline( BookmarkToWriter(aURL.copy( 0, nPos )) );
    2934             :         // If we can find the outline this bookmark refers to
    2935             :         // save the name of the bookmark and the
    2936             :         // node index number of where it points to
    2937           0 :         if( pDoc->GotoOutline( aPos, aOutline ) )
    2938             :         {
    2939           0 :             sal_uLong nIdx = aPos.nNode.GetIndex();
    2940           0 :             aBookmarkPair aImplicitBookmark;
    2941           0 :             aImplicitBookmark.first = aOutline;
    2942           0 :             aImplicitBookmark.second = nIdx;
    2943           0 :             maImplicitBookmarks.push_back(aImplicitBookmark);
    2944           0 :         }
    2945           4 :     }
    2946             : }
    2947             : 
    2948        1032 : void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc)
    2949             : {
    2950             :     const SwFmtINetFmt* pINetFmt;
    2951             :     const SwTxtINetFmt* pTxtAttr;
    2952             :     const SwTxtNode* pTxtNd;
    2953             : 
    2954        1032 :     sal_uInt32 n, nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
    2955        1596 :     for( n = 0; n < nMaxItems; ++n )
    2956             :     {
    2957        1128 :         if( 0 != (pINetFmt = (SwFmtINetFmt*)rDoc.GetAttrPool().GetItem2(
    2958         994 :             RES_TXTATR_INETFMT, n ) ) &&
    2959         430 :             0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) &&
    2960         994 :             0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
    2961         430 :             pTxtNd->GetNodes().IsDocNodes() )
    2962             :         {
    2963         430 :             AddLinkTarget( pINetFmt->GetValue() );
    2964             :         }
    2965             :     }
    2966             : 
    2967             :     const SwFmtURL *pURL;
    2968        1032 :     nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_URL );
    2969        1032 :     for( n = 0; n < nMaxItems; ++n )
    2970             :     {
    2971           0 :         if( 0 != (pURL = (SwFmtURL*)rDoc.GetAttrPool().GetItem2(
    2972           0 :             RES_URL, n ) ) )
    2973             :         {
    2974           0 :             AddLinkTarget( pURL->GetURL() );
    2975           0 :             const ImageMap *pIMap = pURL->GetMap();
    2976           0 :             if( pIMap )
    2977             :             {
    2978           0 :                 for( sal_uInt16 i=0; i<pIMap->GetIMapObjectCount(); i++ )
    2979             :                 {
    2980           0 :                     const IMapObject* pObj = pIMap->GetIMapObject( i );
    2981           0 :                     if( pObj )
    2982             :                     {
    2983           0 :                         AddLinkTarget( pObj->GetURL() );
    2984             :                     }
    2985             :                 }
    2986             :             }
    2987             :         }
    2988             :     }
    2989        1032 : }
    2990             : 
    2991             : namespace
    2992             : {
    2993             :     const sal_uLong WW_BLOCKSIZE = 0x200;
    2994             : 
    2995           0 :     void EncryptRC4(msfilter::MSCodec_Std97& rCtx, SvStream &rIn, SvStream &rOut)
    2996             :     {
    2997           0 :         rIn.Seek(STREAM_SEEK_TO_END);
    2998           0 :         sal_uLong nLen = rIn.Tell();
    2999           0 :         rIn.Seek(0);
    3000             : 
    3001             :         sal_uInt8 in[WW_BLOCKSIZE];
    3002           0 :         for (sal_Size nI = 0, nBlock = 0; nI < nLen; nI += WW_BLOCKSIZE, ++nBlock)
    3003             :         {
    3004           0 :             sal_Size nBS = (nLen - nI > WW_BLOCKSIZE) ? WW_BLOCKSIZE : nLen - nI;
    3005           0 :             nBS = rIn.Read(in, nBS);
    3006           0 :             rCtx.InitCipher(nBlock);
    3007           0 :             rCtx.Encode(in, nBS, in, nBS);
    3008           0 :             rOut.Write(in, nBS);
    3009             :         }
    3010           0 :     }
    3011             : }
    3012             : 
    3013        1032 : void MSWordExportBase::ExportDocument( bool bWriteAll )
    3014             : {
    3015        1032 :     nCharFmtStart = ANZ_DEFAULT_STYLES;
    3016        1032 :     nFmtCollStart = nCharFmtStart + pDoc->GetCharFmts()->size() - 1;
    3017             : 
    3018             :     bStyDef = bBreakBefore = bOutKF =
    3019             :         bOutFlyFrmAttrs = bOutPageDescs = bOutTable = bOutFirstPage =
    3020             :         bOutGrf = bInWriteEscher = bStartTOX =
    3021        1032 :         bInWriteTOX = false;
    3022             : 
    3023        1032 :     bFtnAtTxtEnd = bEndAtTxtEnd = true;
    3024             : 
    3025        1032 :     mpParentFrame = 0;
    3026        1032 :     pFlyOffset = 0;
    3027        1032 :     eNewAnchorType = FLY_AT_PAGE;
    3028        1032 :     nTxtTyp = TXT_MAINTEXT;
    3029        1032 :     nStyleBeforeFly = nLastFmtId = 0;
    3030        1032 :     pStyAttr = 0;
    3031        1032 :     pCurrentStyle = NULL;
    3032        1032 :     pOutFmtNode = 0;
    3033        1032 :     pEscher = 0;
    3034        1032 :     pRedlAuthors = 0;
    3035        1032 :     aTOXArr.clear();
    3036             : 
    3037        1032 :     if ( !pOLEExp )
    3038             :     {
    3039        1032 :         sal_uInt32 nSvxMSDffOLEConvFlags = 0;
    3040        1032 :         const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
    3041        1032 :         if ( rOpt.IsMath2MathType() )
    3042        1032 :             nSvxMSDffOLEConvFlags |= OLE_STARMATH_2_MATHTYPE;
    3043        1032 :         if ( rOpt.IsWriter2WinWord() )
    3044        1032 :             nSvxMSDffOLEConvFlags |= OLE_STARWRITER_2_WINWORD;
    3045        1032 :         if ( rOpt.IsCalc2Excel() )
    3046        1032 :             nSvxMSDffOLEConvFlags |= OLE_STARCALC_2_EXCEL;
    3047        1032 :         if ( rOpt.IsImpress2PowerPoint() )
    3048        1032 :             nSvxMSDffOLEConvFlags |= OLE_STARIMPRESS_2_POWERPOINT;
    3049             : 
    3050        1032 :         pOLEExp = new SvxMSExportOLEObjects( nSvxMSDffOLEConvFlags );
    3051             :     }
    3052             : 
    3053        1032 :     if ( !pOCXExp && pDoc->GetDocShell() )
    3054        1030 :         pOCXExp = new SwMSConvertControls( pDoc->GetDocShell(), pCurPam );
    3055             : 
    3056             :     // #i81405# - Collect anchored objects before changing the redline mode.
    3057        1032 :     maFrames = GetFrames( *pDoc, bWriteAll? NULL : pOrigPam );
    3058             : 
    3059        1032 :     mnRedlineMode = pDoc->getIDocumentRedlineAccess().GetRedlineMode();
    3060        1032 :     if ( !pDoc->getIDocumentRedlineAccess().GetRedlineTbl().empty() )
    3061             :     {
    3062          34 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode( (RedlineMode_t)(mnRedlineMode | nsRedlineMode_t::REDLINE_SHOW_DELETE |
    3063          34 :                                      nsRedlineMode_t::REDLINE_SHOW_INSERT) );
    3064             :     }
    3065             : 
    3066        1032 :     maFontHelper.InitFontTable( SupportsUnicode(), *pDoc );
    3067        1032 :     GatherChapterFields();
    3068             : 
    3069        1032 :     CollectOutlineBookmarks(*pDoc);
    3070             : 
    3071             :     // make unique OrdNums (Z-Order) for all drawing-/fly Objects
    3072        1032 :     if ( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
    3073        1032 :         pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums();
    3074             : 
    3075        1032 :     ExportDocument_Impl();
    3076             : 
    3077        1032 :     if ( mnRedlineMode != pDoc->getIDocumentRedlineAccess().GetRedlineMode() )
    3078           0 :         pDoc->getIDocumentRedlineAccess().SetRedlineMode( (RedlineMode_t)(mnRedlineMode) );
    3079        1032 : }
    3080             : 
    3081          34 : bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec )
    3082             : {
    3083          34 :     uno::Sequence< beans::NamedValue > aEncryptionData;
    3084             : 
    3085          34 :     if ( mpMedium )
    3086             :     {
    3087          34 :         SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
    3088          34 :         if ( pEncryptionDataItem && ( pEncryptionDataItem->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) )
    3089             :         {
    3090             :             OSL_ENSURE( false, "Unexpected EncryptionData!" );
    3091           0 :             aEncryptionData.realloc( 0 );
    3092             :         }
    3093             : 
    3094          34 :         if ( !aEncryptionData.getLength() )
    3095             :         {
    3096             :             // try to generate the encryption data based on password
    3097          34 :             SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, false );
    3098          34 :             if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() && pPasswordItem->GetValue().getLength() <= 15 )
    3099             :             {
    3100             :                 // Generate random number with a seed of time as salt.
    3101             :                 TimeValue aTime;
    3102           0 :                 osl_getSystemTime( &aTime );
    3103           0 :                 rtlRandomPool aRandomPool = rtl_random_createPool ();
    3104           0 :                 rtl_random_addBytes ( aRandomPool, &aTime, 8 );
    3105             : 
    3106             :                 sal_uInt8 pDocId[ 16 ];
    3107           0 :                 rtl_random_getBytes( aRandomPool, pDocId, 16 );
    3108             : 
    3109           0 :                 rtl_random_destroyPool( aRandomPool );
    3110             : 
    3111             :                 sal_Unicode aPassword[16];
    3112           0 :                 memset( aPassword, 0, sizeof( aPassword ) );
    3113             : 
    3114           0 :                 OUString sPassword(pPasswordItem->GetValue());
    3115           0 :                 for ( sal_Int32 nChar = 0; nChar < sPassword.getLength(); ++nChar )
    3116           0 :                     aPassword[nChar] = sPassword[nChar];
    3117             : 
    3118           0 :                 rCodec.InitKey( aPassword, pDocId );
    3119           0 :                 aEncryptionData = rCodec.GetEncryptionData();
    3120             : 
    3121           0 :                 mpMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );
    3122             :             }
    3123             :         }
    3124             : 
    3125          34 :         if ( aEncryptionData.getLength() )
    3126           0 :             mpMedium->GetItemSet()->ClearItem( SID_PASSWORD );
    3127             :     }
    3128             : 
    3129             :     // nonempty encryption data means hier that the codec was successfully initialized
    3130          34 :     return ( aEncryptionData.getLength() != 0 );
    3131             : }
    3132             : 
    3133          34 : void WW8Export::ExportDocument_Impl()
    3134             : {
    3135          34 :     PrepareStorage();
    3136             : 
    3137          34 :     pFib = new WW8Fib( bWrtWW8 ? 8 : 6, m_bDot );
    3138             : 
    3139          34 :     SvStorageStreamRef xWwStrm( GetWriter().GetStorage().OpenSotStream( aMainStg ) );
    3140          68 :     SvStorageStreamRef xTableStrm( xWwStrm ), xDataStrm( xWwStrm );
    3141          34 :     xWwStrm->SetBufferSize( 32768 );
    3142             : 
    3143          34 :     if( bWrtWW8 )
    3144             :     {
    3145          34 :         pFib->fWhichTblStm = true;
    3146          68 :         xTableStrm = GetWriter().GetStorage().OpenSotStream(OUString(SL::a1Table),
    3147          34 :             STREAM_STD_WRITE );
    3148          68 :         xDataStrm = GetWriter().GetStorage().OpenSotStream(OUString(SL::aData),
    3149          34 :             STREAM_STD_WRITE );
    3150             : 
    3151          34 :         xDataStrm->SetBufferSize( 32768 );  // for graphics
    3152          34 :         xTableStrm->SetBufferSize( 16384 ); // for the Font-/Style-Table, etc.
    3153             : 
    3154          34 :         xTableStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    3155          34 :         xDataStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    3156             :     }
    3157             : 
    3158          34 :     GetWriter().SetStream( & *xWwStrm );
    3159          34 :     pTableStrm = &xTableStrm;
    3160          34 :     pDataStrm = &xDataStrm;
    3161             : 
    3162          34 :     Strm().SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    3163             : 
    3164          68 :     utl::TempFile aTempMain;
    3165          34 :     aTempMain.EnableKillingFile();
    3166          68 :     utl::TempFile aTempTable;
    3167          34 :     aTempTable.EnableKillingFile();
    3168          68 :     utl::TempFile aTempData;
    3169          34 :     aTempData.EnableKillingFile();
    3170             : 
    3171          68 :     msfilter::MSCodec_Std97 aCtx;
    3172          34 :     bool bEncrypt = GetWriter().InitStd97CodecUpdateMedium(aCtx);
    3173          34 :     if ( bEncrypt )
    3174             :     {
    3175           0 :         GetWriter().SetStream(
    3176           0 :             aTempMain.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ) );
    3177             : 
    3178           0 :         pTableStrm = aTempTable.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
    3179             : 
    3180           0 :         pDataStrm = aTempData.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
    3181             : 
    3182           0 :         sal_uInt8 aRC4EncryptionHeader[ 52 ] = {0};
    3183           0 :         pTableStrm->Write( aRC4EncryptionHeader, 52 );
    3184             :     }
    3185             : 
    3186             :     // Default: "Standard"
    3187          34 :     pSepx = new WW8_WrPlcSepx( *this );                         // Sections/headers/footers
    3188             : 
    3189          34 :     pFtn = new WW8_WrPlcFtnEdn( TXT_FTN );                      // Footnotes
    3190          34 :     pEdn = new WW8_WrPlcFtnEdn( TXT_EDN );                      // Endnotes
    3191          34 :     pAtn = new WW8_WrPlcAnnotations;                                 // PostIts
    3192          34 :     pTxtBxs = new WW8_WrPlcTxtBoxes( TXT_TXTBOX );
    3193          34 :     pHFTxtBxs = new WW8_WrPlcTxtBoxes( TXT_HFTXTBOX );
    3194             : 
    3195          34 :     pSdrObjs = new MainTxtPlcDrawObj;   // Draw-/Fly-Objects for main text
    3196          34 :     pHFSdrObjs = new HdFtPlcDrawObj;    // Draw-/Fly-Objects for header/footer
    3197             : 
    3198          34 :     pBkmks = new WW8_WrtBookmarks;                          // Bookmarks
    3199          34 :     GetWriter().CreateBookmarkTbl();
    3200             : 
    3201          34 :     pPapPlc = new WW8_WrPlcPn( *this, PAP, pFib->fcMin );
    3202          34 :     pChpPlc = new WW8_WrPlcPn( *this, CHP, pFib->fcMin );
    3203          34 :     pO = new ww::bytes();
    3204          34 :     pStyles = new MSWordStyles( *this );
    3205          34 :     pFldMain = new WW8_WrPlcFld( 2, TXT_MAINTEXT );
    3206          34 :     pFldHdFt = new WW8_WrPlcFld( 2, TXT_HDFT );
    3207          34 :     pFldFtn = new WW8_WrPlcFld( 2, TXT_FTN );
    3208          34 :     pFldEdn = new WW8_WrPlcFld( 2, TXT_EDN );
    3209          34 :     pFldAtn = new WW8_WrPlcFld( 2, TXT_ATN );
    3210          34 :     pFldTxtBxs = new WW8_WrPlcFld( 2, TXT_TXTBOX );
    3211          34 :     pFldHFTxtBxs = new WW8_WrPlcFld( 2, TXT_HFTXTBOX );
    3212             : 
    3213          34 :     pMagicTable = new WW8_WrMagicTable;
    3214             : 
    3215          34 :     pGrf = new SwWW8WrGrf( *this );
    3216          34 :     pPiece = new WW8_WrPct( pFib->fcMin, bWrtWW8 );
    3217          34 :     pDop = new WW8Dop;
    3218             : 
    3219          34 :     pDop->fRevMarking = 0 != ( nsRedlineMode_t::REDLINE_ON & mnRedlineMode );
    3220          34 :     pDop->fRMView = 0 != ( nsRedlineMode_t::REDLINE_SHOW_DELETE & mnRedlineMode );
    3221          34 :     pDop->fRMPrint = pDop->fRMView;
    3222             : 
    3223             :     // set AutoHyphenation flag if found in default para style
    3224             :     const SfxPoolItem* pItem;
    3225             :     SwTxtFmtColl* pStdTxtFmtColl =
    3226          34 :         pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false);
    3227          68 :     if (pStdTxtFmtColl && SfxItemState::SET == pStdTxtFmtColl->GetItemState(
    3228          34 :         RES_PARATR_HYPHENZONE, false, &pItem))
    3229             :     {
    3230          20 :         pDop->fAutoHyphen = ((const SvxHyphenZoneItem*)pItem)->IsHyphen();
    3231             :     }
    3232             : 
    3233          34 :     StoreDoc1();
    3234             : 
    3235          34 :     if ( bEncrypt )
    3236             :     {
    3237             :         SvStream *pStrmTemp, *pTableStrmTemp, *pDataStrmTemp;
    3238           0 :         pStrmTemp = &xWwStrm;
    3239           0 :         pTableStrmTemp = &xTableStrm;
    3240           0 :         pDataStrmTemp = &xDataStrm;
    3241             : 
    3242           0 :         if ( pDataStrmTemp && pDataStrmTemp != pStrmTemp)
    3243           0 :             EncryptRC4(aCtx, *pDataStrm, *pDataStrmTemp);
    3244             : 
    3245           0 :         EncryptRC4(aCtx, *pTableStrm, *pTableStrmTemp);
    3246             : 
    3247             :         // Write Unencrypted Header 52 bytes to the start of the table stream
    3248             :         // EncryptionVersionInfo (4 bytes): A Version structure where Version.vMajor MUST be 0x0001, and Version.vMinor MUST be 0x0001.
    3249           0 :         pTableStrmTemp->Seek( 0 );
    3250           0 :         sal_uInt32 nEncType = 0x10001;
    3251           0 :         pTableStrmTemp->WriteUInt32( nEncType );
    3252             : 
    3253             :         sal_uInt8 pDocId[16];
    3254           0 :         aCtx.GetDocId( pDocId );
    3255             : 
    3256             :         sal_uInt8 pSaltData[16];
    3257             :         sal_uInt8 pSaltDigest[16];
    3258           0 :         aCtx.GetEncryptKey( pDocId, pSaltData, pSaltDigest );
    3259             : 
    3260           0 :         pTableStrmTemp->Write( pDocId, 16 );
    3261           0 :         pTableStrmTemp->Write( pSaltData, 16 );
    3262           0 :         pTableStrmTemp->Write( pSaltDigest, 16 );
    3263             : 
    3264           0 :         EncryptRC4(aCtx, GetWriter().Strm(), *pStrmTemp);
    3265             : 
    3266             :         // Write Unencrypted Fib 68 bytes to the start of the workdocument stream
    3267           0 :         pFib->fEncrypted = true; // fEncrypted indicates the document is encrypted.
    3268           0 :         pFib->fObfuscated = false; // Must be 0 for RC4.
    3269           0 :         pFib->nHash = 0x34; // encrypt header bytes count of table stream.
    3270           0 :         pFib->nKey = 0; // lkey2 must be 0 for RC4.
    3271             : 
    3272           0 :         pStrmTemp->Seek( 0 );
    3273           0 :         pFib->WriteHeader( *pStrmTemp );
    3274             :     }
    3275             : 
    3276          34 :     if (pUsedNumTbl)           // all used NumRules
    3277             :     {
    3278             :         // clear the part of the list array that was copied from the document
    3279             :         // - it's an auto delete array, so the rest of the array which are
    3280             :         // duplicated lists that were added during the export will be deleted.
    3281          14 :         pUsedNumTbl->erase(pUsedNumTbl->begin(), pUsedNumTbl->begin() + pUsedNumTbl->size() - nUniqueList);
    3282          14 :         delete pUsedNumTbl;
    3283             :     }
    3284             : 
    3285          34 :     DELETEZ( pGrf );
    3286          34 :     DELETEZ( pMagicTable );
    3287          34 :     DELETEZ( pFldFtn );
    3288          34 :     DELETEZ( pFldTxtBxs );
    3289          34 :     DELETEZ( pFldHFTxtBxs );
    3290          34 :     DELETEZ( pFldAtn );
    3291          34 :     DELETEZ( pFldEdn );
    3292          34 :     DELETEZ( pFldHdFt );
    3293          34 :     DELETEZ( pFldMain );
    3294          34 :     DELETEZ( pStyles );
    3295          34 :     DELETEZ( pO );
    3296          34 :     DELETEZ( pChpPlc );
    3297          34 :     DELETEZ( pPapPlc );
    3298          34 :     DELETEZ( pSepx );
    3299             : 
    3300          34 :     delete pRedlAuthors;
    3301          34 :     delete pSdrObjs;
    3302          34 :     delete pHFSdrObjs;
    3303          34 :     delete pTxtBxs;
    3304          34 :     delete pHFTxtBxs;
    3305          34 :     delete pAtn;
    3306          34 :     delete pEdn;
    3307          34 :     delete pFtn;
    3308          34 :     delete pBkmks;
    3309          34 :     delete pPiece;
    3310          34 :     delete pDop;
    3311          34 :     delete pFib;
    3312          34 :     GetWriter().SetStream( 0 );
    3313             : 
    3314          34 :     xWwStrm->SetBufferSize( 0 );
    3315          34 :     if( bWrtWW8 )
    3316             :     {
    3317          34 :         xTableStrm->SetBufferSize( 0 );
    3318          34 :         xDataStrm->SetBufferSize( 0 );
    3319          34 :         if( 0 == pDataStrm->Seek( STREAM_SEEK_TO_END ))
    3320             :         {
    3321          28 :             xDataStrm.Clear();
    3322          28 :             pDataStrm = 0;
    3323          28 :             GetWriter().GetStorage().Remove(OUString(SL::aData));
    3324             :         }
    3325          34 :     }
    3326          34 : }
    3327             : 
    3328          34 : void WW8Export::PrepareStorage()
    3329             : {
    3330             :     sal_uLong nLen;
    3331             :     const sal_uInt8* pData;
    3332             :     const char* pName;
    3333             :     sal_uInt32 nId1;
    3334             : 
    3335          34 :     if (bWrtWW8)
    3336             :     {
    3337             :         static const char aUserName[] = "Microsoft Word-Document";
    3338             :         static const sal_uInt8 aCompObj[] =
    3339             :         {
    3340             :             0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
    3341             :             0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x09, 0x02, 0x00,
    3342             :             0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
    3343             :             0x00, 0x00, 0x00, 0x46, 0x18, 0x00, 0x00, 0x00,
    3344             :             0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
    3345             :             0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x2D, 0x44,
    3346             :             0x6F, 0x6B, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x00,
    3347             :             0x0A, 0x00, 0x00, 0x00, 0x4D, 0x53, 0x57, 0x6F,
    3348             :             0x72, 0x64, 0x44, 0x6F, 0x63, 0x00, 0x10, 0x00,
    3349             :             0x00, 0x00, 0x57, 0x6F, 0x72, 0x64, 0x2E, 0x44,
    3350             :             0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E,
    3351             :             0x38, 0x00, 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00,
    3352             :             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    3353             :             0x00, 0x00
    3354             :         };
    3355             : 
    3356          34 :         pName = aUserName;
    3357          34 :         pData = aCompObj;
    3358          34 :         nLen = sizeof( aCompObj );
    3359          34 :         nId1 = 0x00020906L;
    3360             :     }
    3361             :     else
    3362             :     {
    3363             :         static const char aUserName[] = "Microsoft Word 6.0 Document";
    3364             :         static const sal_uInt8 aCompObj[] =
    3365             :         {
    3366             :             0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00,
    3367             :             0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x09, 0x02, 0x00,
    3368             :             0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
    3369             :             0x00, 0x00, 0x00, 0x46, 0x1C, 0x00, 0x00, 0x00,
    3370             :             0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66,
    3371             :             0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x36,
    3372             :             0x2E, 0x30, 0x2D, 0x44, 0x6F, 0x6B, 0x75, 0x6D,
    3373             :             0x65, 0x6E, 0x74, 0x00, 0x0A, 0x00, 0x00, 0x00,
    3374             :             0x4D, 0x53, 0x57, 0x6F, 0x72, 0x64, 0x44, 0x6F,
    3375             :             0x63, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x6F,
    3376             :             0x72, 0x64, 0x2E, 0x44, 0x6F, 0x63, 0x75, 0x6D,
    3377             :             0x65, 0x6E, 0x74, 0x2E, 0x36, 0x00, 0x00, 0x00,
    3378             :             0x00, 0x00
    3379             :         };
    3380             : 
    3381           0 :         pName = aUserName;
    3382           0 :         pData = aCompObj;
    3383           0 :         nLen = sizeof( aCompObj );
    3384           0 :         nId1 = 0x00020900L;
    3385             :     }
    3386             : 
    3387             :     SvGlobalName aGName( nId1, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00,
    3388          34 :                          0x00, 0x00, 0x00, 0x46 );
    3389          34 :     GetWriter().GetStorage().SetClass( aGName, 0, OUString::createFromAscii( pName ));
    3390          68 :     SvStorageStreamRef xStor( GetWriter().GetStorage().OpenSotStream(sCompObj) );
    3391          34 :     xStor->Write( pData, nLen );
    3392             : 
    3393          34 :     SwDocShell* pDocShell = pDoc->GetDocShell ();
    3394             :     OSL_ENSURE(pDocShell, "no SwDocShell");
    3395             : 
    3396          34 :     if (pDocShell) {
    3397             :         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    3398          34 :             pDocShell->GetModel(), uno::UNO_QUERY_THROW);
    3399             :         uno::Reference<document::XDocumentProperties> xDocProps(
    3400          68 :             xDPS->getDocumentProperties());
    3401             :         OSL_ENSURE(xDocProps.is(), "DocumentProperties is null");
    3402             : 
    3403          34 :         if (xDocProps.is())
    3404             :         {
    3405          34 :             if ( SvtFilterOptions::Get().IsEnableWordPreview() )
    3406             :             {
    3407             :                 ::boost::shared_ptr<GDIMetaFile> pMetaFile =
    3408           0 :                     pDocShell->GetPreviewMetaFile(false);
    3409             :                 uno::Sequence<sal_uInt8> metaFile(
    3410           0 :                     sfx2::convertMetaFile(pMetaFile.get()));
    3411           0 :                 sfx2::SaveOlePropertySet(xDocProps, &GetWriter().GetStorage(), &metaFile);
    3412             :             }
    3413             :             else
    3414          34 :                 sfx2::SaveOlePropertySet( xDocProps, &GetWriter().GetStorage() );
    3415          34 :         }
    3416          34 :     }
    3417          34 : }
    3418             : 
    3419          34 : sal_uLong SwWW8Writer::WriteStorage()
    3420             : {
    3421             :     // #i34818# - update layout (if present), for SwWriteTable
    3422          34 :     SwViewShell* pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
    3423          34 :     if( pViewShell != NULL )
    3424          34 :         pViewShell->CalcLayout();
    3425             : 
    3426          34 :     long nMaxNode = pDoc->GetNodes().Count();
    3427          34 :     ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() );
    3428             : 
    3429             :     // Respect table at the beginning of the document
    3430             :     {
    3431          34 :         SwTableNode* pTNd = pCurPam->GetNode().FindTableNode();
    3432          34 :         if( pTNd && bWriteAll )
    3433             :             // start with the table node !!
    3434           2 :             pCurPam->GetPoint()->nNode = *pTNd;
    3435             :     }
    3436             : 
    3437             :     // Do the actual export
    3438             :     {
    3439          34 :         bool bDot = mpMedium->GetFilter()->GetName().endsWith("Vorlage");
    3440          34 :         WW8Export aExport( this, pDoc, pCurPam, pOrigPam, m_bWrtWW8, bDot );
    3441          34 :         m_pExport = &aExport;
    3442          34 :         aExport.ExportDocument( bWriteAll );
    3443          34 :         m_pExport = NULL;
    3444             :     }
    3445             : 
    3446          34 :     ::EndProgress( pDoc->GetDocShell() );
    3447          34 :     return 0;
    3448             : }
    3449             : 
    3450           0 : sal_uLong SwWW8Writer::WriteMedium( SfxMedium& )
    3451             : {
    3452           0 :     return WriteStorage();
    3453             : }
    3454             : 
    3455          34 : sal_uLong SwWW8Writer::Write( SwPaM& rPaM, SfxMedium& rMed,
    3456             :                           const OUString* pFileName )
    3457             : {
    3458          34 :     mpMedium = &rMed;
    3459          34 :     sal_uLong nRet = StgWriter::Write( rPaM, rMed, pFileName );
    3460          34 :     mpMedium = NULL;
    3461          34 :     return nRet;
    3462             : }
    3463             : 
    3464        1032 : MSWordExportBase::MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam )
    3465             :     : aMainStg(sMainStream)
    3466             :     , pISet(0)
    3467             :     , pPiece(NULL)
    3468             :     , pUsedNumTbl(0)
    3469             :     , mpTopNodeOfHdFtPage(0)
    3470             :     , pBkmks(0)
    3471             :     , pRedlAuthors(0)
    3472             :     , pBmpPal(0)
    3473             :     , pOLEExp(0)
    3474             :     , pOCXExp(0)
    3475           0 :     , mpTableInfo(new ww8::WW8TableInfo())
    3476             :     , nCharFmtStart(0)
    3477             :     , nFmtCollStart(0)
    3478             :     , nStyleBeforeFly(0)
    3479             :     , nLastFmtId(0)
    3480             :     , nUniqueList(0)
    3481             :     , mnHdFtIndex(0)
    3482             :     , mnRedlineMode(0)
    3483             :     , pAktPageDesc(0)
    3484             :     , bPrevTextNodeIsEmpty(false)
    3485             :     , pPapPlc(0)
    3486             :     , pChpPlc(0)
    3487             :     , pChpIter(0)
    3488             :     , pStyles(NULL)
    3489             :     , pAtn(0)
    3490             :     , pTxtBxs(0)
    3491             :     , pHFTxtBxs(0)
    3492             :     , mpParentFrame(0)
    3493             :     , pFlyOffset(0)
    3494             :     , eNewAnchorType(FLY_AS_CHAR)
    3495             :     , pFldMain(0)
    3496             :     , pFldHdFt(0)
    3497             :     , pFldFtn(0)
    3498             :     , pFldEdn(0)
    3499             :     , pFldAtn(0)
    3500             :     , pFldTxtBxs(0)
    3501             :     , pFldHFTxtBxs(0)
    3502             :     , pMagicTable(0)
    3503             :     , pGrf(0)
    3504             :     , pStyAttr(0)
    3505             :     , pOutFmtNode(0)
    3506             :     , pCurrentStyle(0)
    3507             :     , pSdrObjs(0)
    3508             :     , pHFSdrObjs(0)
    3509             :     , pEscher(0)
    3510             :     , nTxtTyp(0)
    3511             :     , bStyDef(false)
    3512             :     , bBreakBefore(false)
    3513             :     , bOutKF(false)
    3514             :     , bOutFlyFrmAttrs(false)
    3515             :     , bOutPageDescs(false)
    3516             :     , bOutFirstPage(false)
    3517             :     , bOutTable(false)
    3518             :     , bOutGrf(false)
    3519             :     , bInWriteEscher(false)
    3520             :     , bStartTOX(false)
    3521             :     , bInWriteTOX(false)
    3522             :     , bFtnAtTxtEnd(false)
    3523             :     , bEndAtTxtEnd(false)
    3524             :     , bHasHdr(false)
    3525             :     , bHasFtr(false)
    3526             :     , bSubstituteBullets(true)
    3527             :     , bTabInTOC(false)
    3528             :     , bHideTabLeaderAndPageNumbers(false)
    3529             :     , mbExportModeRTF(false)
    3530             :     , mbOutOutlineOnly(false)
    3531             :     , mbFontSizeWritten(false)
    3532             :     , pDoc(pDocument)
    3533             :     , pCurPam(pCurrentPam)
    3534        1032 :     , pOrigPam(pOriginalPam)
    3535             : {
    3536        1032 : }
    3537             : 
    3538        2064 : MSWordExportBase::~MSWordExportBase()
    3539             : {
    3540        1032 :     delete pBmpPal;
    3541        1032 :     delete pOLEExp;
    3542        1032 :     delete pOCXExp;
    3543        1032 : }
    3544             : 
    3545          34 : WW8Export::WW8Export( SwWW8Writer *pWriter,
    3546             :         SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam,
    3547             :         bool bIsWW8, bool bDot )
    3548             :     : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam )
    3549             :     , pO(NULL)
    3550             :     , pTableStrm(NULL)
    3551             :     , pDataStrm(NULL)
    3552             :     , pFib(NULL)
    3553             :     , pDop(NULL)
    3554             :     , pFtn(NULL)
    3555             :     , pEdn(NULL)
    3556             :     , pSepx(NULL)
    3557             :     , bWrtWW8(bIsWW8)
    3558             :     , m_bDot(bDot)
    3559             :     , m_pWriter(pWriter)
    3560          34 :     , m_pAttrOutput(new WW8AttributeOutput(*this))
    3561             : {
    3562          34 : }
    3563             : 
    3564          68 : WW8Export::~WW8Export()
    3565             : {
    3566          34 :     delete m_pAttrOutput, m_pAttrOutput = NULL;
    3567          34 : }
    3568             : 
    3569       27712 : AttributeOutputBase& WW8Export::AttrOutput() const
    3570             : {
    3571       27712 :     return *m_pAttrOutput;
    3572             : }
    3573             : 
    3574           0 : MSWordSections& WW8Export::Sections() const
    3575             : {
    3576           0 :     return *pSepx;
    3577             : }
    3578             : 
    3579          34 : SwWW8Writer::SwWW8Writer(const OUString& rFltName, const OUString& rBaseURL)
    3580             :     : StgWriter(),
    3581          34 :       m_bWrtWW8( rFltName == FILTER_WW8 ),
    3582             :       m_pExport( NULL ),
    3583          68 :       mpMedium( 0 )
    3584             : {
    3585          34 :     SetBaseURL( rBaseURL );
    3586          34 : }
    3587             : 
    3588          68 : SwWW8Writer::~SwWW8Writer()
    3589             : {
    3590          68 : }
    3591             : 
    3592           0 : extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL SaveOrDelMSVBAStorage_ww8( SfxObjectShell& rDoc, SotStorage& rStor, sal_Bool bSaveInto, const OUString& rStorageName )
    3593             : {
    3594           0 :     SvxImportMSVBasic aTmp( rDoc, rStor );
    3595           0 :     return aTmp.SaveOrDelMSVBAStorage( bSaveInto, rStorageName );
    3596             : }
    3597             : 
    3598          34 : extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportDOC( const OUString& rFltName, const OUString& rBaseURL, WriterRef& xRet )
    3599             : {
    3600          34 :     xRet = new SwWW8Writer( rFltName, rBaseURL );
    3601          34 : }
    3602             : 
    3603           0 : extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL GetSaveWarningOfMSVBAStorage_ww8(  SfxObjectShell &rDocS )
    3604             : {
    3605           0 :     return SvxImportMSVBasic::GetSaveWarningOfMSVBAStorage( rDocS );
    3606             : }
    3607             : 
    3608          68 : bool WW8_WrPlcFtnEdn::WriteTxt( WW8Export& rWrt )
    3609             : {
    3610          68 :     bool bRet = false;
    3611          68 :     if (TXT_FTN == nTyp)
    3612             :     {
    3613          34 :         bRet = WriteGenericTxt( rWrt, TXT_FTN, rWrt.pFib->ccpFtn );
    3614          34 :         rWrt.pFldFtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
    3615          68 :                             rWrt.pFib->ccpText );
    3616             :     }
    3617             :     else
    3618             :     {
    3619          34 :         bRet = WriteGenericTxt( rWrt, TXT_EDN, rWrt.pFib->ccpEdn );
    3620          34 :         rWrt.pFldEdn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
    3621          34 :                             rWrt.pFib->ccpText + rWrt.pFib->ccpFtn
    3622          68 :                             + rWrt.pFib->ccpHdr + rWrt.pFib->ccpAtn );
    3623             :     }
    3624          68 :     return bRet;
    3625             : }
    3626             : 
    3627          68 : void WW8_WrPlcFtnEdn::WritePlc( WW8Export& rWrt ) const
    3628             : {
    3629          68 :     if( TXT_FTN == nTyp )
    3630             :     {
    3631             :         WriteGenericPlc( rWrt, TXT_FTN, rWrt.pFib->fcPlcffndTxt,
    3632             :             rWrt.pFib->lcbPlcffndTxt, rWrt.pFib->fcPlcffndRef,
    3633          34 :             rWrt.pFib->lcbPlcffndRef );
    3634             :     }
    3635             :     else
    3636             :     {
    3637             :         WriteGenericPlc( rWrt, TXT_EDN, rWrt.pFib->fcPlcfendTxt,
    3638             :             rWrt.pFib->lcbPlcfendTxt, rWrt.pFib->fcPlcfendRef,
    3639          34 :             rWrt.pFib->lcbPlcfendRef );
    3640             :     }
    3641          68 : }
    3642             : 
    3643          34 : bool WW8_WrPlcAnnotations::WriteTxt( WW8Export& rWrt )
    3644             : {
    3645          34 :     bool bRet = WriteGenericTxt( rWrt, TXT_ATN, rWrt.pFib->ccpAtn );
    3646          34 :     rWrt.pFldAtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ),
    3647          34 :                         rWrt.pFib->ccpText + rWrt.pFib->ccpFtn
    3648          68 :                         + rWrt.pFib->ccpHdr );
    3649          34 :     return bRet;
    3650             : }
    3651             : 
    3652          34 : void WW8_WrPlcAnnotations::WritePlc( WW8Export& rWrt ) const
    3653             : {
    3654             :     WriteGenericPlc( rWrt, TXT_ATN, rWrt.pFib->fcPlcfandTxt,
    3655             :         rWrt.pFib->lcbPlcfandTxt, rWrt.pFib->fcPlcfandRef,
    3656          34 :         rWrt.pFib->lcbPlcfandRef );
    3657          34 : }
    3658             : 
    3659          68 : void WW8_WrPlcTxtBoxes::WritePlc( WW8Export& rWrt ) const
    3660             : {
    3661          68 :     if( TXT_TXTBOX == nTyp )
    3662             :     {
    3663             :         WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcftxbxBkd,
    3664             :             rWrt.pFib->lcbPlcftxbxBkd, rWrt.pFib->fcPlcftxbxTxt,
    3665          34 :             rWrt.pFib->lcbPlcftxbxTxt );
    3666             :     }
    3667             :     else
    3668             :     {
    3669             :         WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcfHdrtxbxBkd,
    3670             :             rWrt.pFib->lcbPlcfHdrtxbxBkd, rWrt.pFib->fcPlcfHdrtxbxTxt,
    3671          34 :             rWrt.pFib->lcbPlcfHdrtxbxTxt );
    3672             :     }
    3673          68 : }
    3674             : 
    3675          34 : void WW8Export::RestoreMacroCmds()
    3676             : {
    3677          34 :     pFib->fcCmds = pTableStrm->Tell();
    3678             : 
    3679          34 :     uno::Reference < embed::XStorage > xSrcRoot(pDoc->GetDocShell()->GetStorage());
    3680             :     try
    3681             :     {
    3682             :         uno::Reference < io::XStream > xSrcStream =
    3683          56 :                 xSrcRoot->openStreamElement( OUString(SL::aMSMacroCmds), embed::ElementModes::READ );
    3684          12 :         SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xSrcStream );
    3685             : 
    3686          12 :         if ( pStream && SVSTREAM_OK == pStream->GetError())
    3687             :         {
    3688          12 :             pStream->Seek(STREAM_SEEK_TO_END);
    3689          12 :             pFib->lcbCmds = pStream->Tell();
    3690          12 :             pStream->Seek(0);
    3691             : 
    3692          12 :             sal_uInt8 *pBuffer = new sal_uInt8[pFib->lcbCmds];
    3693          12 :             bool bReadOk = checkRead(*pStream, pBuffer, pFib->lcbCmds);
    3694          12 :             if (bReadOk)
    3695          12 :                 pTableStrm->Write(pBuffer, pFib->lcbCmds);
    3696          12 :             delete[] pBuffer;
    3697             : 
    3698             :         }
    3699             : 
    3700          12 :         delete pStream;
    3701             :     }
    3702          22 :     catch ( const uno::Exception& )
    3703             :     {
    3704             :     }
    3705             : 
    3706             :     // set len to FIB
    3707          34 :     pFib->lcbCmds = pTableStrm->Tell() - pFib->fcCmds;
    3708          34 : }
    3709             : 
    3710         536 : void WW8SHDLong::Write( WW8Export& rExport )
    3711             : {
    3712         536 :     rExport.InsUInt32( m_cvFore );
    3713         536 :     rExport.InsUInt32( m_cvBack );
    3714         536 :     rExport.InsUInt16( m_ipat );
    3715         536 : }
    3716             : 
    3717           0 : void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
    3718             : {
    3719             :     OSL_ENSURE( bWrtWW8, "No 95 export yet" );
    3720           0 :     if ( !bWrtWW8 )
    3721           0 :         return;
    3722             : 
    3723           0 :     const ::sw::mark::IFieldmark* pFieldmark = &rFieldmark;
    3724           0 :     const ::sw::mark::ICheckboxFieldmark* pAsCheckbox = dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >( pFieldmark );
    3725             : 
    3726             :     OSL_ENSURE(rFieldmark.GetFieldname() == ODF_FORMTEXT ||
    3727             :                 rFieldmark.GetFieldname() == ODF_FORMDROPDOWN ||
    3728             :                 rFieldmark.GetFieldname() == ODF_FORMCHECKBOX, "Unknown field type!!!");
    3729           0 :     if ( ! ( rFieldmark.GetFieldname() == ODF_FORMTEXT ||
    3730           0 :                 rFieldmark.GetFieldname() == ODF_FORMDROPDOWN ||
    3731           0 :                 rFieldmark.GetFieldname() == ODF_FORMCHECKBOX ) )
    3732           0 :         return;
    3733             : 
    3734           0 :     int type = 0; // TextFieldmark
    3735           0 :     if ( pAsCheckbox )
    3736           0 :         type = 1;
    3737           0 :     if ( rFieldmark.GetFieldname() == ODF_FORMDROPDOWN )
    3738           0 :         type=2;
    3739             : 
    3740           0 :     ::sw::mark::IFieldmark::parameter_map_t::const_iterator pNameParameter = rFieldmark.GetParameters()->find("name");
    3741           0 :     OUString ffname;
    3742           0 :     if(pNameParameter != rFieldmark.GetParameters()->end())
    3743           0 :         pNameParameter->second >>= ffname;
    3744             : 
    3745           0 :     sal_uLong nDataStt = pDataStrm->Tell();
    3746           0 :     pChpPlc->AppendFkpEntry(Strm().Tell());
    3747             : 
    3748           0 :     WriteChar(0x01);
    3749             :     static sal_uInt8 aArr1[] =
    3750             :     {
    3751             :         0x03, 0x6a, 0,0,0,0,    // sprmCPicLocation
    3752             : 
    3753             :         0x06, 0x08, 0x01,       // sprmCFData
    3754             :         0x55, 0x08, 0x01,       // sprmCFSpec
    3755             :         0x02, 0x08, 0x01        // sprmCFFldVanish
    3756             :     };
    3757           0 :     sal_uInt8* pDataAdr = aArr1 + 2;
    3758           0 :     Set_UInt32(pDataAdr, nDataStt);
    3759             : 
    3760           0 :     pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aArr1 ), aArr1 );
    3761             : 
    3762             :     struct FFDataHeader
    3763             :     {
    3764             :         sal_uInt32 version;
    3765             :         sal_uInt16 bits;
    3766             :         sal_uInt16 cch;
    3767             :         sal_uInt16 hps;
    3768           0 :         FFDataHeader() : version( 0xFFFFFFFF ), bits(0), cch(0), hps(0) {}
    3769             :     };
    3770             : 
    3771           0 :     FFDataHeader aFldHeader;
    3772           0 :     aFldHeader.bits |= (type & 0x03);
    3773             : 
    3774           0 :     sal_Int32 ffres = 0; // rFieldmark.GetFFRes();
    3775           0 :     if ( pAsCheckbox && pAsCheckbox->IsChecked() )
    3776           0 :         ffres = 1;
    3777           0 :     else if ( type == 2 )
    3778             :     {
    3779           0 :         ::sw::mark::IFieldmark::parameter_map_t::const_iterator pResParameter = rFieldmark.GetParameters()->find(ODF_FORMDROPDOWN_RESULT);
    3780           0 :         if(pResParameter != rFieldmark.GetParameters()->end())
    3781           0 :             pResParameter->second >>= ffres;
    3782             :         else
    3783           0 :             ffres = 0;
    3784             :     }
    3785           0 :     aFldHeader.bits |= ( (ffres<<2) & 0x7C );
    3786             : 
    3787           0 :     std::vector< OUString > aListItems;
    3788           0 :     if (type==2)
    3789             :     {
    3790           0 :         aFldHeader.bits |= 0x8000; // ffhaslistbox
    3791           0 :         const ::sw::mark::IFieldmark::parameter_map_t* const pParameters = rFieldmark.GetParameters();
    3792           0 :         ::sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
    3793           0 :         if(pListEntries != pParameters->end())
    3794             :         {
    3795           0 :             uno::Sequence< OUString > vListEntries;
    3796           0 :             pListEntries->second >>= vListEntries;
    3797           0 :             copy(vListEntries.begin(), vListEntries.end(), back_inserter(aListItems));
    3798             :         }
    3799             :     }
    3800             : 
    3801           0 :     const OUString ffdeftext;
    3802           0 :     const OUString ffformat;
    3803           0 :     const OUString ffhelptext;
    3804           0 :     const OUString ffstattext;
    3805           0 :     const OUString ffentrymcr;
    3806           0 :     const OUString ffexitmcr;
    3807             : 
    3808             :     const sal_uInt8 aFldData[] =
    3809             :     {
    3810             :         0x44,0,         // the start of "next" data
    3811             :         0,0,0,0,0,0,0,0,0,0,                // PIC-Structure!  /10
    3812             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |              /16
    3813             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |              /16
    3814             :         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |              /16
    3815             :         0,0,0,0,                            // /               /4
    3816           0 :     };
    3817             :    sal_uInt32 slen = sizeof(sal_uInt32)
    3818             :         + sizeof(aFldData)
    3819             :         + sizeof( aFldHeader.version ) + sizeof( aFldHeader.bits ) + sizeof( aFldHeader.cch ) + sizeof( aFldHeader.hps )
    3820           0 :         + 2*ffname.getLength() + 4
    3821           0 :         + 2*ffformat.getLength() + 4
    3822           0 :         + 2*ffhelptext.getLength() + 4
    3823           0 :         + 2*ffstattext.getLength() + 4
    3824           0 :         + 2*ffentrymcr.getLength() + 4
    3825           0 :         + 2*ffexitmcr.getLength() + 4;
    3826           0 :     if ( type )
    3827           0 :         slen += 2; // wDef
    3828             :     else
    3829           0 :         slen += 2*ffdeftext.getLength() + 4; //xstzTextDef
    3830           0 :     if ( type==2 ) {
    3831           0 :         slen += 2; // sttb ( fExtend )
    3832           0 :         slen += 4; // for num of list items
    3833           0 :         const int items = aListItems.size();
    3834           0 :         for( int i = 0; i < items; i++ ) {
    3835           0 :             OUString item = aListItems[i];
    3836           0 :             slen += 2 * item.getLength() + 2;
    3837           0 :         }
    3838             :     }
    3839             : 
    3840           0 :     pDataStrm->WriteUInt32( slen );
    3841             : 
    3842           0 :     int len = sizeof( aFldData );
    3843             :     OSL_ENSURE( len == 0x44-sizeof(sal_uInt32), "SwWW8Writer::WriteFormData(..) - wrong aFldData length" );
    3844           0 :     pDataStrm->Write( aFldData, len );
    3845             : 
    3846           0 :     pDataStrm->WriteUInt32( aFldHeader.version ).WriteUInt16( aFldHeader.bits ).WriteUInt16( aFldHeader.cch ).WriteUInt16( aFldHeader.hps );
    3847             : 
    3848           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, ffname, true ); // Form field name
    3849             : 
    3850           0 :     if ( !type )
    3851           0 :         SwWW8Writer::WriteString_xstz( *pDataStrm, ffdeftext, true );
    3852           0 :     if ( type )
    3853           0 :         pDataStrm->WriteUInt16( sal_uInt16(0) );
    3854             : 
    3855           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffformat ), true );
    3856           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffhelptext ), true );
    3857           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffstattext ), true );
    3858           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffentrymcr ), true );
    3859           0 :     SwWW8Writer::WriteString_xstz( *pDataStrm, OUString( ffexitmcr ), true );
    3860           0 :     if (type==2) {
    3861           0 :         pDataStrm->WriteUInt16( 0xFFFF );
    3862           0 :         const int items=aListItems.size();
    3863           0 :         pDataStrm->WriteUInt32( items );
    3864           0 :         for(int i=0;i<items;i++) {
    3865           0 :             OUString item=aListItems[i];
    3866           0 :             SwWW8Writer::WriteString_xstz( *pDataStrm, item, false );
    3867           0 :         }
    3868           0 :     }
    3869             : }
    3870             : 
    3871           0 : void WW8Export::WriteHyperlinkData( const sw::mark::IFieldmark& /*rFieldmark*/ )
    3872             : {
    3873             :     //@TODO implement me !!!
    3874           0 : }
    3875             : 
    3876         536 : void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
    3877             : {
    3878             :     SVBT16 nStyle;
    3879         536 :     ShortToSVBT16( m_rWW8Export.nStyleBeforeFly, nStyle );
    3880             : 
    3881             : #ifdef DBG_UTIL
    3882             :     SAL_INFO( "sw.ww8", "<OutWW8_TableNodeInfoInner>" << pNodeInfoInner->toString());
    3883             : #endif
    3884             : 
    3885         536 :     m_rWW8Export.pO->clear();
    3886             : 
    3887         536 :     sal_uInt32 nShadowsBefore = pNodeInfoInner->getShadowsBefore();
    3888         536 :     if (nShadowsBefore > 0)
    3889             :     {
    3890             :         ww8::WW8TableNodeInfoInner::Pointer_t
    3891           0 :             pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL));
    3892             : 
    3893           0 :         pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth());
    3894           0 :         pTmpNodeInfoInner->setEndOfCell(true);
    3895             : 
    3896           0 :         for (sal_uInt32 n = 0; n < nShadowsBefore; ++n)
    3897             :         {
    3898           0 :             m_rWW8Export.WriteCR(pTmpNodeInfoInner);
    3899             : 
    3900           0 :             m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3901           0 :             TableInfoCell(pTmpNodeInfoInner);
    3902             :             m_rWW8Export.pPapPlc->AppendFkpEntry
    3903           0 :                 ( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3904             : 
    3905           0 :             m_rWW8Export.pO->clear();
    3906           0 :         }
    3907             :     }
    3908             : 
    3909         536 :     if (pNodeInfoInner->isEndOfCell())
    3910             :     {
    3911             :         SAL_INFO( "sw.ww8", "<endOfCell/>" );
    3912             : 
    3913           0 :         m_rWW8Export.WriteCR(pNodeInfoInner);
    3914             : 
    3915           0 :         m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3916           0 :         TableInfoCell(pNodeInfoInner);
    3917           0 :         m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3918             : 
    3919           0 :         m_rWW8Export.pO->clear();
    3920             :     }
    3921             : 
    3922         536 :     sal_uInt32 nShadowsAfter = pNodeInfoInner->getShadowsAfter();
    3923         536 :     if (nShadowsAfter > 0)
    3924             :     {
    3925             :         ww8::WW8TableNodeInfoInner::Pointer_t
    3926           0 :             pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL));
    3927             : 
    3928           0 :         pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth());
    3929           0 :         pTmpNodeInfoInner->setEndOfCell(true);
    3930             : 
    3931           0 :         for (sal_uInt32 n = 0; n < nShadowsAfter; ++n)
    3932             :         {
    3933           0 :             m_rWW8Export.WriteCR(pTmpNodeInfoInner);
    3934             : 
    3935           0 :             m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3936           0 :             TableInfoCell(pTmpNodeInfoInner);
    3937           0 :             m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3938             : 
    3939           0 :             m_rWW8Export.pO->clear();
    3940           0 :         }
    3941             :     }
    3942             : 
    3943         536 :     if (pNodeInfoInner->isEndOfLine())
    3944             :     {
    3945             :         SAL_INFO( "sw.ww8", "<endOfLine/>" );
    3946             : 
    3947           0 :         TableRowEnd(pNodeInfoInner->getDepth());
    3948             : 
    3949           0 :         ShortToSVBT16(0, nStyle);
    3950           0 :         m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), (sal_uInt8*)&nStyle, (sal_uInt8*)&nStyle+2 );     // Style #
    3951           0 :         TableInfoRow(pNodeInfoInner);
    3952           0 :         m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
    3953             : 
    3954           0 :         m_rWW8Export.pO->clear();
    3955             :     }
    3956             :     SAL_INFO( "sw.ww8", "</OutWW8_TableNodeInfoInner>" );
    3957         536 : }
    3958             : 
    3959        4634 : void MSWordExportBase::OutputStartNode( const SwStartNode & rNode)
    3960             : {
    3961             : 
    3962             :     ww8::WW8TableNodeInfo::Pointer_t pNodeInfo =
    3963        4634 :         mpTableInfo->getTableNodeInfo( &rNode );
    3964             : 
    3965        4634 :     if (pNodeInfo.get() != NULL)
    3966             :     {
    3967             : #ifdef DBG_UTIL
    3968             :         SAL_INFO( "sw.ww8", pNodeInfo->toString());
    3969             : #endif
    3970        3602 :         const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners();
    3971        3602 :         ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aIt(aInners.rbegin());
    3972        3602 :         ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aEnd(aInners.rend());
    3973       11468 :         while (aIt != aEnd)
    3974             :         {
    3975        4264 :             ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
    3976             : 
    3977        4264 :             AttrOutput().TableNodeInfoInner(pInner);
    3978        4264 :             ++aIt;
    3979        7866 :         }
    3980             :     }
    3981        4634 :     SAL_INFO( "sw.ww8", "</OutWW8_SwStartNode>" );
    3982        4634 : }
    3983             : 
    3984        4864 : void MSWordExportBase::OutputEndNode( const SwEndNode &rNode )
    3985             : {
    3986             : #ifdef DBG_UTIL
    3987             :     SAL_INFO( "sw.ww8", "<OutWW8_SwEndNode>" << dbg_out(&rNode));
    3988             : #endif
    3989             : 
    3990        4864 :     ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = mpTableInfo->getTableNodeInfo( &rNode );
    3991             : 
    3992        4864 :     if (pNodeInfo.get() != NULL)
    3993             :     {
    3994             : #ifdef DBG_UTIL
    3995             :         SAL_INFO( "sw.ww8", pNodeInfo->toString());
    3996             : #endif
    3997             : 
    3998        3582 :         const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners();
    3999        3582 :         ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt(aInners.begin());
    4000        3582 :         ww8::WW8TableNodeInfo::Inners_t::const_iterator aEnd(aInners.end());
    4001       11422 :         while (aIt != aEnd)
    4002             :          {
    4003        4258 :             ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
    4004        4258 :             AttrOutput().TableNodeInfoInner(pInner);
    4005        4258 :             ++aIt;
    4006        7840 :          }
    4007             :     }
    4008        4864 :     SAL_INFO( "sw.ww8", "</OutWW8_SwEndNode>" );
    4009        4864 : }
    4010             : 
    4011           4 : const NfKeywordTable & MSWordExportBase::GetNfKeywordTable()
    4012             : {
    4013           4 :     if (pKeyMap.get() == NULL)
    4014             :     {
    4015           4 :         pKeyMap.reset(new NfKeywordTable);
    4016           4 :         NfKeywordTable & rKeywordTable = *pKeyMap;
    4017           4 :         rKeywordTable[NF_KEY_D] = "d";
    4018           4 :         rKeywordTable[NF_KEY_DD] = "dd";
    4019           4 :         rKeywordTable[NF_KEY_DDD] = "ddd";
    4020           4 :         rKeywordTable[NF_KEY_DDDD] = "dddd";
    4021           4 :         rKeywordTable[NF_KEY_M] = "M";
    4022           4 :         rKeywordTable[NF_KEY_MM] = "MM";
    4023           4 :         rKeywordTable[NF_KEY_MMM] = "MMM";
    4024           4 :         rKeywordTable[NF_KEY_MMMM] = "MMMM";
    4025           4 :         rKeywordTable[NF_KEY_NN] = "ddd";
    4026           4 :         rKeywordTable[NF_KEY_NNN] = "dddd";
    4027           4 :         rKeywordTable[NF_KEY_NNNN] = "dddd";
    4028           4 :         rKeywordTable[NF_KEY_YY] = "yy";
    4029           4 :         rKeywordTable[NF_KEY_YYYY] = "yyyy";
    4030           4 :         rKeywordTable[NF_KEY_H] = "H";
    4031           4 :         rKeywordTable[NF_KEY_HH] = "HH";
    4032           4 :         rKeywordTable[NF_KEY_MI] = "m";
    4033           4 :         rKeywordTable[NF_KEY_MMI] = "mm";
    4034           4 :         rKeywordTable[NF_KEY_S] = "s";
    4035           4 :         rKeywordTable[NF_KEY_SS] = "ss";
    4036           4 :         rKeywordTable[NF_KEY_AMPM] = "AM/PM";
    4037             :     }
    4038             : 
    4039           4 :     return *pKeyMap;
    4040         102 : }
    4041             : 
    4042             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10