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

Generated by: LCOV version 1.10