LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/filter/ww8 - wrtw8sty.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 807 1174 68.7 %
Date: 2013-07-09 Functions: 84 98 85.7 %
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 <algorithm>
      22             : #include <functional>
      23             : 
      24             : #include <boost/scoped_array.hpp>
      25             : 
      26             : #include <com/sun/star/i18n/ScriptType.hpp>
      27             : #include <rtl/tencinfo.h>
      28             : #include <hintids.hxx>
      29             : #include <editeng/boxitem.hxx>
      30             : #include <editeng/fontitem.hxx>
      31             : #include <svx/svdobj.hxx>
      32             : #include <svx/svdotext.hxx>
      33             : #include <svx/fmglob.hxx>
      34             : #include <editeng/frmdiritem.hxx>
      35             : #include <editeng/lrspitem.hxx>
      36             : #include <editeng/ulspitem.hxx>
      37             : #include <doc.hxx>
      38             : #include <wrtww8.hxx>
      39             : #include <docary.hxx>
      40             : #include <poolfmt.hxx>
      41             : #include <fmtpdsc.hxx>
      42             : #include <pagedesc.hxx>
      43             : #include <ndtxt.hxx>
      44             : #include <ftninfo.hxx>
      45             : #include <fmthdft.hxx>
      46             : #include <section.hxx>
      47             : #include <fmtcntnt.hxx>
      48             : #include <fmtftn.hxx>
      49             : #include <ndindex.hxx>
      50             : #include <txtftn.hxx>
      51             : #include <charfmt.hxx>
      52             : #include <docufld.hxx>
      53             : #include <dcontact.hxx>
      54             : #include <fmtcnct.hxx>
      55             : #include <ftnidx.hxx>
      56             : #include <fmtclds.hxx>
      57             : #include <lineinfo.hxx>
      58             : #include <fmtline.hxx>
      59             : #include <swtable.hxx>
      60             : #include <msfilter.hxx>
      61             : #include <swmodule.hxx>
      62             : 
      63             : #include <doctok/sprmids.hxx>
      64             : 
      65             : #include "writerhelper.hxx"
      66             : #include "writerwordglue.hxx"
      67             : #include "../inc/wwstyles.hxx"
      68             : #include "ww8par.hxx"
      69             : #include "ww8attributeoutput.hxx"
      70             : #include "docxattributeoutput.hxx"
      71             : #include "rtfattributeoutput.hxx"
      72             : 
      73             : using namespace css;
      74             : using namespace sw::util;
      75             : using namespace nsHdFtFlags;
      76             : 
      77             : /// For the output of sections.
      78          11 : struct WW8_PdAttrDesc
      79             : {
      80             :     ::boost::scoped_array<sal_uInt8> m_pData;
      81             :     sal_uInt16 m_nLen;
      82             :     WW8_FC m_nSepxFcPos;
      83          11 :     WW8_PdAttrDesc() : m_nLen(0), m_nSepxFcPos(0xffffffff) /*default: none*/
      84          11 :         { }
      85             : };
      86             : 
      87             : struct WW8_SED
      88             : {
      89             :     SVBT16 aBits1;      // orientation change + internal, Default: 6
      90             :     SVBT32 fcSepx;      //  FC  file offset to beginning of SEPX for section.
      91             :                         //  0xFFFFFFFF for no Sprms
      92             :     SVBT16 fnMpr;       //  used internally by Windows Word, Default: 0
      93             :     SVBT32 fcMpr;       //  FC, points to offset in FC space for MacWord
      94             :                         // Default: 0xffffffff ( nothing )
      95             :                         //  cbSED is 12 (decimal)), C (hex).
      96             : };
      97             : 
      98             : // class WW8_WrPlc0 is only used for header and footer positioning
      99             : // ie there is no content support structure
     100          11 : class WW8_WrPlc0
     101             : {
     102             : private:
     103             :     std::vector<sal_uLong> aPos;      // PTRARR of CPs / FCs
     104             :     sal_uLong nOfs;
     105             : 
     106             :     //No copying
     107             :     WW8_WrPlc0(const WW8_WrPlc0&);
     108             :     WW8_WrPlc0 &operator=(const WW8_WrPlc0&);
     109             : public:
     110             :     WW8_WrPlc0( sal_uLong nOffset );
     111          13 :     sal_uInt16 Count() const                { return aPos.size(); }
     112             :     void Append( sal_uLong nStartCpOrFc );
     113             :     void Write( SvStream& rStrm );
     114             : };
     115             : 
     116             : //------------------------------------------------------------
     117             : //  Styles
     118             : //------------------------------------------------------------
     119             : 
     120             : #define WW8_RESERVED_SLOTS 15
     121             : 
     122             : // GetId( SwCharFmt ) for use in text -> zero is not allowed,
     123             : // use "Default Char Style" instead
     124           8 : sal_uInt16 MSWordExportBase::GetId( const SwCharFmt& rFmt ) const
     125             : {
     126           8 :     sal_uInt16 nRet = pStyles->GetSlot( rFmt );
     127           8 :     return ( nRet != 0x0fff ) ? nRet : 10;      // Default Char Style
     128             : }
     129             : 
     130             : // GetId( SwTxtFmtColl ) for use in TextNodes -> zero is not allowed,
     131             : // "Standard" instead
     132         620 : sal_uInt16 MSWordExportBase::GetId( const SwTxtFmtColl& rColl ) const
     133             : {
     134         620 :     sal_uInt16 nRet = pStyles->GetSlot( rColl );
     135         620 :     return ( nRet != 0xfff ) ? nRet : 0;        // Default TxtFmtColl
     136             : }
     137             : 
     138             : 
     139             : 
     140             : //typedef pFmtT
     141          97 : MSWordStyles::MSWordStyles( MSWordExportBase& rExport )
     142          97 :     : m_rExport( rExport )
     143             : {
     144             :     // if exist any Foot-/End-Notes then get from the EndNoteInfo struct
     145             :     // the CharFormats. They will create it!
     146          97 :     if ( !m_rExport.pDoc->GetFtnIdxs().empty() )
     147             :     {
     148           3 :         m_rExport.pDoc->GetEndNoteInfo().GetAnchorCharFmt( *m_rExport.pDoc );
     149           3 :         m_rExport.pDoc->GetEndNoteInfo().GetCharFmt( *m_rExport.pDoc );
     150           3 :         m_rExport.pDoc->GetFtnInfo().GetAnchorCharFmt( *m_rExport.pDoc );
     151           3 :         m_rExport.pDoc->GetFtnInfo().GetCharFmt( *m_rExport.pDoc );
     152             :     }
     153          97 :     sal_uInt16 nAlloc = WW8_RESERVED_SLOTS + m_rExport.pDoc->GetCharFmts()->size() - 1 +
     154          97 :                                          m_rExport.pDoc->GetTxtFmtColls()->size() - 1;
     155             : 
     156             :     // somewhat generous ( free for up to 15 )
     157          97 :     pFmtA = new SwFmt*[ nAlloc ];
     158          97 :     memset( pFmtA, 0, nAlloc * sizeof( SwFmt* ) );
     159             : 
     160          97 :     BuildStylesTable();
     161          97 : }
     162             : 
     163          56 : MSWordStyles::~MSWordStyles()
     164             : {
     165          56 :     delete[] pFmtA;
     166          56 : }
     167             : 
     168             : // Sty_SetWWSlot() dependencies for the styles -> zero is allowed
     169        2254 : sal_uInt16 MSWordStyles::GetSlot( const SwFmt& rFmt ) const
     170             : {
     171             :     sal_uInt16 n;
     172       32823 :     for ( n = 0; n < nUsedSlots; n++ )
     173       32608 :         if ( pFmtA[n] == &rFmt )
     174        2039 :             return n;
     175         215 :     return 0xfff;                   // 0xfff: WW: zero
     176             : }
     177             : 
     178         813 : sal_uInt16 MSWordStyles::BuildGetSlot( const SwFmt& rFmt )
     179             : {
     180             :     sal_uInt16 nRet;
     181         813 :     switch ( nRet = rFmt.GetPoolFmtId() )
     182             :     {
     183             :         case RES_POOLCOLL_STANDARD:
     184          97 :             nRet = 0;
     185          97 :             break;
     186             : 
     187             :         case RES_POOLCOLL_HEADLINE1:
     188             :         case RES_POOLCOLL_HEADLINE2:
     189             :         case RES_POOLCOLL_HEADLINE3:
     190             :         case RES_POOLCOLL_HEADLINE4:
     191             :         case RES_POOLCOLL_HEADLINE5:
     192             :         case RES_POOLCOLL_HEADLINE6:
     193             :         case RES_POOLCOLL_HEADLINE7:
     194             :         case RES_POOLCOLL_HEADLINE8:
     195             :         case RES_POOLCOLL_HEADLINE9:
     196           4 :             nRet -= RES_POOLCOLL_HEADLINE1-1;
     197           4 :             break;
     198             : 
     199             :         default:
     200         712 :             nRet = nUsedSlots++;
     201         712 :             break;
     202             :     }
     203         813 :     return nRet;
     204             : }
     205             : 
     206         813 : sal_uInt16 MSWordStyles::GetWWId( const SwFmt& rFmt ) const
     207             : {
     208         813 :     sal_uInt16 nRet = ww::stiUser;    // User-Style als default
     209         813 :     sal_uInt16 nPoolId = rFmt.GetPoolFmtId();
     210         813 :     if( nPoolId == RES_POOLCOLL_STANDARD )
     211          97 :         nRet = 0;
     212         716 :     else if( nPoolId >= RES_POOLCOLL_HEADLINE1 &&
     213             :              nPoolId <= RES_POOLCOLL_HEADLINE9 )
     214           4 :         nRet = static_cast< sal_uInt16 >(nPoolId + 1 - RES_POOLCOLL_HEADLINE1);
     215         712 :     else if( nPoolId >= RES_POOLCOLL_TOX_IDX1 &&
     216             :              nPoolId <= RES_POOLCOLL_TOX_IDX3 )
     217           0 :         nRet = static_cast< sal_uInt16 >(nPoolId + 10 - RES_POOLCOLL_TOX_IDX1);
     218         712 :     else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT1 &&
     219             :              nPoolId <= RES_POOLCOLL_TOX_CNTNT5 )
     220           3 :         nRet = static_cast< sal_uInt16 >(nPoolId + 19 - RES_POOLCOLL_TOX_CNTNT1);
     221         709 :     else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT6 &&
     222             :              nPoolId <= RES_POOLCOLL_TOX_CNTNT9 )
     223           0 :         nRet = static_cast< sal_uInt16 >(nPoolId + 24 - RES_POOLCOLL_TOX_CNTNT6);
     224             :     else
     225         709 :         switch( nPoolId )
     226             :         {
     227           3 :         case RES_POOLCOLL_FOOTNOTE:         nRet = 29;  break;
     228           0 :         case RES_POOLCOLL_MARGINAL:         nRet = 30;  break;
     229          12 :         case RES_POOLCOLL_HEADER:           nRet = 31;  break;
     230          12 :         case RES_POOLCOLL_FOOTER:           nRet = 32;  break;
     231           0 :         case RES_POOLCOLL_TOX_IDXH:         nRet = 33;  break;
     232          97 :         case RES_POOLCOLL_LABEL:            nRet = 34;  break;
     233           0 :         case RES_POOLCOLL_LABEL_DRAWING:    nRet = 35;  break;
     234           0 :         case RES_POOLCOLL_JAKETADRESS:      nRet = 36;  break;
     235           0 :         case RES_POOLCOLL_SENDADRESS:       nRet = 37;  break;
     236           1 :         case RES_POOLCOLL_ENDNOTE:          nRet = 43;  break;
     237           0 :         case RES_POOLCOLL_TOX_AUTHORITIESH: nRet = 44;  break;
     238           1 :         case RES_POOLCOLL_TOX_CNTNTH:       nRet = 46;  break;
     239           0 :         case RES_POOLCOLL_BUL_LEVEL1:       nRet = 48;  break;
     240          97 :         case RES_POOLCOLL_LISTS_BEGIN:      nRet = 47;  break;
     241           1 :         case RES_POOLCOLL_NUM_LEVEL1:       nRet = 49;  break;
     242           0 :         case RES_POOLCOLL_BUL_LEVEL2:       nRet = 54;  break;
     243           0 :         case RES_POOLCOLL_BUL_LEVEL3:       nRet = 55;  break;
     244           0 :         case RES_POOLCOLL_BUL_LEVEL4:       nRet = 56;  break;
     245           0 :         case RES_POOLCOLL_BUL_LEVEL5:       nRet = 57;  break;
     246           1 :         case RES_POOLCOLL_NUM_LEVEL2:       nRet = 58;  break;
     247           1 :         case RES_POOLCOLL_NUM_LEVEL3:       nRet = 59;  break;
     248           0 :         case RES_POOLCOLL_NUM_LEVEL4:       nRet = 60;  break;
     249           1 :         case RES_POOLCOLL_NUM_LEVEL5:       nRet = 61;  break;
     250           1 :         case RES_POOLCOLL_DOC_TITEL:        nRet = 62;  break;
     251           0 :         case RES_POOLCOLL_SIGNATURE:        nRet = 64;  break;
     252          97 :         case RES_POOLCOLL_TEXT:             nRet = 66;  break;
     253           1 :         case RES_POOLCOLL_TEXT_MOVE:        nRet = 67;  break;
     254           0 :         case RES_POOLCOLL_BUL_NONUM1:       nRet = 68;  break;
     255           0 :         case RES_POOLCOLL_BUL_NONUM2:       nRet = 69;  break;
     256           0 :         case RES_POOLCOLL_BUL_NONUM3:       nRet = 70;  break;
     257           0 :         case RES_POOLCOLL_BUL_NONUM4:       nRet = 71;  break;
     258           0 :         case RES_POOLCOLL_BUL_NONUM5:       nRet = 72;  break;
     259           1 :         case RES_POOLCOLL_DOC_SUBTITEL:     nRet = 74;  break;
     260           0 :         case RES_POOLCOLL_GREETING:         nRet = 75;  break;
     261           1 :         case RES_POOLCOLL_TEXT_IDENT:       nRet = 77;  break;
     262             : 
     263           3 :         case RES_POOLCHR_FOOTNOTE_ANCHOR:   nRet = 38;  break;
     264           3 :         case RES_POOLCHR_ENDNOTE_ANCHOR:    nRet = 42;  break;
     265           6 :         case RES_POOLCHR_INET_NORMAL:       nRet = 85;  break;
     266           0 :         case RES_POOLCHR_INET_VISIT:        nRet = 86;  break;
     267           0 :         case RES_POOLCHR_HTML_STRONG:       nRet = 87;  break;
     268           0 :         case RES_POOLCHR_HTML_EMPHASIS:     nRet = 88;  break;
     269           0 :         case RES_POOLCHR_LINENUM:           nRet = 40;  break;
     270           0 :         case RES_POOLCHR_PAGENO:            nRet = 41;  break;
     271             :         }
     272         813 :     return nRet;
     273             : }
     274             : 
     275          97 : void MSWordStyles::BuildStylesTable()
     276             : {
     277          97 :     nUsedSlots = WW8_RESERVED_SLOTS;    // soviele sind reserviert fuer
     278             :                                         // Standard und HeadingX u.a.
     279          97 :     const SwCharFmts& rArr = *m_rExport.pDoc->GetCharFmts();       // first CharFmt
     280             :     // das Default-ZeichenStyle ( 0 ) wird nicht mit ausgegeben !
     281         249 :     for( sal_uInt16 n = 1; n < rArr.size(); n++ )
     282             :     {
     283         152 :         SwCharFmt* pFmt = rArr[n];
     284         152 :         pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt;
     285             :     }
     286             : 
     287          97 :     const SwTxtFmtColls& rArr2 = *m_rExport.pDoc->GetTxtFmtColls();   // then TxtFmtColls
     288             :     // das Default-TextStyle ( 0 ) wird nicht mit ausgegeben !
     289         758 :     for( sal_uInt16 n = 1; n < rArr2.size(); n++ )
     290             :     {
     291         661 :         SwTxtFmtColl* pFmt = rArr2[n];
     292         661 :         pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt;
     293             :     }
     294          97 : }
     295             : 
     296             : /// For WW8 only - extend pO so that the size of pTableStrm is even.
     297         434 : static void impl_SkipOdd( ww::bytes* pO, sal_Size nTableStrmTell )
     298             : {
     299         434 :     if ( ( nTableStrmTell + pO->size() ) & 1 )     // Start auf gerader
     300         239 :         pO->push_back( (sal_uInt8)0 );         // Adress
     301         434 : }
     302             : 
     303         174 : void WW8AttributeOutput::EndStyle()
     304             : {
     305         174 :     impl_SkipOdd( m_rWW8Export.pO, m_rWW8Export.pTableStrm->Tell() );
     306             : 
     307         174 :     short nLen = m_rWW8Export.pO->size() - 2;            // length of the style
     308         174 :     sal_uInt8* p = &m_rWW8Export.pO->front() + nPOPosStdLen1;
     309         174 :     ShortToSVBT16( nLen, p );               // nachtragen
     310         174 :     p = &m_rWW8Export.pO->front() + nPOPosStdLen2;
     311         174 :     ShortToSVBT16( nLen, p );               // dito
     312             : 
     313         174 :     m_rWW8Export.pTableStrm->Write( m_rWW8Export.pO->data(), m_rWW8Export.pO->size() );      // write it into the file
     314         174 :     m_rWW8Export.pO->clear();
     315         174 : }
     316             : 
     317         174 : void WW8AttributeOutput::StartStyle( const String& rName, bool bPapFmt, sal_uInt16 nWwBase,
     318             :     sal_uInt16 nWwNext, sal_uInt16 nWwId, sal_uInt16 /*nId*/, bool bAutoUpdate )
     319             : {
     320             :     sal_uInt8 aWW8_STD[ sizeof( WW8_STD ) ];
     321         174 :     sal_uInt8* pData = aWW8_STD;
     322         174 :     memset( &aWW8_STD, 0, sizeof( WW8_STD ) );
     323             : 
     324         174 :     sal_uInt16 nBit16 = 0x1000;         // fInvalHeight
     325         174 :     nBit16 |= (ww::stiNil & nWwId);
     326         174 :     Set_UInt16( pData, nBit16 );
     327             : 
     328         174 :     nBit16 = nWwBase << 4;          // istdBase
     329         174 :     nBit16 |= bPapFmt ? 1 : 2;      // sgc
     330         174 :     Set_UInt16( pData, nBit16 );
     331             : 
     332         174 :     nBit16 = nWwNext << 4;          // istdNext
     333         174 :     nBit16 |= bPapFmt ? 2 : 1;      // cupx
     334         174 :     Set_UInt16( pData, nBit16 );
     335             : 
     336         174 :     pData += sizeof( sal_uInt16 );      // bchUpe
     337             : 
     338         174 :     if( m_rWW8Export.bWrtWW8 )
     339             :     {
     340         174 :         nBit16 = bAutoUpdate ? 1 : 0;  // fAutoRedef : 1
     341         174 :         Set_UInt16( pData, nBit16 );
     342             :         //-------- jetzt neu:
     343             :         // ab Ver8 gibts zwei Felder mehr:
     344             :         //sal_uInt16    fHidden : 1;       /* hidden from UI? */
     345             :         //sal_uInt16    : 14;              /* unused bits */
     346             :     }
     347             : 
     348             : 
     349         174 :     sal_uInt16 nLen = static_cast< sal_uInt16 >( ( pData - aWW8_STD ) + 1 +
     350         174 :                 ((m_rWW8Export.bWrtWW8 ? 2 : 1 ) * (rName.Len() + 1)) );  // temporary
     351             : 
     352         174 :     nPOPosStdLen1 = m_rWW8Export.pO->size();        // Adr1 zum nachtragen der Laenge
     353             : 
     354         174 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nLen );
     355         174 :     m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aWW8_STD, pData );
     356             : 
     357         174 :     nPOPosStdLen2 = nPOPosStdLen1 + 8;  // Adr2 zum nachtragen von "end of upx"
     358             : 
     359             :     // write names
     360         174 :     if( m_rWW8Export.bWrtWW8 )
     361             :     {
     362         174 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, rName.Len() ); // length
     363         174 :         SwWW8Writer::InsAsString16( *m_rWW8Export.pO, rName );
     364             :     }
     365             :     else
     366             :     {
     367           0 :         m_rWW8Export.pO->push_back( (sal_uInt8)rName.Len() );       // length
     368           0 :         SwWW8Writer::InsAsString8( *m_rWW8Export.pO, rName, RTL_TEXTENCODING_MS_1252 );
     369             :     }
     370         174 :     m_rWW8Export.pO->push_back( (sal_uInt8)0 );             // Trotz P-String 0 am Ende!
     371         174 : }
     372             : 
     373         194 : void MSWordStyles::SetStyleDefaults( const SwFmt& rFmt, bool bPap )
     374             : {
     375         194 :     const SwModify* pOldMod = m_rExport.pOutFmtNode;
     376         194 :     m_rExport.pOutFmtNode = &rFmt;
     377             :     bool aFlags[ static_cast< sal_uInt16 >(RES_FRMATR_END) - RES_CHRATR_BEGIN ];
     378             :     sal_uInt16 nStt, nEnd, n;
     379         194 :     if( bPap )
     380          97 :        nStt = RES_PARATR_BEGIN, nEnd = RES_FRMATR_END;
     381             :     else
     382          97 :        nStt = RES_CHRATR_BEGIN, nEnd = RES_TXTATR_END;
     383             : 
     384             :     // dynamic defaults
     385         194 :     const SfxItemPool& rPool = *rFmt.GetAttrSet().GetPool();
     386       12125 :     for( n = nStt; n < nEnd; ++n )
     387       11931 :         aFlags[ n - RES_CHRATR_BEGIN ] = 0 != rPool.GetPoolDefaultItem( n );
     388             : 
     389             :     // static defaults, that differs between WinWord and SO
     390         194 :     if( bPap )
     391             :     {
     392          97 :         aFlags[ static_cast< sal_uInt16 >(RES_PARATR_WIDOWS) - RES_CHRATR_BEGIN ] = 1;
     393          97 :         aFlags[ static_cast< sal_uInt16 >(RES_PARATR_HYPHENZONE) - RES_CHRATR_BEGIN ] = 1;
     394             :     }
     395             :     else
     396             :     {
     397          97 :         aFlags[ RES_CHRATR_FONTSIZE - RES_CHRATR_BEGIN ] = 1;
     398          97 :         aFlags[ RES_CHRATR_LANGUAGE - RES_CHRATR_BEGIN ] = 1;
     399             :     }
     400             : 
     401         194 :     const SfxItemSet* pOldI = m_rExport.GetCurItemSet();
     402         194 :     m_rExport.SetCurItemSet( &rFmt.GetAttrSet() );
     403             : 
     404         194 :     const bool* pFlags = aFlags + ( nStt - RES_CHRATR_BEGIN );
     405       12125 :     for ( n = nStt; n < nEnd; ++n, ++pFlags )
     406             :     {
     407       13603 :         if ( *pFlags && !m_rExport.ignoreAttributeForStyles( n )
     408       13563 :             && SFX_ITEM_SET != rFmt.GetItemState(n, false))
     409             :         {
     410             :             //If we are a character property then see if it is one of the
     411             :             //western/asian ones that must be collapsed together for export to
     412             :             //word. If so default to the western varient.
     413        2030 :             if ( bPap || m_rExport.CollapseScriptsforWordOk(
     414         776 :                 i18n::ScriptType::LATIN, n) )
     415             :             {
     416        1187 :                 m_rExport.AttrOutput().OutputItem( rFmt.GetFmtAttr( n, true ) );
     417             :             }
     418             :         }
     419             :     }
     420             : 
     421         194 :     m_rExport.SetCurItemSet( pOldI );
     422         194 :     m_rExport.pOutFmtNode = pOldMod;
     423         194 : }
     424             : 
     425         260 : void WW8AttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 nStyle )
     426             : {
     427         260 :     impl_SkipOdd( m_rWW8Export.pO, m_rWW8Export.pTableStrm->Tell() );
     428             : 
     429         260 :     sal_uInt16 nLen = ( bParProp ) ? 2 : 0;             // default length
     430         260 :     m_nStyleLenPos = m_rWW8Export.pO->size();               // Laenge zum Nachtragen
     431             :                                     // Keinen Pointer merken, da sich bei
     432             :                                     // _grow der Pointer aendert !
     433             : 
     434         260 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nLen );        // Style-Len
     435             : 
     436         260 :     m_nStyleStartSize = m_rWW8Export.pO->size();
     437             : 
     438         260 :     if ( bParProp )
     439          86 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nStyle );     // Style-Nummer
     440         260 : }
     441             : 
     442        1474 : void MSWordStyles::WriteProperties( const SwFmt* pFmt, bool bParProp, sal_uInt16 nPos,
     443             :     bool bInsDefCharSiz )
     444             : {
     445        1474 :     m_rExport.AttrOutput().StartStyleProperties( bParProp, nPos );
     446             : 
     447             :     OSL_ENSURE( m_rExport.pCurrentStyle == NULL, "Current style not NULL" ); // set current style before calling out
     448        1474 :     m_rExport.pCurrentStyle = pFmt;
     449             : 
     450        1474 :     m_rExport.OutputFormat( *pFmt, bParProp, !bParProp );
     451             : 
     452             :     OSL_ENSURE( m_rExport.pCurrentStyle == pFmt, "current style was changed" );
     453             :     // reset current style...
     454        1474 :     m_rExport.pCurrentStyle = NULL;
     455             : 
     456        1474 :     if ( bInsDefCharSiz  )                   // not derived from other Style
     457         194 :         SetStyleDefaults( *pFmt, bParProp );
     458             : 
     459        1474 :     m_rExport.AttrOutput().EndStyleProperties( bParProp );
     460        1474 : }
     461             : 
     462         260 : void WW8AttributeOutput::EndStyleProperties( bool /*bParProp*/ )
     463             : {
     464         260 :     sal_uInt16 nLen = m_rWW8Export.pO->size() - m_nStyleStartSize;
     465         260 :     sal_uInt8* pUpxLen = &m_rWW8Export.pO->front() + m_nStyleLenPos; // Laenge zum Nachtragen
     466         260 :     ShortToSVBT16( nLen, pUpxLen );                 // add default length
     467         260 : }
     468             : 
     469         813 : void MSWordStyles::GetStyleData( SwFmt* pFmt, bool& bFmtColl, sal_uInt16& nBase, sal_uInt16& nNext )
     470             : {
     471         813 :     bFmtColl = pFmt->Which() == RES_TXTFMTCOLL || pFmt->Which() == RES_CONDTXTFMTCOLL;
     472             : 
     473             :     // Default: none
     474         813 :     nBase = 0xfff;
     475             : 
     476             :     // Derived from?
     477         813 :     if ( !pFmt->IsDefault() )
     478         813 :         nBase = GetSlot( *pFmt->DerivedFrom() );
     479             : 
     480             :     SwFmt* pNext;
     481         813 :     if ( bFmtColl )
     482         661 :         pNext = &((SwTxtFmtColl*)pFmt)->GetNextTxtFmtColl();
     483             :     else
     484         152 :         pNext = pFmt; // CharFmt: next CharFmt == self
     485             : 
     486         813 :     nNext = GetSlot( *pNext );
     487         813 : }
     488             : 
     489         109 : void WW8AttributeOutput::DefaultStyle( sal_uInt16 nStyle )
     490             : {
     491         109 :     if ( nStyle == 10 )           // Default Char-Style ( only WW )
     492             :     {
     493           8 :         if ( m_rWW8Export.bWrtWW8 )
     494             :         {
     495           8 :             sal_uInt16 n = 0;
     496           8 :             m_rWW8Export.pTableStrm->Write( &n , 2 );   // empty Style
     497             :         }
     498             :         else
     499             :         {
     500             :             static sal_uInt8 aDefCharSty[] = {
     501             :                 0x26, 0x00,
     502             :                 0x41, 0x40, 0xF2, 0xFF, 0xA1, 0x00, 0x26, 0x00,
     503             :                 0x19, 0x41, 0x62, 0x73, 0x61, 0x74, 0x7A, 0x2D,
     504             :                 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64,
     505             :                 0x73, 0x63, 0x68, 0x72, 0x69, 0x66, 0x74, 0x61,
     506             :                 0x72, 0x74, 0x00, 0x00, 0x00, 0x00 };
     507           0 :             m_rWW8Export.pTableStrm->Write( &aDefCharSty, sizeof( aDefCharSty ) );
     508             :         }
     509             :     }
     510             :     else
     511             :     {
     512         101 :         sal_uInt16 n = 0;
     513         101 :         m_rWW8Export.pTableStrm->Write( &n , 2 );   // empty Style
     514             :     }
     515         109 : }
     516             : 
     517             : // OutputStyle applies for TxtFmtColls and CharFmts
     518        2167 : void MSWordStyles::OutputStyle( SwFmt* pFmt, sal_uInt16 nPos )
     519             : {
     520        2167 :     if ( !pFmt )
     521        1354 :         m_rExport.AttrOutput().DefaultStyle( nPos );
     522             :     else
     523             :     {
     524             :         bool bFmtColl;
     525             :         sal_uInt16 nBase, nWwNext;
     526             : 
     527         813 :         GetStyleData( pFmt, bFmtColl, nBase, nWwNext );
     528             : 
     529         813 :         String aName = pFmt->GetName();
     530             :         // We want to map LO's default style to Word's "Normal" style.
     531             :         // Word looks for this specific style name when reading docx files.
     532             :         // (It must be the English word regardless of language settings)
     533         813 :         if ( nPos == 0 ) {
     534             :             assert( pFmt->GetPoolFmtId() == RES_POOLCOLL_STANDARD );
     535          97 :             aName = OUString("Normal");
     536         716 :         } else if (aName.EqualsIgnoreCaseAscii("Normal")) {
     537             :             // If LO has a style named "Normal"(!) rename it to something unique
     538           0 :             aName.InsertAscii("LO-" , 0);
     539           0 :             String aBaseName = aName;
     540             :             // Check if we still have a clash, in which case we add a suffix
     541           0 :             for ( int nSuffix = 0; ; ++nSuffix ) {
     542           0 :                 bool clash=false;
     543           0 :                 for ( int n = 1; n < nUsedSlots; ++n )
     544           0 :                     if ( pFmtA[n] &&
     545           0 :                          pFmtA[n]->GetName().EqualsIgnoreCaseAscii(aName) )
     546             :                     {
     547           0 :                         clash = true;
     548           0 :                         break;
     549             :                     }
     550           0 :                 if (!clash)
     551           0 :                     break;
     552           0 :                 aName = aBaseName;
     553           0 :                 aName += OUString::number(++nSuffix);
     554           0 :             }
     555             :         }
     556             : 
     557         813 :         m_rExport.AttrOutput().StartStyle( aName, bFmtColl,
     558         813 :                 nBase, nWwNext, GetWWId( *pFmt ), nPos,
     559        2439 :                 pFmt->IsAutoUpdateFmt() );
     560             : 
     561         813 :         if ( bFmtColl )
     562         661 :             WriteProperties( pFmt, true, nPos, nBase==0xfff );           // UPX.papx
     563             : 
     564         813 :         WriteProperties( pFmt, false, nPos, bFmtColl && nBase==0xfff );  // UPX.chpx
     565             : 
     566         813 :         m_rExport.AttrOutput().EndStyle();
     567             :     }
     568        2167 : }
     569             : 
     570           8 : void WW8AttributeOutput::StartStyles()
     571             : {
     572           8 :     WW8Fib& rFib = *m_rWW8Export.pFib;
     573             : 
     574           8 :     sal_uLong nCurPos = m_rWW8Export.pTableStrm->Tell();
     575           8 :     if ( nCurPos & 1 )                   // Start auf gerader
     576             :     {
     577           0 :         *m_rWW8Export.pTableStrm << (char)0;        // Adress
     578           0 :         ++nCurPos;
     579             :     }
     580           8 :     rFib.fcStshfOrig = rFib.fcStshf = nCurPos;
     581           8 :     m_nStyAnzPos = nCurPos + 2;     // Anzahl wird nachgetragen
     582             : 
     583           8 :     if ( m_rWW8Export.bWrtWW8 )
     584             :     {
     585             :         static sal_uInt8 aStShi[] = {
     586             :             0x12, 0x00,
     587             :             0x0F, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x5B, 0x00,
     588             :             0x0F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
     589             :             0x00, 0x00 };
     590             : 
     591           8 :         m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) );
     592             :     }
     593             :     else
     594             :     {
     595             :         static sal_uInt8 aStShi[] = {
     596             :             0x0E, 0x00,
     597             :             0x0F, 0x00, 0x08, 0x00, 0x01, 0x00, 0x4B, 0x00,
     598             :             0x0F, 0x00, 0x00, 0x00, 0x00, 0x00 };
     599           0 :         m_rWW8Export.pTableStrm->Write( &aStShi, sizeof( aStShi ) );
     600             :     }
     601           8 : }
     602             : 
     603           8 : void WW8AttributeOutput::EndStyles( sal_uInt16 nNumberOfStyles )
     604             : {
     605           8 :     WW8Fib& rFib = *m_rWW8Export.pFib;
     606             : 
     607           8 :     rFib.lcbStshfOrig = rFib.lcbStshf = m_rWW8Export.pTableStrm->Tell() - rFib.fcStshf;
     608           8 :     SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, m_nStyAnzPos, nNumberOfStyles );
     609           8 : }
     610             : 
     611          97 : void MSWordStyles::OutputStylesTable()
     612             : {
     613          97 :     m_rExport.bStyDef = true;
     614             : 
     615          97 :     m_rExport.AttrOutput().StartStyles();
     616             : 
     617             :     sal_uInt16 n;
     618        2264 :     for ( n = 0; n < nUsedSlots; n++ )
     619        2167 :         OutputStyle( pFmtA[n], n );
     620             : 
     621          97 :     m_rExport.AttrOutput().EndStyles( nUsedSlots );
     622             : 
     623          97 :     m_rExport.bStyDef = false;
     624          97 : }
     625             : 
     626             : //---------------------------------------------------------------------------
     627             : //          Fonts
     628             : //---------------------------------------------------------------------------
     629        2257 : wwFont::wwFont(const String &rFamilyName, FontPitch ePitch, FontFamily eFamily,
     630        2257 :     rtl_TextEncoding eChrSet, bool bWrtWW8) : mbAlt(false), mbWrtWW8(bWrtWW8), mePitch(ePitch), meFamily(eFamily), meChrSet(eChrSet)
     631             : {
     632        2257 :     FontMapExport aResult(rFamilyName);
     633        2257 :     msFamilyNm = aResult.msPrimary;
     634        2257 :     msAltNm = aResult.msSecondary;
     635        2885 :     if (msAltNm.Len() && msAltNm != msFamilyNm &&
     636         628 :         (msFamilyNm.Len() + msAltNm.Len() + 2 <= 65) )
     637             :     {
     638             :         //max size of szFfn in 65 chars
     639         628 :         mbAlt = true;
     640             :     }
     641             : 
     642        2257 :     memset(maWW8_FFN, 0, sizeof(maWW8_FFN));
     643             : 
     644        2257 :     if (bWrtWW8)
     645             :     {
     646        2257 :         maWW8_FFN[0] = (sal_uInt8)( 6 - 1 + 0x22 + ( 2 * ( 1 + msFamilyNm.Len() ) ));
     647        2257 :         if (mbAlt)
     648         628 :             maWW8_FFN[0] = static_cast< sal_uInt8 >(maWW8_FFN[0] + 2 * ( 1 + msAltNm.Len()));
     649             :     }
     650             :     else
     651             :     {
     652           0 :         maWW8_FFN[0] = (sal_uInt8)( 6 - 1 + 1 + msFamilyNm.Len() );
     653           0 :         if (mbAlt)
     654           0 :             maWW8_FFN[0] = static_cast< sal_uInt8 >(maWW8_FFN[0] + 1 + msAltNm.Len());
     655             :     }
     656             : 
     657        2257 :     sal_uInt8 aB = 0;
     658        2257 :     switch(ePitch)
     659             :     {
     660             :         case PITCH_VARIABLE:
     661        1126 :             aB |= 2;    // aF.prg = 2
     662        1126 :             break;
     663             :         case PITCH_FIXED:
     664           0 :             aB |= 1;
     665           0 :             break;
     666             :         default:        // aF.prg = 0 : DEFAULT_PITCH (windows.h)
     667        1131 :             break;
     668             :     }
     669        2257 :     aB |= 1 << 2;   // aF.fTrueType = 1; don't know any better;
     670             : 
     671        2257 :     switch(eFamily)
     672             :     {
     673             :         case FAMILY_ROMAN:
     674         873 :             aB |= 1 << 4;   // aF.ff = 1;
     675         873 :             break;
     676             :         case FAMILY_SWISS:
     677         786 :             aB |= 2 << 4;   // aF.ff = 2;
     678         786 :             break;
     679             :         case FAMILY_MODERN:
     680          20 :             aB |= 3 << 4;   // aF.ff = 3;
     681          20 :             break;
     682             :         case FAMILY_SCRIPT:
     683           0 :             aB |= 4 << 4;   // aF.ff = 4;
     684           0 :             break;
     685             :         case FAMILY_DECORATIVE:
     686           0 :             aB |= 5 << 4;   // aF.ff = 5;
     687           0 :             break;
     688             :         default:            // aF.ff = 0; FF_DONTCARE (windows.h)
     689         578 :             break;
     690             :     }
     691        2257 :     maWW8_FFN[1] = aB;
     692             : 
     693        2257 :     ShortToSVBT16( 400, &maWW8_FFN[2] );        // don't know any better
     694             :                                                 // 400 == FW_NORMAL (windows.h)
     695             :                                                 //
     696             :     //#i61927# For unicode fonts like Arial Unicode, Word 97+ sets the chs
     697             :     //to SHIFTJIS presumably to capture that it's a multi-byte encoding font
     698             :     //but Word95 doesn't do this, and sets it to 0 (ANSI), so we should do the
     699             :     //same
     700             :     maWW8_FFN[4] = bWrtWW8 ?
     701        2257 :         sw::ms::rtl_TextEncodingToWinCharset(eChrSet) :
     702        4514 :         rtl_getBestWindowsCharsetFromTextEncoding(eChrSet);
     703             : 
     704        2257 :     if (mbAlt)
     705         628 :         maWW8_FFN[5] = static_cast< sal_uInt8 >(msFamilyNm.Len() + 1);
     706        2257 : }
     707             : 
     708          82 : bool wwFont::Write(SvStream *pTableStrm) const
     709             : {
     710          82 :     pTableStrm->Write(maWW8_FFN, sizeof(maWW8_FFN));    // fixed part
     711          82 :     if (mbWrtWW8)
     712             :     {
     713             :         // ab Ver8 sind folgende beiden Felder eingeschoben,
     714             :         // werden von uns ignoriert.
     715             :         //char  panose[ 10 ];       //  0x6   PANOSE
     716             :         //char  fs[ 24     ];       //  0x10  FONTSIGNATURE
     717          82 :         SwWW8Writer::FillCount(*pTableStrm, 0x22);
     718          82 :         SwWW8Writer::WriteString16(*pTableStrm, msFamilyNm, true);
     719          82 :         if (mbAlt)
     720          18 :             SwWW8Writer::WriteString16(*pTableStrm, msAltNm, true);
     721             :     }
     722             :     else
     723             :     {
     724             :         SwWW8Writer::WriteString8(*pTableStrm, msFamilyNm, true,
     725           0 :             RTL_TEXTENCODING_MS_1252);
     726           0 :         if (mbAlt)
     727             :         {
     728             :             SwWW8Writer::WriteString8( *pTableStrm, msAltNm, true,
     729           0 :                 RTL_TEXTENCODING_MS_1252);
     730             :         }
     731             :     }
     732          82 :     return true;
     733             : }
     734             : 
     735         341 : void wwFont::WriteDocx( DocxAttributeOutput* rAttrOutput ) const
     736             : {
     737             :     // no font embedding, panose id, subsetting, ... implemented
     738             : 
     739         341 :     rAttrOutput->StartFont( msFamilyNm );
     740             : 
     741         341 :     if ( mbAlt )
     742         143 :         rAttrOutput->FontAlternateName( msAltNm );
     743         341 :     rAttrOutput->FontCharset( sw::ms::rtl_TextEncodingToWinCharset( meChrSet ), meChrSet );
     744         341 :     rAttrOutput->FontFamilyType( meFamily );
     745         341 :     rAttrOutput->FontPitchType( mePitch );
     746         341 :     rAttrOutput->EmbedFont( msFamilyNm, meFamily, mePitch, meChrSet );
     747             : 
     748         341 :     rAttrOutput->EndFont();
     749         341 : }
     750             : 
     751         367 : void wwFont::WriteRtf( const RtfAttributeOutput* rAttrOutput ) const
     752             : {
     753         367 :     rAttrOutput->FontFamilyType( meFamily, *this );
     754         367 :     rAttrOutput->FontPitchType( mePitch );
     755         367 :     rAttrOutput->FontCharset( rtl_getBestWindowsCharsetFromTextEncoding( meChrSet ) );
     756         367 :     rAttrOutput->StartFont( msFamilyNm );
     757         367 :     if ( mbAlt )
     758         112 :         rAttrOutput->FontAlternateName( msAltNm );
     759         367 :     rAttrOutput->EndFont();
     760         367 : }
     761             : 
     762       13282 : bool operator<(const wwFont &r1, const wwFont &r2)
     763             : {
     764       13282 :     int nRet = memcmp(r1.maWW8_FFN, r2.maWW8_FFN, sizeof(r1.maWW8_FFN));
     765       13282 :     if (nRet == 0)
     766             :     {
     767        4104 :         StringCompare eRet = r1.msFamilyNm.CompareTo(r2.msFamilyNm);
     768        4104 :         if (eRet == COMPARE_EQUAL)
     769        3662 :             eRet = r1.msAltNm.CompareTo(r2.msAltNm);
     770        4104 :         nRet = eRet;
     771             :     }
     772       13282 :     return nRet < 0;
     773             : }
     774             : 
     775             : 
     776        2624 : sal_uInt16 wwFontHelper::GetId(const wwFont &rFont)
     777             : {
     778             :     sal_uInt16 nRet;
     779        2624 :     ::std::map<wwFont, sal_uInt16>::const_iterator aIter = maFonts.find(rFont);
     780        2624 :     if (aIter != maFonts.end())
     781        1831 :         nRet = aIter->second;
     782             :     else
     783             :     {
     784         793 :         nRet = static_cast< sal_uInt16 >(maFonts.size());
     785         793 :         maFonts[rFont] = nRet;
     786             :     }
     787        2624 :     return nRet;
     788             : }
     789             : 
     790          97 : void wwFontHelper::InitFontTable(bool bWrtWW8,const SwDoc& rDoc)
     791             : {
     792          97 :     mbWrtWW8 = bWrtWW8;
     793             : 
     794             :     GetId(wwFont(OUString("Times New Roman"), PITCH_VARIABLE,
     795          97 :         FAMILY_ROMAN, RTL_TEXTENCODING_MS_1252,bWrtWW8));
     796             : 
     797             :     GetId(wwFont(OUString("Symbol"), PITCH_VARIABLE, FAMILY_ROMAN,
     798          97 :         RTL_TEXTENCODING_SYMBOL,bWrtWW8));
     799             : 
     800             :     GetId(wwFont(OUString("Arial"), PITCH_VARIABLE, FAMILY_SWISS,
     801          97 :         RTL_TEXTENCODING_MS_1252,bWrtWW8));
     802             : 
     803          97 :     const SvxFontItem* pFont = (const SvxFontItem*)GetDfltAttr(RES_CHRATR_FONT);
     804             : 
     805          97 :     GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
     806         194 :         pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
     807             : 
     808          97 :     const SfxItemPool& rPool = rDoc.GetAttrPool();
     809          97 :     if (0 != (pFont = (const SvxFontItem*)rPool.GetPoolDefaultItem(RES_CHRATR_FONT)))
     810             :     {
     811          97 :         GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
     812         194 :             pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
     813             :     }
     814             : 
     815          97 :     if (!bLoadAllFonts)
     816         153 :         return;
     817             : 
     818          41 :     const sal_uInt16 aTypes[] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT, 0 };
     819         164 :     for (const sal_uInt16* pId = aTypes; *pId; ++pId)
     820             :     {
     821         123 :         sal_uInt32 const nMaxItem = rPool.GetItemCount2( *pId );
     822         378 :         for (sal_uInt32 nGet = 0; nGet < nMaxItem; ++nGet)
     823             :         {
     824         255 :             pFont = (const SvxFontItem*)rPool.GetItem2( *pId, nGet );
     825         255 :             if (0 != pFont)
     826             :             {
     827         199 :                 GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
     828         398 :                             pFont->GetFamily(), pFont->GetCharSet(),bWrtWW8));
     829             :             }
     830             :         }
     831             :     }
     832             : }
     833             : 
     834           0 : sal_uInt16 wwFontHelper::GetId(const Font& rFont)
     835             : {
     836           0 :     wwFont aFont(rFont.GetName(), rFont.GetPitch(), rFont.GetFamily(),
     837           0 :         rFont.GetCharSet(), mbWrtWW8);
     838           0 :     return GetId(aFont);
     839             : }
     840             : 
     841        1569 : sal_uInt16 wwFontHelper::GetId(const SvxFontItem& rFont)
     842             : {
     843        1569 :     wwFont aFont(rFont.GetFamilyName(), rFont.GetPitch(), rFont.GetFamily(),
     844        3138 :         rFont.GetCharSet(), mbWrtWW8);
     845        1569 :     return GetId(aFont);
     846             : }
     847             : 
     848          97 : ::std::vector< const wwFont* > wwFontHelper::AsVector() const
     849             : {
     850          97 :     ::std::vector<const wwFont *> aFontList( maFonts.size() );
     851             : 
     852             :     typedef ::std::map<wwFont, sal_uInt16>::const_iterator myiter;
     853          97 :     myiter aEnd = maFonts.end();
     854         887 :     for ( myiter aIter = maFonts.begin(); aIter != aEnd; ++aIter )
     855         790 :         aFontList[aIter->second] = &aIter->first;
     856             : 
     857          97 :     return aFontList;
     858             : }
     859             : 
     860           8 : void wwFontHelper::WriteFontTable(SvStream *pTableStream, WW8Fib& rFib)
     861             : {
     862           8 :     rFib.fcSttbfffn = pTableStream->Tell();
     863             :     /*
     864             :      * Reserve some space to fill in the len after we know how big it is
     865             :      */
     866           8 :     if (mbWrtWW8)
     867           8 :         SwWW8Writer::WriteLong(*pTableStream, 0);
     868             :     else
     869           0 :         SwWW8Writer::WriteShort(*pTableStream, 0);
     870             : 
     871             :     /*
     872             :      * Convert from fast insertion map to linear vector in the order that we
     873             :      * want to write.
     874             :      */
     875           8 :     ::std::vector<const wwFont *> aFontList( AsVector() );
     876             : 
     877             :     /*
     878             :      * Write them all to pTableStream
     879             :      */
     880             :     ::std::for_each(aFontList.begin(), aFontList.end(),
     881           8 :         ::std::bind2nd(::std::mem_fun(&wwFont::Write),pTableStream));
     882             : 
     883             :     /*
     884             :      * Write the position and len in the FIB
     885             :      */
     886           8 :     rFib.lcbSttbfffn = pTableStream->Tell() - rFib.fcSttbfffn;
     887           8 :     if (mbWrtWW8)
     888           8 :         SwWW8Writer::WriteLong( *pTableStream, rFib.fcSttbfffn, maFonts.size());
     889             :     else
     890             :     {
     891             :         SwWW8Writer::WriteShort( *pTableStream, rFib.fcSttbfffn,
     892           0 :             (sal_Int16)rFib.lcbSttbfffn );
     893           8 :     }
     894           8 : }
     895             : 
     896          48 : void wwFontHelper::WriteFontTable( DocxAttributeOutput& rAttrOutput )
     897             : {
     898          48 :     ::std::vector<const wwFont *> aFontList( AsVector() );
     899             : 
     900             :     ::std::for_each( aFontList.begin(), aFontList.end(),
     901          48 :         ::std::bind2nd( ::std::mem_fun( &wwFont::WriteDocx ), &rAttrOutput ) );
     902          48 : }
     903             : 
     904          41 : void wwFontHelper::WriteFontTable( const RtfAttributeOutput& rAttrOutput )
     905             : {
     906          41 :     ::std::vector<const wwFont *> aFontList( AsVector() );
     907             : 
     908             :     ::std::for_each( aFontList.begin(), aFontList.end(),
     909          41 :         ::std::bind2nd( ::std::mem_fun( &wwFont::WriteRtf ), &rAttrOutput ) );
     910          41 : }
     911             : 
     912             : 
     913          11 : WW8_WrPlc0::WW8_WrPlc0( sal_uLong nOffset )
     914          11 :     : nOfs( nOffset )
     915             : {
     916          11 : }
     917             : 
     918         136 : void WW8_WrPlc0::Append( sal_uLong nStartCpOrFc )
     919             : {
     920         136 :     aPos.push_back( nStartCpOrFc - nOfs );
     921         136 : }
     922             : 
     923          10 : void WW8_WrPlc0::Write( SvStream& rStrm )
     924             : {
     925          10 :     std::vector<sal_uLong>::const_iterator iter;
     926         113 :     for( iter = aPos.begin(); iter != aPos.end(); ++iter )
     927             :     {
     928             :         SVBT32 nP;
     929         103 :         UInt32ToSVBT32( *iter, nP );
     930         103 :         rStrm.Write( nP, 4 );
     931             :     }
     932          10 : }
     933             : 
     934             : //------------------------------------------------------------------------------
     935             : 
     936             : //------------------------------------------------------------------------------
     937             : // class MSWordSections : translate PageDescs into Sections
     938             : //      also deals with header and footer
     939             : //------------------------------------------------------------------------------
     940             : 
     941          97 : MSWordSections::MSWordSections( MSWordExportBase& rExport )
     942          97 :     : mbDocumentIsProtected( false )
     943             : {
     944          97 :     const SwSectionFmt *pFmt = 0;
     945          97 :     rExport.pAktPageDesc = &rExport.pDoc->GetPageDesc( 0 );
     946             : 
     947             :     const SfxPoolItem* pI;
     948          97 :     const SwNode* pNd = rExport.pCurPam->GetCntntNode();
     949          97 :     const SfxItemSet* pSet = pNd ? &((SwCntntNode*)pNd)->GetSwAttrSet() : 0;
     950             : 
     951          97 :     sal_uLong nRstLnNum =  pSet ? ((SwFmtLineNumber&)pSet->Get( RES_LINENUMBER )).GetStartValue() : 0;
     952             : 
     953          97 :     const SwTableNode* pTblNd = rExport.pCurPam->GetNode()->FindTableNode();
     954             :     const SwSectionNode* pSectNd;
     955          97 :     if ( pTblNd )
     956             :     {
     957           3 :         pSet = &pTblNd->GetTable().GetFrmFmt()->GetAttrSet();
     958           3 :         pNd = pTblNd;
     959             :     }
     960          94 :     else if ( 0 != ( pSectNd = pNd->FindSectionNode() ) )
     961             :     {
     962           0 :         if ( TOX_HEADER_SECTION == pSectNd->GetSection().GetType() &&
     963           0 :              pSectNd->StartOfSectionNode()->IsSectionNode() )
     964             :         {
     965           0 :             pSectNd = pSectNd->StartOfSectionNode()->GetSectionNode();
     966             :         }
     967             : 
     968           0 :         if ( TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
     969             :         {
     970           0 :             pNd = pSectNd;
     971           0 :             rExport.pCurPam->GetPoint()->nNode = *pNd;
     972             :         }
     973             : 
     974           0 :         if ( CONTENT_SECTION == pSectNd->GetSection().GetType() )
     975           0 :             pFmt = pSectNd->GetSection().GetFmt();
     976             :     }
     977             : 
     978             :     // Hole evtl. Pagedesc des 1. Nodes
     979         194 :     if ( pSet &&
     980         177 :          SFX_ITEM_ON == pSet->GetItemState( RES_PAGEDESC, true, &pI ) &&
     981          80 :          ( (SwFmtPageDesc*)pI )->GetPageDesc() )
     982             :     {
     983          80 :         AppendSection( *(SwFmtPageDesc*)pI, *pNd, pFmt, nRstLnNum );
     984             :     }
     985             :     else
     986          17 :         AppendSection( rExport.pAktPageDesc, pFmt, nRstLnNum );
     987          97 : }
     988             : 
     989           8 : WW8_WrPlcSepx::WW8_WrPlcSepx( MSWordExportBase& rExport )
     990             :     : MSWordSections( rExport )
     991             :     , m_bHeaderFooterWritten( false )
     992           8 :     , pTxtPos( 0 )
     993             : {
     994             :     // to be in sync with the AppendSection() call in the MSWordSections
     995             :     // constructor
     996           8 :     aCps.push_back( 0 );
     997           8 : }
     998             : 
     999         104 : MSWordSections::~MSWordSections()
    1000             : {
    1001         104 : }
    1002             : 
    1003          24 : WW8_WrPlcSepx::~WW8_WrPlcSepx()
    1004             : {
    1005           8 :     delete pTxtPos;
    1006          16 : }
    1007             : 
    1008          99 : bool MSWordSections::HeaderFooterWritten()
    1009             : {
    1010          99 :     return false; // only relevant for WW8
    1011             : }
    1012             : 
    1013           6 : bool WW8_WrPlcSepx::HeaderFooterWritten()
    1014             : {
    1015           6 :     return m_bHeaderFooterWritten;
    1016             : }
    1017             : 
    1018           0 : sal_uInt16 MSWordSections::CurrentNumberOfColumns( const SwDoc &rDoc ) const
    1019             : {
    1020             :     OSL_ENSURE( !aSects.empty(), "no segement inserted yet" );
    1021           0 :     if ( aSects.empty() )
    1022           0 :         return 1;
    1023             : 
    1024           0 :     return NumberOfColumns( rDoc, aSects.back() );
    1025             : }
    1026             : 
    1027           0 : sal_uInt16 MSWordSections::NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo ) const
    1028             : {
    1029           0 :     const SwPageDesc* pPd = rInfo.pPageDesc;
    1030           0 :     if ( !pPd )
    1031           0 :         pPd = &rDoc.GetPageDesc( 0 );
    1032             : 
    1033           0 :     if ( !pPd )
    1034             :     {
    1035             :         OSL_ENSURE( pPd, "totally impossible" );
    1036           0 :         return 1;
    1037             :     }
    1038             : 
    1039           0 :     const SfxItemSet &rSet = pPd->GetMaster().GetAttrSet();
    1040           0 :     SfxItemSet aSet( *rSet.GetPool(), RES_COL, RES_COL );
    1041           0 :     aSet.SetParent( &rSet );
    1042             : 
    1043             :     //0xffffffff, what the hell is going on with that!, fixme most terribly
    1044           0 :     if ( rInfo.pSectionFmt && (SwSectionFmt*)0xFFFFFFFF != rInfo.pSectionFmt )
    1045           0 :         aSet.Put( rInfo.pSectionFmt->GetFmtAttr( RES_COL ) );
    1046             : 
    1047           0 :     const SwFmtCol& rCol = (const SwFmtCol&)aSet.Get( RES_COL );
    1048           0 :     const SwColumns& rColumns = rCol.GetColumns();
    1049           0 :     return rColumns.size();
    1050             : }
    1051             : 
    1052          49 : const WW8_SepInfo* MSWordSections::CurrentSectionInfo()
    1053             : {
    1054          49 :     if ( !aSects.empty() )
    1055          49 :         return &aSects.back();
    1056             : 
    1057           0 :     return NULL;
    1058             : }
    1059             : 
    1060          17 : void MSWordSections::AppendSection( const SwPageDesc* pPd,
    1061             :     const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1062             : {
    1063          17 :     if (HeaderFooterWritten()) {
    1064          17 :         return; // #i117955# prevent new sections in endnotes
    1065             :     }
    1066          17 :     aSects.push_back( WW8_SepInfo( pPd, pSectionFmt, nLnNumRestartNo ) );
    1067          17 :     NeedsDocumentProtected( aSects.back() );
    1068             : }
    1069             : 
    1070           0 : void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd,
    1071             :     const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1072             : {
    1073           0 :     if (HeaderFooterWritten()) {
    1074           0 :         return; // #i117955# prevent new sections in endnotes
    1075             :     }
    1076           0 :     aCps.push_back( nStartCp );
    1077           0 :     AppendSection( pPd, pSectionFmt, nLnNumRestartNo );
    1078             : }
    1079             : 
    1080          85 : void MSWordSections::AppendSection( const SwFmtPageDesc& rPD,
    1081             :     const SwNode& rNd, const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1082             : {
    1083          85 :     if (HeaderFooterWritten()) {
    1084          85 :         return; // #i117955# prevent new sections in endnotes
    1085             :     }
    1086             :     WW8_SepInfo aI( rPD.GetPageDesc(), pSectionFmt, nLnNumRestartNo,
    1087          85 :             rPD.GetNumOffset(), &rNd );
    1088          85 :     aSects.push_back( aI );
    1089          85 :     NeedsDocumentProtected( aI );
    1090             : }
    1091             : 
    1092           3 : void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwFmtPageDesc& rPD,
    1093             :     const SwNode& rNd, const SwSectionFmt* pSectionFmt, sal_uLong nLnNumRestartNo )
    1094             : {
    1095           3 :     if (HeaderFooterWritten()) {
    1096           3 :         return; // #i117955# prevent new sections in endnotes
    1097             :     }
    1098           3 :     aCps.push_back( nStartCp );
    1099           3 :     AppendSection( rPD, rNd, pSectionFmt, nLnNumRestartNo );
    1100             : }
    1101             : 
    1102             : // MSWordSections::SetNum() sets in each section the Num-pointers for the first call.
    1103             : // All subsequent calls will be ignored.
    1104             : // Thus, the first list of the section will be adopted.
    1105             : 
    1106           0 : void MSWordSections::SetNum( const SwTxtNode* pNumNd )
    1107             : {
    1108           0 :     WW8_SepInfo& rInfo = aSects.back();
    1109           0 :     if ( !rInfo.pNumNd ) // not yet assigned
    1110           0 :         rInfo.pNumNd = pNumNd;
    1111           0 : }
    1112             : 
    1113           8 : void WW8_WrPlcSepx::WriteFtnEndTxt( WW8Export& rWrt, sal_uLong nCpStt )
    1114             : {
    1115           8 :     sal_uInt8 nInfoFlags = 0;
    1116           8 :     const SwFtnInfo& rInfo = rWrt.pDoc->GetFtnInfo();
    1117           8 :     if( rInfo.aErgoSum.Len() )  nInfoFlags |= 0x02;
    1118           8 :     if( rInfo.aQuoVadis.Len() ) nInfoFlags |= 0x04;
    1119             : 
    1120           8 :     sal_uInt8 nEmptyStt = rWrt.bWrtWW8 ? 0 : 6;
    1121           8 :     if( nInfoFlags )
    1122             :     {
    1123           0 :         if( rWrt.bWrtWW8 )
    1124           0 :             pTxtPos->Append( nCpStt );  // empty footnote separator
    1125             : 
    1126           0 :         if( 0x02 & nInfoFlags )         // Footnote continuation separator
    1127             :         {
    1128           0 :             pTxtPos->Append( nCpStt );
    1129           0 :             rWrt.WriteStringAsPara( rInfo.aErgoSum );
    1130           0 :             rWrt.WriteStringAsPara( aEmptyStr );
    1131           0 :             nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1132             :         }
    1133           0 :         else if( rWrt.bWrtWW8 )
    1134           0 :             pTxtPos->Append( nCpStt );
    1135             : 
    1136           0 :         if( 0x04 & nInfoFlags )         // Footnote continuation notice
    1137             :         {
    1138           0 :             pTxtPos->Append( nCpStt );
    1139           0 :             rWrt.WriteStringAsPara( rInfo.aQuoVadis );
    1140           0 :             rWrt.WriteStringAsPara( aEmptyStr );
    1141           0 :             nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1142             :         }
    1143           0 :         else if( rWrt.bWrtWW8 )
    1144           0 :             pTxtPos->Append( nCpStt );
    1145             : 
    1146           0 :         if( rWrt.bWrtWW8 )
    1147           0 :             nEmptyStt = 3;
    1148             :         else
    1149           0 :             rWrt.pDop->grpfIhdt = nInfoFlags;
    1150             :     }
    1151             : 
    1152          64 :     while( 6 > nEmptyStt++ )
    1153          48 :         pTxtPos->Append( nCpStt );
    1154             : 
    1155             :     // gleich die Flags am Dop setzen
    1156           8 :     WW8Dop& rDop = *rWrt.pDop;
    1157             :     // Footnote Info
    1158           8 :     switch( rInfo.eNum )
    1159             :     {
    1160           0 :     case FTNNUM_PAGE:       rDop.rncFtn = 2; break;
    1161           0 :     case FTNNUM_CHAPTER:    rDop.rncFtn  = 1; break;
    1162           8 :     default: rDop.rncFtn  = 0; break;
    1163             :     }                                   // rncFtn
    1164           8 :     rDop.nfcFtnRef = WW8Export::GetNumId( rInfo.aFmt.GetNumberingType() );
    1165           8 :     rDop.nFtn = rInfo.nFtnOffset + 1;
    1166           8 :     rDop.fpc = rWrt.bFtnAtTxtEnd ? 2 : 1;
    1167             : 
    1168             :     // Endnote Info
    1169           8 :     rDop.rncEdn = 0;                        // rncEdn: Don't Restart
    1170           8 :     const SwEndNoteInfo& rEndInfo = rWrt.pDoc->GetEndNoteInfo();
    1171           8 :     rDop.nfcEdnRef = WW8Export::GetNumId( rEndInfo.aFmt.GetNumberingType() );
    1172           8 :     rDop.nEdn = rEndInfo.nFtnOffset + 1;
    1173           8 :     rDop.epc = rWrt.bEndAtTxtEnd ? 3 : 0;
    1174           8 : }
    1175             : 
    1176          67 : void MSWordSections::SetHeaderFlag( sal_uInt8& rHeadFootFlags, const SwFmt& rFmt,
    1177             :     sal_uInt8 nFlag )
    1178             : {
    1179             :     const SfxPoolItem* pItem;
    1180         134 :     if( SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, true, &pItem)
    1181          87 :         && ((SwFmtHeader*)pItem)->IsActive() &&
    1182          20 :         ((SwFmtHeader*)pItem)->GetHeaderFmt() )
    1183          20 :         rHeadFootFlags |= nFlag;
    1184          67 : }
    1185             : 
    1186          68 : void MSWordSections::SetFooterFlag( sal_uInt8& rHeadFootFlags, const SwFmt& rFmt,
    1187             :     sal_uInt8 nFlag )
    1188             : {
    1189             :     const SfxPoolItem* pItem;
    1190         136 :     if( SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, true, &pItem)
    1191          90 :         && ((SwFmtFooter*)pItem)->IsActive() &&
    1192          22 :         ((SwFmtFooter*)pItem)->GetFooterFmt() )
    1193          22 :         rHeadFootFlags |= nFlag;
    1194          68 : }
    1195             : 
    1196          66 : void WW8_WrPlcSepx::OutHeaderFooter( WW8Export& rWrt, bool bHeader,
    1197             :                      const SwFmt& rFmt, sal_uLong& rCpPos, sal_uInt8 nHFFlags,
    1198             :                      sal_uInt8 nFlag,  sal_uInt8 nBreakCode)
    1199             : {
    1200          66 :     if ( nFlag & nHFFlags )
    1201             :     {
    1202          29 :         pTxtPos->Append( rCpPos );
    1203          29 :         rWrt.WriteHeaderFooterText( rFmt, bHeader);
    1204          29 :         rWrt.WriteStringAsPara( aEmptyStr ); // CR ans Ende ( sonst mault WW )
    1205          29 :         rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1206             :     }
    1207          37 :     else if ( rWrt.bWrtWW8 )
    1208             :     {
    1209          37 :         pTxtPos->Append( rCpPos );
    1210          37 :         if ((bHeader? rWrt.bHasHdr : rWrt.bHasFtr) && nBreakCode!=0)
    1211             :         {
    1212          11 :             rWrt.WriteStringAsPara( aEmptyStr ); // Empty paragraph for empty header/footer
    1213          11 :             rWrt.WriteStringAsPara( aEmptyStr ); // a CR that WW8 needs for end of the stream
    1214          11 :             rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1215             :         }
    1216             :     }
    1217          66 : }
    1218             : 
    1219         102 : void MSWordSections::NeedsDocumentProtected(const WW8_SepInfo &rInfo)
    1220             : {
    1221         102 :     if (rInfo.IsProtected())
    1222           0 :         mbDocumentIsProtected = true;
    1223         102 : }
    1224             : 
    1225         162 : bool WW8_SepInfo::IsProtected() const
    1226             : {
    1227         162 :     bool bRet = false;
    1228         162 :     if (
    1229           0 :          pSectionFmt &&
    1230           0 :          ((SwSectionFmt*)0xFFFFFFFF != pSectionFmt)
    1231             :        )
    1232             :     {
    1233           0 :         const SwSection *pSection = pSectionFmt->GetSection();
    1234           0 :         if (pSection && pSection->IsProtect())
    1235             :         {
    1236           0 :             bRet = true;
    1237             :         }
    1238             :     }
    1239         162 :     return bRet;
    1240             : }
    1241             : 
    1242             : 
    1243           8 : void MSWordSections::CheckForFacinPg( WW8Export& rWrt ) const
    1244             : {
    1245             :     // 2 values getting set
    1246             :     //      Dop.fFacingPages            == Header and Footer different
    1247             :     //      Dop.fSwapBordersFacingPgs   == mirrored borders
    1248           8 :     std::vector<WW8_SepInfo>::const_iterator iter = aSects.begin();
    1249          19 :     for( sal_uInt16 nEnde = 0; iter != aSects.end(); ++iter )
    1250             :     {
    1251          11 :         const WW8_SepInfo& rSepInfo = *iter;
    1252          11 :         if( !rSepInfo.pSectionFmt )
    1253             :         {
    1254          11 :             const SwPageDesc* pPd = rSepInfo.pPageDesc;
    1255          33 :             if( pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1256           0 :                 pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
    1257          11 :                 rSepInfo.pPDNd &&
    1258           0 :                 pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) )
    1259             :                 // das ist also 1.Seite und nachfolgende, also nur den
    1260             :                 // follow beachten
    1261           0 :                 pPd = pPd->GetFollow();
    1262             : 
    1263             :             // left-/right chain of pagedescs ?
    1264          31 :             else if( !( 1 & nEnde ) &&
    1265          18 :                 pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1266          11 :                 pPd->GetFollow()->GetFollow() == pPd &&
    1267           0 :                 (( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1268           0 :                    nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ||
    1269           0 :                  ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1270           0 :                    nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ))
    1271             :             {
    1272           0 :                 rWrt.pDop->fFacingPages = rWrt.pDop->fMirrorMargins = true;
    1273           0 :                 nEnde |= 1;
    1274             :             }
    1275             : 
    1276          22 :             if( !( 1 & nEnde ) &&
    1277          16 :                 ( !pPd->IsHeaderShared() || !pPd->IsFooterShared() ))
    1278             :             {
    1279           2 :                 rWrt.pDop->fFacingPages = true;
    1280           2 :                 nEnde |= 1;
    1281             :             }
    1282          22 :             if( !( 2 & nEnde ) &&
    1283          11 :                 nsUseOnPage::PD_MIRROR == ( nsUseOnPage::PD_MIRROR & pPd->ReadUseOn() ))
    1284             :             {
    1285             :                 rWrt.pDop->fSwapBordersFacingPgs =
    1286           1 :                     rWrt.pDop->fMirrorMargins = true;
    1287           1 :                 nEnde |= 2;
    1288             :             }
    1289             : 
    1290          11 :             if( 3 == nEnde )
    1291           0 :                 break;      // We do not need to go any further
    1292             :         }
    1293             :     }
    1294           8 : }
    1295             : 
    1296          22 : int MSWordSections::HasBorderItem( const SwFmt& rFmt )
    1297             : {
    1298             :     const SfxPoolItem* pItem;
    1299          22 :     return SFX_ITEM_SET == rFmt.GetItemState(RES_BOX, true, &pItem) &&
    1300           0 :             (   ((SvxBoxItem*)pItem)->GetTop() ||
    1301           0 :                 ((SvxBoxItem*)pItem)->GetBottom()  ||
    1302           0 :                 ((SvxBoxItem*)pItem)->GetLeft()  ||
    1303          22 :                 ((SvxBoxItem*)pItem)->GetRight() );
    1304             : }
    1305             : 
    1306          11 : void WW8AttributeOutput::StartSection()
    1307             : {
    1308          11 :     m_rWW8Export.pO->clear();
    1309          11 : }
    1310             : 
    1311          11 : void WW8AttributeOutput::SectionFormProtection( bool bProtected )
    1312             : {
    1313             :     //If the document is to be exported as protected, then if a segment
    1314             :     //is not protected, set the unlocked flag
    1315          11 :     if ( m_rWW8Export.pSepx->DocumentIsProtected() && !bProtected )
    1316             :     {
    1317           0 :         if ( m_rWW8Export.bWrtWW8 )
    1318           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFProtected );
    1319             :         else
    1320           0 :             m_rWW8Export.pO->push_back( 139 );
    1321           0 :         m_rWW8Export.pO->push_back( 1 );
    1322             :     }
    1323          11 : }
    1324             : 
    1325           0 : void WW8AttributeOutput::SectionLineNumbering( sal_uLong nRestartNo, const SwLineNumberInfo& rLnNumInfo )
    1326             : {
    1327             :     // sprmSNLnnMod - activate Line Numbering and define Modulo
    1328           0 :     if ( m_rWW8Export.bWrtWW8 )
    1329           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNLnnMod );
    1330             :     else
    1331           0 :         m_rWW8Export.pO->push_back( 154 );
    1332           0 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (sal_uInt16)rLnNumInfo.GetCountBy() );
    1333             : 
    1334             :     // sprmSDxaLnn - xPosition of Line Number
    1335           0 :     if ( m_rWW8Export.bWrtWW8 )
    1336           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SDxaLnn );
    1337             :     else
    1338           0 :         m_rWW8Export.pO->push_back( 155 );
    1339           0 :     SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (sal_uInt16)rLnNumInfo.GetPosFromLeft() );
    1340             : 
    1341             :     // sprmSLnc - restart number: 0 per page, 1 per section, 2 never restart
    1342           0 :     if ( nRestartNo || !rLnNumInfo.IsRestartEachPage() )
    1343             :     {
    1344           0 :         if ( m_rWW8Export.bWrtWW8 )
    1345           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnc );
    1346             :         else
    1347           0 :             m_rWW8Export.pO->push_back( 152 );
    1348           0 :         m_rWW8Export.pO->push_back( nRestartNo ? 1 : 2 );
    1349             :     }
    1350             : 
    1351             :     // sprmSLnnMin - Restart the Line Number with given value
    1352           0 :     if ( nRestartNo )
    1353             :     {
    1354           0 :         if ( m_rWW8Export.bWrtWW8 )
    1355           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SLnnMin );
    1356             :         else
    1357           0 :             m_rWW8Export.pO->push_back( 160 );
    1358           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, (sal_uInt16)nRestartNo - 1 );
    1359             :     }
    1360           0 : }
    1361             : 
    1362           3 : void WW8AttributeOutput::SectionTitlePage()
    1363             : {
    1364             :     // sprmSFTitlePage
    1365           3 :     if ( m_rWW8Export.bWrtWW8 )
    1366           3 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFTitlePage );
    1367             :     else
    1368           0 :         m_rWW8Export.pO->push_back( 143 );
    1369           3 :     m_rWW8Export.pO->push_back( 1 );
    1370           3 : }
    1371             : 
    1372          11 : void WW8AttributeOutput::SectionPageBorders( const SwFrmFmt* pPdFmt, const SwFrmFmt* pPdFirstPgFmt )
    1373             : {
    1374          11 :     if ( m_rWW8Export.bWrtWW8 )              // write border of page
    1375             :     {
    1376          11 :         sal_uInt16 nPgBorder = MSWordSections::HasBorderItem( *pPdFmt ) ? 0 : USHRT_MAX;
    1377          11 :         if ( pPdFmt != pPdFirstPgFmt )
    1378             :         {
    1379          11 :             if ( MSWordSections::HasBorderItem( *pPdFirstPgFmt ) )
    1380             :             {
    1381           0 :                 if ( USHRT_MAX == nPgBorder )
    1382             :                 {
    1383           0 :                     nPgBorder = 1;
    1384             :                     // only the first page outlined -> Get the BoxItem from the correct format
    1385           0 :                     m_rWW8Export.pISet = &pPdFirstPgFmt->GetAttrSet();
    1386           0 :                     OutputItem( pPdFirstPgFmt->GetFmtAttr( RES_BOX ) );
    1387             :                 }
    1388             :             }
    1389          11 :             else if ( !nPgBorder )
    1390           0 :                 nPgBorder = 2;
    1391             :         }
    1392             : 
    1393          11 :         if ( USHRT_MAX != nPgBorder )
    1394             :         {
    1395             :             // write the Flag and Border Attribute
    1396           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgbProp );
    1397           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPgBorder );
    1398             :         }
    1399             :     }
    1400          11 : }
    1401             : 
    1402           0 : void WW8AttributeOutput::SectionBiDi( bool bBiDi )
    1403             : {
    1404           0 :     if ( m_rWW8Export.bWrtWW8 )
    1405             :     {
    1406           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFBiDi );
    1407           0 :         m_rWW8Export.pO->push_back( bBiDi? 1: 0 );
    1408             :     }
    1409           0 : }
    1410             : 
    1411          11 : void WW8AttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, sal_uInt16 nPageRestartNumber )
    1412             : {
    1413             :     // sprmSNfcPgn
    1414          11 :     sal_uInt8 nb = WW8Export::GetNumId( nNumType );
    1415          11 :     if ( m_rWW8Export.bWrtWW8 )
    1416          11 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SNfcPgn );
    1417             :     else
    1418           0 :         m_rWW8Export.pO->push_back( 147 );
    1419          11 :     m_rWW8Export.pO->push_back( nb );
    1420             : 
    1421          11 :     if ( nPageRestartNumber )
    1422             :     {
    1423             :         // sprmSFPgnRestart
    1424           0 :         if ( m_rWW8Export.bWrtWW8 )
    1425           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SFPgnRestart );
    1426             :         else
    1427           0 :             m_rWW8Export.pO->push_back( 150 );
    1428           0 :         m_rWW8Export.pO->push_back( 1 );
    1429             : 
    1430             :         // sprmSPgnStart
    1431           0 :         if ( m_rWW8Export.bWrtWW8 )
    1432           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SPgnStart );
    1433             :         else
    1434           0 :             m_rWW8Export.pO->push_back( 161 );
    1435           0 :         SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPageRestartNumber );
    1436             :     }
    1437          11 : }
    1438             : 
    1439          11 : void WW8AttributeOutput::SectionType( sal_uInt8 nBreakCode )
    1440             : {
    1441          11 :     if ( 2 != nBreakCode ) // new page is the default
    1442             :     {
    1443           0 :         if ( m_rWW8Export.bWrtWW8 )
    1444           0 :             SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_SBkc );
    1445             :         else
    1446           0 :             m_rWW8Export.pO->push_back( 142 );
    1447           0 :         m_rWW8Export.pO->push_back( nBreakCode );
    1448             :     }
    1449          11 : }
    1450             : 
    1451          11 : void WW8AttributeOutput::SectionWW6HeaderFooterFlags( sal_uInt8 nHeadFootFlags )
    1452             : {
    1453          11 :     if ( nHeadFootFlags && !m_rWW8Export.bWrtWW8 )
    1454             :     {
    1455           0 :         sal_uInt8 nTmpFlags = nHeadFootFlags;
    1456           0 :         if ( m_rWW8Export.pDop->fFacingPages )
    1457             :         {
    1458           0 :             if ( !(nTmpFlags & WW8_FOOTER_EVEN) && (nTmpFlags & WW8_FOOTER_ODD ) )
    1459           0 :                 nTmpFlags |= WW8_FOOTER_EVEN;
    1460             : 
    1461           0 :             if ( !(nTmpFlags & WW8_HEADER_EVEN) && (nTmpFlags & WW8_HEADER_ODD ) )
    1462           0 :                 nTmpFlags |= WW8_HEADER_EVEN;
    1463             :         }
    1464             : 
    1465             :         // sprmSGprfIhdt, is only needed in WW95
    1466           0 :         m_rWW8Export.pO->push_back( 153 );
    1467           0 :         m_rWW8Export.pO->push_back( nTmpFlags );
    1468             :     }
    1469          11 : }
    1470             : 
    1471          11 : void WW8Export::SetupSectionPositions( WW8_PdAttrDesc* pA )
    1472             : {
    1473          11 :     if ( !pA )
    1474          11 :         return;
    1475             : 
    1476          11 :     if ( !pO->empty() ) // are there attributes ?
    1477             :     {
    1478          11 :         pA->m_nLen = pO->size();
    1479          11 :         pA->m_pData.reset(new sal_uInt8 [pO->size()]);
    1480             :         // store for later
    1481          11 :         memcpy( pA->m_pData.get(), pO->data(), pO->size() );
    1482          11 :         pO->clear(); // clear HdFt-Text
    1483             :     }
    1484             :     else // no attributes there
    1485             :     {
    1486           0 :         pA->m_pData.reset();
    1487           0 :         pA->m_nLen = 0;
    1488             :     }
    1489             : }
    1490             : 
    1491          11 : void WW8Export::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
    1492             :         const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, sal_uInt8 nBreakCode )
    1493             : {
    1494          11 :     sal_uLong nCpPos = Fc2Cp( Strm().Tell() );
    1495             : 
    1496          11 :     IncrementHdFtIndex();
    1497          11 :     if ( !(nHeadFootFlags & WW8_HEADER_EVEN) && pDop->fFacingPages )
    1498           0 :         pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
    1499             :     else
    1500          11 :         pSepx->OutHeaderFooter( *this, true, rLeftFmt, nCpPos, nHeadFootFlags, WW8_HEADER_EVEN, nBreakCode );
    1501          11 :     IncrementHdFtIndex();
    1502          11 :     pSepx->OutHeaderFooter( *this, true, rFmt, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
    1503             : 
    1504          11 :     IncrementHdFtIndex();
    1505          11 :     if ( !(nHeadFootFlags & WW8_FOOTER_EVEN) && pDop->fFacingPages )
    1506           0 :         pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
    1507             :     else
    1508          11 :         pSepx->OutHeaderFooter( *this, false, rLeftFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_EVEN, nBreakCode );
    1509          11 :     IncrementHdFtIndex();
    1510          11 :     pSepx->OutHeaderFooter( *this, false, rFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
    1511             : 
    1512             :     //#i24344# Drawing objects cannot be directly shared between main hd/ft
    1513             :     //and title hd/ft so we need to differenciate them
    1514          11 :     IncrementHdFtIndex();
    1515          11 :     pSepx->OutHeaderFooter( *this, true, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_HEADER_FIRST, nBreakCode );
    1516          11 :     pSepx->OutHeaderFooter( *this, false, rFirstPageFmt, nCpPos, nHeadFootFlags, WW8_FOOTER_FIRST, nBreakCode );
    1517          11 : }
    1518             : 
    1519          60 : void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAttrDesc* pA )
    1520             : {
    1521          60 :     const SwPageDesc* pPd = rSepInfo.pPageDesc;
    1522             : 
    1523          60 :     if ( rSepInfo.pSectionFmt && !pPd )
    1524           0 :         pPd = &pDoc->GetPageDesc( 0 );
    1525             : 
    1526          60 :     pAktPageDesc = pPd;
    1527             : 
    1528          60 :     if ( !pPd )
    1529          60 :         return;
    1530             : 
    1531          60 :     bool bOldPg = bOutPageDescs;
    1532          60 :     bOutPageDescs = true;
    1533             : 
    1534          60 :     AttrOutput().StartSection();
    1535             : 
    1536          60 :     AttrOutput().SectFootnoteEndnotePr();
    1537             : 
    1538             :     // forms
    1539          60 :     AttrOutput().SectionFormProtection( rSepInfo.IsProtected() );
    1540             : 
    1541             :     // line numbers
    1542          60 :     const SwLineNumberInfo& rLnNumInfo = pDoc->GetLineNumberInfo();
    1543          60 :     if ( rLnNumInfo.IsPaintLineNumbers() )
    1544           1 :         AttrOutput().SectionLineNumbering( rSepInfo.nLnNumRestartNo, rLnNumInfo );
    1545             : 
    1546             :     /*  sprmSBkc, break code:   0 No break, 1 New column
    1547             :         2 New page, 3 Even page, 4 Odd page
    1548             :         */
    1549          60 :     sal_uInt8 nBreakCode = 2;            // default neue Seite beginnen
    1550          60 :     bool bOutPgDscSet = true, bLeftRightPgChain = false;
    1551          60 :     const SwFrmFmt* pPdFmt = &pPd->GetMaster();
    1552          60 :     if ( rSepInfo.pSectionFmt )
    1553             :     {
    1554             :         // if pSectionFmt is set, then there is a SectionNode
    1555             :         //  valid pointer -> start Section ,
    1556             :         //  0xfff -> Section terminated
    1557           0 :         nBreakCode = 0;         // fortlaufender Abschnitt
    1558             : 
    1559           0 :         if ( rSepInfo.pPDNd && rSepInfo.pPDNd->IsCntntNode() )
    1560             :         {
    1561           0 :             if ( !NoPageBreakSection( &rSepInfo.pPDNd->GetCntntNode()->GetSwAttrSet() ) )
    1562             :             {
    1563           0 :                 nBreakCode = 2;
    1564             :             }
    1565             :         }
    1566             : 
    1567           0 :         if ( (SwSectionFmt*)0xFFFFFFFF != rSepInfo.pSectionFmt )
    1568             :         {
    1569           0 :             if ( nBreakCode == 0 )
    1570           0 :                 bOutPgDscSet = false;
    1571             : 
    1572             :             // produce Itemset, which inherits PgDesk-Attr-Set:
    1573             :             // als Nachkomme wird bei 'deep'-OutputItemSet
    1574             :             // auch der Vorfahr abgeklappert
    1575           0 :             const SfxItemSet* pPdSet = &pPdFmt->GetAttrSet();
    1576           0 :             SfxItemSet aSet( *pPdSet->GetPool(), pPdSet->GetRanges() );
    1577           0 :             aSet.SetParent( pPdSet );
    1578             : 
    1579             :             // am Nachkommen NUR  die Spaltigkeit gemaess Sect-Attr.
    1580             :             // umsetzen
    1581           0 :             aSet.Put( rSepInfo.pSectionFmt->GetFmtAttr( RES_COL ) );
    1582             : 
    1583             :             const SvxLRSpaceItem &rSectionLR =
    1584           0 :                 ItemGet<SvxLRSpaceItem>( *(rSepInfo.pSectionFmt), RES_LR_SPACE );
    1585             :             const SvxLRSpaceItem &rPageLR =
    1586           0 :                 ItemGet<SvxLRSpaceItem>( *pPdFmt, RES_LR_SPACE );
    1587             : 
    1588           0 :             SvxLRSpaceItem aResultLR( rPageLR.GetLeft() +
    1589           0 :                     rSectionLR.GetLeft(), rPageLR.GetRight() +
    1590           0 :                     rSectionLR.GetRight(), 0, 0, RES_LR_SPACE );
    1591             : 
    1592           0 :             aSet.Put( aResultLR );
    1593             : 
    1594             :             // und raus damit ins WW-File
    1595           0 :             const SfxItemSet* pOldI = pISet;
    1596           0 :             pISet = &aSet;
    1597             : 
    1598             :             // Switch off test on default item values, if page description
    1599             :             // set (value of <bOutPgDscSet>) isn't written.
    1600           0 :             AttrOutput().OutputStyleItemSet( aSet, true, bOutPgDscSet );
    1601             : 
    1602             :             //Cannot export as normal page framedir, as continous sections
    1603             :             //cannot contain any grid settings like proper sections
    1604           0 :             AttrOutput().SectionBiDi( FRMDIR_HORI_RIGHT_TOP == TrueFrameDirection( *rSepInfo.pSectionFmt ) );
    1605             : 
    1606           0 :             pISet = pOldI;
    1607             :         }
    1608             :     }
    1609             : 
    1610             :     // Libreoffice 4.0 introduces support for page styles (SwPageDesc) with
    1611             :     // a different header/footer for the first page.  The same effect can be
    1612             :     // achieved by chaining two page styles together (SwPageDesc::GetFollow)
    1613             :     // which are identical except for header/footer.
    1614             :     // The latter method was previously used by the doc/docx import filter.
    1615             :     // In both of these cases, we emit a single Word section with different
    1616             :     // first page header/footer.
    1617          60 :     const SwFrmFmt* pPdFirstPgFmt = &pPd->GetFirst();
    1618          60 :     bool titlePage = !pPd->IsFirstShared();
    1619          60 :     if ( bOutPgDscSet )
    1620             :     {
    1621             :         // if a Follow is set and it does not point to itself,
    1622             :         // then there is a page chain.
    1623             :         // Falls damit eine "Erste Seite" simuliert werden soll, so
    1624             :         // koennen wir das auch als solches schreiben.
    1625             :         // Anders sieht es mit Links/Rechts wechseln aus. Dafuer muss
    1626             :         // erkannt werden, wo der Seitenwechsel statt findet. Hier ist
    1627             :         // es aber dafuer zuspaet!
    1628         180 :         if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1629          60 :              pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
    1630           0 :              ( !rSepInfo.pPDNd || pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) ) )
    1631             :         {
    1632           0 :             const SwPageDesc *pFollow = pPd->GetFollow();
    1633           0 :             const SwFrmFmt& rFollowFmt = pFollow->GetMaster();
    1634           0 :             if ( sw::util::IsPlausableSingleWordSection( *pPdFirstPgFmt, rFollowFmt ) )
    1635             :             {
    1636           0 :                 if (rSepInfo.pPDNd)
    1637           0 :                     pPdFirstPgFmt = pPd->GetPageFmtOfNode( *rSepInfo.pPDNd );
    1638             :                 else
    1639           0 :                     pPdFirstPgFmt = &pPd->GetMaster();
    1640             : 
    1641           0 :                 pAktPageDesc = pPd = pFollow;
    1642           0 :                 pPdFmt = &rFollowFmt;
    1643             : 
    1644             :                 // has different headers/footers for the title page
    1645           0 :                 titlePage = true;
    1646             :             }
    1647             :         }
    1648             : 
    1649          60 :         if( titlePage )
    1650           3 :             AttrOutput().SectionTitlePage();
    1651             : 
    1652          60 :         const SfxItemSet* pOldI = pISet;
    1653             : 
    1654          60 :         AttrOutput().SectionPageBorders( pPdFmt, pPdFirstPgFmt );
    1655             : 
    1656             :         const SfxPoolItem* pItem;
    1657          63 :         if ( titlePage && SFX_ITEM_SET ==
    1658           3 :                 pPdFirstPgFmt->GetItemState( RES_PAPER_BIN, true, &pItem ) )
    1659             :         {
    1660           0 :             pISet = &pPdFirstPgFmt->GetAttrSet();
    1661           0 :             bOutFirstPage = true;
    1662           0 :             AttrOutput().OutputItem( *pItem );
    1663           0 :             bOutFirstPage = false;
    1664             :         }
    1665             : 
    1666             :         // left-/right chain of pagedescs ?
    1667         180 :         if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
    1668          60 :                 pPd->GetFollow()->GetFollow() == pPd &&
    1669           0 :                 (( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1670           0 :                    nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ||
    1671           0 :                  ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) &&
    1672           0 :                    nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->GetFollow()->ReadUseOn() )) ))
    1673             :         {
    1674           0 :             bLeftRightPgChain = true;
    1675             : 
    1676             :             // which is the reference point? (left or right?)
    1677             :             // assume it is on the right side!
    1678           0 :             if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
    1679             :             {
    1680           0 :                 nBreakCode = 3;
    1681           0 :                 pPd = pPd->GetFollow();
    1682           0 :                 pPdFmt = &pPd->GetMaster();
    1683             :             }
    1684             :             else
    1685           0 :                 nBreakCode = 4;
    1686             :         }
    1687             : 
    1688          60 :         pISet = &pPdFmt->GetAttrSet();
    1689          60 :         AttrOutput().OutputStyleItemSet( pPdFmt->GetAttrSet(), true, false );
    1690          60 :         pISet = pOldI;
    1691             : 
    1692             :         // then the rest of the settings from PageDesc
    1693          60 :         AttrOutput().SectionPageNumbering( pPd->GetNumType().GetNumberingType(), rSepInfo.nPgRestartNo );
    1694             : 
    1695             :         // werden es nur linke oder nur rechte Seiten?
    1696          60 :         if ( 2 == nBreakCode )
    1697             :         {
    1698          60 :             if ( nsUseOnPage::PD_LEFT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
    1699           0 :                 nBreakCode = 3;
    1700          60 :             else if ( nsUseOnPage::PD_RIGHT == ( nsUseOnPage::PD_ALL & pPd->ReadUseOn() ) )
    1701           0 :                 nBreakCode = 4;
    1702             :         }
    1703             :     }
    1704             : 
    1705          60 :     AttrOutput().SectionType( nBreakCode );
    1706             : 
    1707          60 :     const SwTxtNode* pNd = rSepInfo.pNumNd;
    1708          60 :     if ( pNd )
    1709             :     {
    1710           0 :         const SwNumRule* pRule = pNd->GetNumRule();
    1711           0 :         if ( pRule )
    1712           0 :             OutputOlst( *pRule );
    1713             :     }
    1714             : 
    1715             :     // Header or Footer
    1716          60 :     sal_uInt8 nHeadFootFlags = 0;
    1717             : 
    1718             :     const SwFrmFmt* pPdLeftFmt = bLeftRightPgChain
    1719           0 :         ? &pPd->GetFollow()->GetMaster()
    1720          60 :         : &pPd->GetLeft();
    1721             : 
    1722          60 :     if ( nBreakCode != 0 )
    1723             :     {
    1724          60 :         if ( titlePage )
    1725             :         {
    1726             :             // there is a First Page:
    1727           3 :             MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_HEADER_FIRST );
    1728           3 :             MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFirstPgFmt, WW8_FOOTER_FIRST );
    1729             :         }
    1730          60 :         MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFmt, WW8_HEADER_ODD );
    1731          60 :         MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFmt, WW8_FOOTER_ODD );
    1732             : 
    1733          60 :         if ( !pPd->IsHeaderShared() || bLeftRightPgChain )
    1734           4 :             MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftFmt, WW8_HEADER_EVEN );
    1735             : 
    1736          60 :         if ( !pPd->IsFooterShared() || bLeftRightPgChain )
    1737           5 :             MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFmt, WW8_FOOTER_EVEN );
    1738          60 :         AttrOutput().SectionWW6HeaderFooterFlags( nHeadFootFlags );
    1739             :     }
    1740             : 
    1741             :     // binary filters only
    1742          60 :     SetupSectionPositions( pA );
    1743             : 
    1744             :     /*
    1745             :        !!!!!!!!!!!
    1746             :     // Umrandungen an Kopf- und Fusstexten muessten etwa so gehen:
    1747             :     // Dabei muss etwas wie pOut eingebaut werden,
    1748             :     // das bei jeder Spezialtext-Zeile wiederholt wird.
    1749             :     const SwFrmFmt* pFFmt = rFt.GetFooterFmt();
    1750             :     const SvxBoxItem& rBox = pFFmt->GetBox(false);
    1751             :     OutWW8_SwFmtBox1( m_rWW8Export.pOut, rBox, false);
    1752             :     !!!!!!!!!!!
    1753             :     You can turn this into paragraph attributes, which are then observed in each paragraph.
    1754             :     Applies to background / border.
    1755             :     !!!!!!!!!!!
    1756             :     */
    1757             : 
    1758          60 :     const SwTxtNode *pOldPageRoot = GetHdFtPageRoot();
    1759          60 :     SetHdFtPageRoot( rSepInfo.pPDNd ? rSepInfo.pPDNd->GetTxtNode() : 0 );
    1760             : 
    1761          60 :     WriteHeadersFooters( nHeadFootFlags, *pPdFmt, *pPdLeftFmt, *pPdFirstPgFmt, nBreakCode );
    1762             : 
    1763          60 :     SetHdFtPageRoot( pOldPageRoot );
    1764             : 
    1765          60 :     AttrOutput().EndSection();
    1766             : 
    1767             :     // outside of the section properties again
    1768          60 :     bOutPageDescs = bOldPg;
    1769             : }
    1770             : 
    1771           8 : bool WW8_WrPlcSepx::WriteKFTxt( WW8Export& rWrt )
    1772             : {
    1773           8 :     sal_uLong nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1774             : 
    1775             :     OSL_ENSURE( !pTxtPos, "who set the pointer?" );
    1776           8 :     pTxtPos = new WW8_WrPlc0( nCpStart );
    1777             : 
    1778           8 :     WriteFtnEndTxt( rWrt, nCpStart );
    1779           8 :     CheckForFacinPg( rWrt );
    1780             : 
    1781           8 :     unsigned int nOldIndex = rWrt.GetHdFtIndex();
    1782           8 :     rWrt.SetHdFtIndex( 0 );
    1783             : 
    1784          19 :     for ( sal_uInt16 i = 0; i < aSects.size(); ++i )
    1785             :     {
    1786          11 :         ::boost::shared_ptr<WW8_PdAttrDesc> const pAttrDesc(new WW8_PdAttrDesc);
    1787          11 :         m_SectionAttributes.push_back(pAttrDesc);
    1788             : 
    1789          11 :         WW8_SepInfo& rSepInfo = aSects[i];
    1790          11 :         rWrt.SectionProperties( rSepInfo, pAttrDesc.get() );
    1791             : 
    1792             :         // FIXME: this writes the section properties, but not of all sections;
    1793             :         // it's possible that later in the document (e.g. in endnotes) sections
    1794             :         // are added, but they won't have their properties written here!
    1795          11 :         m_bHeaderFooterWritten = true;
    1796          11 :     }
    1797           8 :     rWrt.SetHdFtIndex( nOldIndex ); //0
    1798             : 
    1799           8 :     if ( pTxtPos->Count() )
    1800             :     {
    1801             :         // HdFt available?
    1802           8 :         sal_uLong nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    1803           8 :         pTxtPos->Append( nCpEnd );  // End of last Header/Footer for PlcfHdd
    1804             : 
    1805           8 :         if ( nCpEnd > nCpStart )
    1806             :         {
    1807           5 :             ++nCpEnd;
    1808           5 :             pTxtPos->Append( nCpEnd + 1 );  // End of last Header/Footer for PlcfHdd
    1809             : 
    1810           5 :             rWrt.WriteStringAsPara( aEmptyStr ); // CR ans Ende ( sonst mault WW )
    1811             :         }
    1812           8 :         rWrt.pFldHdFt->Finish( nCpEnd, rWrt.pFib->ccpText + rWrt.pFib->ccpFtn );
    1813           8 :         rWrt.pFib->ccpHdr = nCpEnd - nCpStart;
    1814             :     }
    1815             :     else
    1816           0 :         delete pTxtPos, pTxtPos = 0;
    1817             : 
    1818           8 :     return rWrt.pFib->ccpHdr != 0;
    1819             : }
    1820             : 
    1821           8 : void WW8_WrPlcSepx::WriteSepx( SvStream& rStrm ) const
    1822             : {
    1823             :     OSL_ENSURE(m_SectionAttributes.size() == static_cast<size_t>(aSects.size())
    1824             :         , "WriteSepx(): arrays out of sync!");
    1825          19 :     for (size_t i = 0; i < m_SectionAttributes.size(); i++) // all sections
    1826             :     {
    1827          11 :         WW8_PdAttrDesc *const pA = m_SectionAttributes[i].get();
    1828          11 :         if (pA->m_nLen && pA->m_pData != 0)
    1829             :         {
    1830             :             SVBT16 nL;
    1831          11 :             pA->m_nSepxFcPos = rStrm.Tell();
    1832          11 :             ShortToSVBT16( pA->m_nLen, nL );
    1833          11 :             rStrm.Write( nL, 2 );
    1834          11 :             rStrm.Write( pA->m_pData.get(), pA->m_nLen );
    1835             :         }
    1836             :     }
    1837           8 : }
    1838             : 
    1839           8 : void WW8_WrPlcSepx::WritePlcSed( WW8Export& rWrt ) const
    1840             : {
    1841             :     OSL_ENSURE(m_SectionAttributes.size() == static_cast<size_t>(aSects.size())
    1842             :         , "WritePlcSed(): arrays out of sync!");
    1843             :     OSL_ENSURE( aCps.size() == aSects.size() + 1, "WrPlcSepx: DeSync" );
    1844           8 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
    1845             : 
    1846             :     sal_uInt16 i;
    1847          27 :     for( i = 0; i <= aSects.size(); i++ )
    1848             :     {
    1849          19 :         sal_uInt32 nP = aCps[i];
    1850             :         SVBT32 nPos;
    1851          19 :         UInt32ToSVBT32( nP, nPos );
    1852          19 :         rWrt.pTableStrm->Write( nPos, 4 );
    1853             :     }
    1854             : 
    1855             :     static WW8_SED aSed = {{4, 0},{0, 0, 0, 0},{0, 0},{0xff, 0xff, 0xff, 0xff}};
    1856             : 
    1857          19 :     for (size_t j = 0; j < m_SectionAttributes.size(); j++ )
    1858             :     {
    1859             :         // Sepx-Pos
    1860          11 :         UInt32ToSVBT32( m_SectionAttributes[j]->m_nSepxFcPos, aSed.fcSepx );
    1861          11 :         rWrt.pTableStrm->Write( &aSed, sizeof( aSed ) );
    1862             :     }
    1863           8 :     rWrt.pFib->fcPlcfsed = nFcStart;
    1864           8 :     rWrt.pFib->lcbPlcfsed = rWrt.pTableStrm->Tell() - nFcStart;
    1865           8 : }
    1866             : 
    1867             : 
    1868           8 : void WW8_WrPlcSepx::WritePlcHdd( WW8Export& rWrt ) const
    1869             : {
    1870             :     // Don't write out the PlcfHdd if ccpHdd is 0: it's a validation failure case.
    1871           8 :     if( rWrt.pFib->ccpHdr != 0 && pTxtPos && pTxtPos->Count() )
    1872             :     {
    1873           5 :         rWrt.pFib->fcPlcfhdd = rWrt.pTableStrm->Tell();
    1874           5 :         pTxtPos->Write( *rWrt.pTableStrm );             // Plc0
    1875           5 :         rWrt.pFib->lcbPlcfhdd = rWrt.pTableStrm->Tell() -
    1876          10 :                                 rWrt.pFib->fcPlcfhdd;
    1877             :     }
    1878           8 : }
    1879             : 
    1880          42 : void MSWordExportBase::WriteHeaderFooterText( const SwFmt& rFmt, bool bHeader )
    1881             : {
    1882             :     const SwFmtCntnt *pCntnt;
    1883          42 :     if ( bHeader )
    1884             :     {
    1885          20 :         bHasHdr = true;
    1886          20 :         const SwFmtHeader& rHd = rFmt.GetHeader();
    1887             :         OSL_ENSURE( rHd.GetHeaderFmt(), "Header text is not here" );
    1888          20 :         pCntnt = &rHd.GetHeaderFmt()->GetCntnt();
    1889             :     }
    1890             :     else
    1891             :     {
    1892          22 :         bHasFtr = true;
    1893          22 :         const SwFmtFooter& rFt = rFmt.GetFooter();
    1894             :         OSL_ENSURE( rFt.GetFooterFmt(), "Footer text is not here" );
    1895          22 :         pCntnt = &rFt.GetFooterFmt()->GetCntnt();
    1896             :     }
    1897             : 
    1898          42 :     const SwNodeIndex* pSttIdx = pCntnt->GetCntntIdx();
    1899             : 
    1900          42 :     if ( pSttIdx )
    1901             :     {
    1902          42 :         SwNodeIndex aIdx( *pSttIdx, 1 ),
    1903          84 :         aEnd( *pSttIdx->GetNode().EndOfSectionNode() );
    1904          42 :         sal_uLong nStart = aIdx.GetIndex();
    1905          42 :         sal_uLong nEnd = aEnd.GetIndex();
    1906             : 
    1907             :         // Bereich also gueltiger Node
    1908          42 :         if ( nStart < nEnd )
    1909             :         {
    1910          42 :             bool bOldKF = bOutKF;
    1911          42 :             bOutKF = true;
    1912          42 :             WriteSpecialText( nStart, nEnd, TXT_HDFT );
    1913          42 :             bOutKF = bOldKF;
    1914             :         }
    1915             :         else
    1916          42 :             pSttIdx = 0;
    1917             :     }
    1918             : 
    1919          42 :     if ( !pSttIdx )
    1920             :     {
    1921             :         // there is no Header/Footer, but a CR is still necessary
    1922             :         OSL_ENSURE( pSttIdx, "Header/Footer text is not really present" );
    1923           0 :         AttrOutput().EmptyParagraph(); // CR ans Ende ( sonst mault WW )
    1924             :     }
    1925          42 : }
    1926             : 
    1927             : //------------------------------------------------------------------------------
    1928             : // class WW8_WrPlcFtnEdn : Collect the Footnotes and Endnotes and output their text
    1929             : // and Plcs at the end of the document.
    1930             : // WW8_WrPlcFtnEdn is the class for Footnotes and Endnotes
    1931             : //------------------------------------------------------------------------------
    1932          40 : WW8_WrPlcSubDoc::WW8_WrPlcSubDoc()
    1933          40 :     : pTxtPos( 0 )
    1934             : {
    1935          40 : }
    1936             : 
    1937          80 : WW8_WrPlcSubDoc::~WW8_WrPlcSubDoc()
    1938             : {
    1939          40 :     delete pTxtPos;
    1940          40 : }
    1941             : 
    1942           1 : void WW8_WrPlcFtnEdn::Append( WW8_CP nCp, const SwFmtFtn& rFtn )
    1943             : {
    1944           1 :     aCps.push_back( nCp );
    1945           1 :     aCntnt.push_back( &rFtn );
    1946           1 : }
    1947             : 
    1948           0 : WW8_Annotation::WW8_Annotation(const SwPostItField* pPostIt)
    1949             :     :
    1950           0 :         maDateTime( DateTime::EMPTY )
    1951             : {
    1952           0 :     mpRichText = pPostIt->GetTextObject();
    1953           0 :     if (!mpRichText)
    1954           0 :         msSimpleText = pPostIt->GetTxt();
    1955           0 :     msOwner = pPostIt->GetPar1();
    1956           0 :     maDateTime = DateTime(pPostIt->GetDate(), pPostIt->GetTime());
    1957           0 : }
    1958             : 
    1959           0 : WW8_Annotation::WW8_Annotation(const SwRedlineData* pRedline)
    1960             :     :
    1961             :         mpRichText(0),
    1962           0 :         maDateTime( DateTime::EMPTY )
    1963             : {
    1964           0 :     msSimpleText = pRedline->GetComment();
    1965           0 :     msOwner = SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor());
    1966           0 :     maDateTime = pRedline->GetTimeStamp();
    1967           0 : }
    1968             : 
    1969           0 : void WW8_WrPlcAnnotations::Append( WW8_CP nCp, const SwPostItField *pPostIt )
    1970             : {
    1971           0 :     aCps.push_back( nCp );
    1972           0 :     WW8_Annotation* p = new WW8_Annotation(pPostIt);
    1973           0 :     aCntnt.push_back( p );
    1974           0 : }
    1975             : 
    1976           0 : void WW8_WrPlcAnnotations::Append( WW8_CP nCp, const SwRedlineData *pRedline )
    1977             : {
    1978           0 :     maProcessedRedlines.insert(pRedline);
    1979           0 :     aCps.push_back( nCp );
    1980           0 :     WW8_Annotation* p = new WW8_Annotation(pRedline);
    1981           0 :     aCntnt.push_back( p );
    1982           0 : }
    1983             : 
    1984           0 : bool WW8_WrPlcAnnotations::IsNewRedlineComment( const SwRedlineData *pRedline )
    1985             : {
    1986           0 :     return maProcessedRedlines.find(pRedline) == maProcessedRedlines.end();
    1987             : }
    1988             : 
    1989          24 : WW8_WrPlcAnnotations::~WW8_WrPlcAnnotations()
    1990             : {
    1991           8 :     for( sal_uInt16 n=0; n < aCntnt.size(); n++ )
    1992           0 :         delete (WW8_Annotation*)aCntnt[n];
    1993          16 : }
    1994             : 
    1995          40 : bool WW8_WrPlcSubDoc::WriteGenericTxt( WW8Export& rWrt, sal_uInt8 nTTyp,
    1996             :     WW8_CP& rCount )
    1997             : {
    1998          40 :     sal_uInt16 nLen = aCntnt.size();
    1999          40 :     if ( !nLen )
    2000          37 :         return false;
    2001             : 
    2002           3 :     sal_uLong nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    2003           3 :     pTxtPos = new WW8_WrPlc0( nCpStart );
    2004             :     sal_uInt16 i;
    2005             : 
    2006           3 :     switch ( nTTyp )
    2007             :     {
    2008             :         case TXT_ATN:
    2009           0 :             for ( i = 0; i < nLen; i++ )
    2010             :             {
    2011             :                 // beginning for PlcfAtnTxt
    2012           0 :                 pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
    2013             : 
    2014           0 :                 rWrt.WritePostItBegin();
    2015           0 :                 const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2016           0 :                 if (rAtn.mpRichText)
    2017           0 :                     rWrt.WriteOutliner(*rAtn.mpRichText, nTTyp);
    2018             :                 else
    2019             :                 {
    2020           0 :                     String sTxt(rAtn.msSimpleText);
    2021           0 :                     sTxt.SearchAndReplaceAll(0x0A, 0x0B);
    2022           0 :                     rWrt.WriteStringAsPara( sTxt );
    2023             :                 }
    2024             :             }
    2025           0 :             break;
    2026             : 
    2027             :         case TXT_TXTBOX:
    2028             :         case TXT_HFTXTBOX:
    2029           4 :             for ( i = 0; i < nLen; i++ )
    2030             :             {
    2031             :                 // textbox content
    2032           2 :                 WW8_CP nCP = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    2033           2 :                 aCps.insert( aCps.begin()+i, nCP );
    2034           2 :                 pTxtPos->Append( nCP );
    2035             : 
    2036           2 :                 if( aCntnt[ i ] != NULL )
    2037             :                 {
    2038             :                 // is it an writer or sdr - textbox?
    2039           2 :                 const SdrObject& rObj = *(SdrObject*)aCntnt[ i ];
    2040           2 :                 if (rObj.GetObjInventor() == FmFormInventor)
    2041             :                 {
    2042           1 :                     sal_uInt8 nOldTyp = rWrt.nTxtTyp;
    2043           1 :                     rWrt.nTxtTyp = nTTyp;
    2044           1 :                     rWrt.GetOCXExp().ExportControl(rWrt,&rObj);
    2045           1 :                     rWrt.nTxtTyp = nOldTyp;
    2046             :                 }
    2047           1 :                 else if( rObj.ISA( SdrTextObj ) )
    2048           0 :                     rWrt.WriteSdrTextObj(rObj, nTTyp);
    2049             :                 else
    2050             :                 {
    2051           1 :                     const SwFrmFmt* pFmt = ::FindFrmFmt( &rObj );
    2052             :                     OSL_ENSURE( pFmt, "where is the format?" );
    2053             : 
    2054           1 :                     const SwNodeIndex* pNdIdx = pFmt->GetCntnt().GetCntntIdx();
    2055             :                     OSL_ENSURE( pNdIdx, "where is the StartNode of the Textbox?" );
    2056           1 :                     rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1,
    2057           1 :                                            pNdIdx->GetNode().EndOfSectionIndex(),
    2058           3 :                                            nTTyp );
    2059             :                     {
    2060           1 :                         SwNodeIndex aContentIdx = *pNdIdx;
    2061           1 :                         ++aContentIdx;
    2062           1 :                         if ( aContentIdx.GetNode().IsTableNode() )
    2063             :                         {
    2064           1 :                             bool bContainsOnlyTables = true;
    2065           1 :                             do {
    2066           1 :                                 aContentIdx = *(aContentIdx.GetNode().EndOfSectionNode());
    2067           1 :                                 ++aContentIdx;
    2068           2 :                                 if ( !aContentIdx.GetNode().IsTableNode() &&
    2069           1 :                                      aContentIdx.GetIndex() != pNdIdx->GetNode().EndOfSectionIndex() )
    2070             :                                 {
    2071           1 :                                     bContainsOnlyTables = false;
    2072             :                                 }
    2073           1 :                             } while ( aContentIdx.GetNode().IsTableNode() );
    2074           1 :                             if ( bContainsOnlyTables )
    2075             :                             {
    2076             :                                 // Additional paragraph containing a space to
    2077             :                                 // assure that by WW created RTF from written WW8
    2078             :                                 // does not crash WW.
    2079           0 :                                 rWrt.WriteStringAsPara( OUString(" ") );
    2080             :                             }
    2081           1 :                         }
    2082             :                     }
    2083             :                 }
    2084             :                 }
    2085           0 :                 else if( i < aSpareFmts.size() )
    2086             :                 {
    2087           0 :                     if( const SwFrmFmt* pFmt = (const SwFrmFmt*)aSpareFmts[ i ] )
    2088             :                     {
    2089           0 :                         const SwNodeIndex* pNdIdx = pFmt->GetCntnt().GetCntntIdx();
    2090           0 :                         rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1,
    2091           0 :                                    pNdIdx->GetNode().EndOfSectionIndex(), nTTyp );
    2092             :                     }
    2093             :                 }
    2094             : 
    2095             :                 // CR at end of one textbox text ( otherwise WW gpft :-( )
    2096           2 :                 rWrt.WriteStringAsPara( aEmptyStr );
    2097             :             }
    2098           2 :             break;
    2099             : 
    2100             :         case TXT_EDN:
    2101             :         case TXT_FTN:
    2102           2 :             for ( i = 0; i < nLen; i++ )
    2103             :             {
    2104             :                 // beginning for PlcfFtnTxt/PlcfEdnTxt
    2105           1 :                 pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
    2106             : 
    2107             :                 // Note content
    2108           1 :                 const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ];
    2109           1 :                 rWrt.WriteFtnBegin( *pFtn );
    2110           1 :                 const SwNodeIndex* pIdx = pFtn->GetTxtFtn()->GetStartNode();
    2111             :                 OSL_ENSURE( pIdx, "wo ist der StartNode der Fuss-/EndNote?" );
    2112           1 :                 rWrt.WriteSpecialText( pIdx->GetIndex() + 1,
    2113           1 :                                        pIdx->GetNode().EndOfSectionIndex(),
    2114           3 :                                        nTTyp );
    2115             :             }
    2116           1 :             break;
    2117             : 
    2118             :         default:
    2119             :             OSL_ENSURE( !this, "was ist das fuer ein SubDocType?" );
    2120             :     }
    2121             : 
    2122           3 :     pTxtPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
    2123             :     // CR ans Ende ( sonst mault WW )
    2124           3 :     rWrt.WriteStringAsPara( aEmptyStr );
    2125             : 
    2126           3 :     WW8_CP nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
    2127           3 :     pTxtPos->Append( nCpEnd );
    2128           3 :     rCount = nCpEnd - nCpStart;
    2129             : 
    2130           3 :     return ( rCount != 0 );
    2131             : }
    2132             : 
    2133          40 : void WW8_WrPlcSubDoc::WriteGenericPlc( WW8Export& rWrt, sal_uInt8 nTTyp,
    2134             :     WW8_FC& rTxtStart, sal_Int32& rTxtCount, WW8_FC& rRefStart, sal_Int32& rRefCount ) const
    2135             : {
    2136             :     typedef ::std::vector<String>::iterator myiter;
    2137             : 
    2138          40 :     sal_uLong nFcStart = rWrt.pTableStrm->Tell();
    2139          40 :     sal_uInt16 nLen = aCps.size();
    2140          40 :     if ( !nLen )
    2141          77 :         return;
    2142             : 
    2143             :     OSL_ENSURE( aCps.size() + 2 == pTxtPos->Count(), "WritePlc: DeSync" );
    2144             : 
    2145           3 :     ::std::vector<String> aStrArr;
    2146           3 :     WW8Fib& rFib = *rWrt.pFib;              // n+1-te CP-Pos nach Handbuch
    2147             :     sal_uInt16 i;
    2148           3 :     bool bWriteCP = true;
    2149             : 
    2150           3 :     switch ( nTTyp )
    2151             :     {
    2152             :         case TXT_ATN:
    2153             :             {
    2154             :                 // then write first the GrpXstAtnOwners
    2155           0 :                 for ( i = 0; i < nLen; ++i )
    2156             :                 {
    2157           0 :                     const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2158           0 :                     aStrArr.push_back(rAtn.msOwner);
    2159             :                 }
    2160             : 
    2161             :                 //sort and remove duplicates
    2162           0 :                 ::std::sort(aStrArr.begin(), aStrArr.end());
    2163           0 :                 myiter aIter = ::std::unique(aStrArr.begin(), aStrArr.end());
    2164           0 :                 aStrArr.erase(aIter, aStrArr.end());
    2165             : 
    2166           0 :                 if ( rWrt.bWrtWW8 )
    2167             :                 {
    2168           0 :                     for ( i = 0; i < aStrArr.size(); ++i )
    2169             :                     {
    2170           0 :                         const String& rStr = aStrArr[i];
    2171           0 :                         SwWW8Writer::WriteShort(*rWrt.pTableStrm, rStr.Len());
    2172             :                         SwWW8Writer::WriteString16(*rWrt.pTableStrm, rStr,
    2173           0 :                                 false);
    2174             :                     }
    2175             :                 }
    2176             :                 else
    2177             :                 {
    2178           0 :                     for ( i = 0; i < aStrArr.size(); ++i )
    2179             :                     {
    2180           0 :                         const String& rStr = aStrArr[i];
    2181           0 :                         *rWrt.pTableStrm << (sal_uInt8)rStr.Len();
    2182             :                         SwWW8Writer::WriteString8(*rWrt.pTableStrm, rStr, false,
    2183           0 :                                 RTL_TEXTENCODING_MS_1252);
    2184             :                     }
    2185             :                 }
    2186             : 
    2187           0 :                 rFib.fcGrpStAtnOwners = nFcStart;
    2188           0 :                 nFcStart = rWrt.pTableStrm->Tell();
    2189           0 :                 rFib.lcbGrpStAtnOwners = nFcStart - rFib.fcGrpStAtnOwners;
    2190             : 
    2191             :                 // Write the extended >= Word XP ATLD records
    2192           0 :                 if( rWrt.bWrtWW8 )
    2193             :                 {
    2194           0 :                     for( i = 0; i < nLen; ++i )
    2195             :                     {
    2196           0 :                         const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2197             : 
    2198           0 :                         sal_uInt32 nDTTM = sw::ms::DateTime2DTTM(rAtn.maDateTime);
    2199             : 
    2200           0 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, nDTTM );
    2201           0 :                         SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2202           0 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2203           0 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2204           0 :                         SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2205             :                     }
    2206             : 
    2207           0 :                     rFib.fcAtrdExtra = nFcStart;
    2208           0 :                     nFcStart = rWrt.pTableStrm->Tell();
    2209           0 :                     rFib.lcbAtrdExtra = nFcStart - rFib.fcAtrdExtra;
    2210           0 :                     rFib.fcHplxsdr = 0x01010002;  //WTF, but apparently necessary
    2211           0 :                     rFib.lcbHplxsdr = 0;
    2212             :                 }
    2213             :             }
    2214           0 :             break;
    2215             :         case TXT_TXTBOX:
    2216             :         case TXT_HFTXTBOX:
    2217             :             {
    2218           2 :                 pTxtPos->Write( *rWrt.pTableStrm );
    2219           2 :                 const std::vector<sal_uInt32>* pShapeIds = GetShapeIdArr();
    2220             :                 OSL_ENSURE( pShapeIds, "Where are the ShapeIds?" );
    2221             : 
    2222           4 :                 for ( i = 0; i < nLen; ++i )
    2223             :                 {
    2224             :                     // write textbox story - FTXBXS
    2225             :                     // is it an writer or sdr - textbox?
    2226           2 :                     const SdrObject* pObj = (SdrObject*)aCntnt[ i ];
    2227           2 :                     sal_Int32 nCnt = 1;
    2228           2 :                     if (pObj && !pObj->ISA( SdrTextObj ) )
    2229             :                     {
    2230             :                         // find the "highest" SdrObject of this
    2231           1 :                         const SwFrmFmt& rFmt = *::FindFrmFmt( pObj );
    2232             : 
    2233           1 :                         const SwFmtChain* pChn = &rFmt.GetChain();
    2234           2 :                         while ( pChn->GetNext() )
    2235             :                         {
    2236             :                             // has a chain?
    2237             :                             // then calc the cur pos in the chain
    2238           0 :                             ++nCnt;
    2239           0 :                             pChn = &pChn->GetNext()->GetChain();
    2240             :                         }
    2241             :                     }
    2242           2 :                     if( NULL == pObj )
    2243             :                     {
    2244           0 :                         if( i < aSpareFmts.size() && aSpareFmts[ i ] )
    2245             :                         {
    2246           0 :                             const SwFrmFmt& rFmt = *(const SwFrmFmt*)aSpareFmts[ i ];
    2247             : 
    2248           0 :                             const SwFmtChain* pChn = &rFmt.GetChain();
    2249           0 :                             while( pChn->GetNext() )
    2250             :                             {
    2251             :                                 // has a chain?
    2252             :                                 // then calc the cur pos in the chain
    2253           0 :                                 ++nCnt;
    2254           0 :                                 pChn = &pChn->GetNext()->GetChain();
    2255             :                             }
    2256             :                         }
    2257             :                     }
    2258             :                     // long cTxbx / iNextReuse
    2259           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, nCnt );
    2260             :                     // long cReusable
    2261           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2262             :                     // short fReusable
    2263           2 :                     SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2264             :                     // long reserved
    2265           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
    2266             :                     // long lid
    2267             :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm,
    2268           2 :                             (*pShapeIds)[i]);
    2269             :                     // long txidUndo
    2270           2 :                     SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
    2271             :                 }
    2272           2 :                 SwWW8Writer::FillCount( *rWrt.pTableStrm, 22 );
    2273           2 :                 bWriteCP = false;
    2274             :             }
    2275           2 :             break;
    2276             :     }
    2277             : 
    2278           3 :     if ( bWriteCP )
    2279             :     {
    2280             :         // write CP Positions
    2281           2 :         for ( i = 0; i < nLen; i++ )
    2282           1 :             SwWW8Writer::WriteLong( *rWrt.pTableStrm, aCps[ i ] );
    2283             : 
    2284             :         // n+1-te CP-Pos nach Handbuch
    2285             :         SwWW8Writer::WriteLong( *rWrt.pTableStrm,
    2286           1 :                 rFib.ccpText + rFib.ccpFtn + rFib.ccpHdr + rFib.ccpEdn +
    2287           1 :                 rFib.ccpTxbx + rFib.ccpHdrTxbx + 1 );
    2288             : 
    2289           1 :         if ( TXT_ATN == nTTyp )
    2290             :         {
    2291           0 :             for ( i = 0; i < nLen; ++i )
    2292             :             {
    2293           0 :                 const WW8_Annotation& rAtn = *(const WW8_Annotation*)aCntnt[i];
    2294             : 
    2295             :                 //aStrArr is sorted
    2296             :                 myiter aIter = ::std::lower_bound(aStrArr.begin(),
    2297           0 :                         aStrArr.end(), rAtn.msOwner);
    2298             :                 OSL_ENSURE(aIter != aStrArr.end() && *aIter == rAtn.msOwner,
    2299             :                         "Impossible");
    2300           0 :                 sal_uInt16 nFndPos = static_cast< sal_uInt16 >(aIter - aStrArr.begin());
    2301           0 :                 String sAuthor(*aIter);
    2302           0 :                 sal_uInt8 nNameLen = (sal_uInt8)sAuthor.Len();
    2303           0 :                 if ( nNameLen > 9 )
    2304             :                 {
    2305           0 :                     sAuthor.Erase( 9 );
    2306           0 :                     nNameLen = 9;
    2307             :                 }
    2308             : 
    2309             :                 // xstUsrInitl[ 10 ] pascal-style String holding initials
    2310             :                 // of annotation author
    2311           0 :                 if ( rWrt.bWrtWW8 )
    2312             :                 {
    2313           0 :                     SwWW8Writer::WriteShort(*rWrt.pTableStrm, nNameLen);
    2314             :                     SwWW8Writer::WriteString16(*rWrt.pTableStrm, sAuthor,
    2315           0 :                             false);
    2316             :                     SwWW8Writer::FillCount( *rWrt.pTableStrm,
    2317           0 :                             (9 - nNameLen) * 2 );
    2318             : 
    2319             :                 }
    2320             :                 else
    2321             :                 {
    2322           0 :                     *rWrt.pTableStrm << nNameLen;
    2323             :                     SwWW8Writer::WriteString8(*rWrt.pTableStrm, sAuthor,
    2324           0 :                             false, RTL_TEXTENCODING_MS_1252);
    2325           0 :                     SwWW8Writer::FillCount(*rWrt.pTableStrm, 9 - nNameLen);
    2326             :                 }
    2327             : 
    2328             :                 // documents layout of WriteShort's below:
    2329             :                 //
    2330             :                 // SVBT16 ibst;      // index into GrpXstAtnOwners
    2331             :                 // SVBT16 ak;        // not used
    2332             :                 // SVBT16 grfbmc;    // not used
    2333             :                 // SVBT32 ITagBkmk;  // when not -1, this tag identifies the
    2334             : 
    2335           0 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, nFndPos );
    2336           0 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2337           0 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2338           0 :                 SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
    2339           0 :             }
    2340             :         }
    2341             :         else
    2342             :         {
    2343           1 :             sal_uInt16 nNo = 0;
    2344           2 :             for ( i = 0; i < nLen; ++i )             // write Flags
    2345             :             {
    2346           1 :                 const SwFmtFtn* pFtn = (SwFmtFtn*)aCntnt[ i ];
    2347             :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm,
    2348           1 :                         pFtn->GetNumStr().Len() ? 0 : ++nNo );
    2349             :             }
    2350             :         }
    2351             :     }
    2352           3 :     rRefStart = nFcStart;
    2353           3 :     nFcStart = rWrt.pTableStrm->Tell();
    2354           3 :     rRefCount = nFcStart - rRefStart;
    2355             : 
    2356           3 :     pTxtPos->Write( *rWrt.pTableStrm );
    2357             : 
    2358           3 :     switch ( nTTyp )
    2359             :     {
    2360             :         case TXT_TXTBOX:
    2361             :         case TXT_HFTXTBOX:
    2362           4 :             for ( i = 0; i < nLen; ++i )
    2363             :             {
    2364             :                 // write break descriptor (BKD)
    2365             :                 // short itxbxs
    2366           2 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, i );
    2367             :                 // short dcpDepend
    2368           2 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
    2369             :                 // short flags : icol/fTableBreak/fColumnBreak/fMarked/
    2370             :                 //               fUnk/fTextOverflow
    2371           2 :                 SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0x800 );
    2372             :             }
    2373           2 :             SwWW8Writer::FillCount( *rWrt.pTableStrm, 6 );
    2374           2 :             break;
    2375             :     }
    2376             : 
    2377           3 :     rTxtStart = nFcStart;
    2378           3 :     rTxtCount = rWrt.pTableStrm->Tell() - nFcStart;
    2379             : }
    2380             : 
    2381           0 : const std::vector<sal_uInt32>* WW8_WrPlcSubDoc::GetShapeIdArr() const
    2382             : {
    2383           0 :     return 0;
    2384          18 : }
    2385             : 
    2386             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10