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

Generated by: LCOV version 1.10